16/05/2016
Cet article fait partie d'un projet d'atelier menuiserie pour FreeCAD.
Dans cet article on modélise des pièces dont la section comporte des segments de droite et des arcs de cercle.
On veut faire faire à FreeCAD des pièces comme sur la copie d'écran ci-dessus, c'est à dire comportant sur sa section des segments de droite et des arcs de cercle. On veut aussi utiliser une syntaxe très dépouillée :
f = Fer(nom, hauteur, (x0, y0), (x, y)|(a, x, y), ...)
nom
est le nom de la pièce. Ex. "F096"
(x0, y0)
est l'origine du tracé. Ex. (0, 0)
hauteur
est un entier qui mesure la hauteur de la pièce. Ex. 24
Suivent alors des tuples. Un couple pour un segment et un triplet pour un arc.
(x, y)
indique qu'il faut joindre un segment du point courant au point de coordonnées (x, y)
(a, x, y)
indique qu'il faut tracer un arc de cercle depuis le point courant au point (x, y)
tangent au vecteur d'angle a
au point courant. def __init__(self, label, h, *args):
self.n = 0 # count of edges
self.edges = [] # edges of the shape
arg = args[0] # start point
self.x, self.y = arg[0], arg[1] # current point of the drawing
for arg in args[1:]:
if len(arg) == 2: # line
self.lineTo(*arg)
else: # arc
self.arcTo(*arg)
w = Part.Wire(self.edges)
face = Part.Face(w)
fer = face.extrude(fv(0, 0, h))
fobj = doc.addObject("Part::Feature", label)
fobj.Shape = fer
La classe Fer mémorise les coordonnées du point courant (sef.x, self.y
)
La fonction lineTo trace un segment de droite vers le nouveau point en utilisant la fonction Part.makeLine
du module Part
. (voir documentation API FreeCAD)
def lineTo(self, x, y):
""" Draw a line from the current point to (x, y)
update the current point """
x0, y0 = self.x, self.y
self.x, self.y = x, y
e = Part.makeLine((x0, y0, 0), (x, y, 0))
self.addEdge(e)
Pour dessiner un arc de cercle du point courant au suivant, c'est un peu plus compliqué. Il faut d'abord déterminer le centre du cercle et d'autre part tenir compte de l'orientation de l'espace. Un document expose le calcul mathématique : Math2Fer
def arcTo(self, alpha, x, y):
""" a is the start angle of the arc from the current point
(x, y) is the end point
draw an arc from the current point to (x, y)
update the current point
"""
a = radians(alpha)
x0, y0 = self.x, self.y # start point
self.x, self.y = x, y # update current start point
p = x*x + y*y - x0*x0 - y0*y0
q = x0*cos(a) + y0*sin(a)
d = (x - x0)*sin(a) - (y - y0)*cos(a)
X = (.5*sin(a)*p - (y-y0)*q) / d # center of arc
Y = ((x-x0)*q -.5*cos(a)*p) / d
r = hypot(X - x, Y - y)
g = (y - y0)*cos(a) - (x - x0)*sin(a)
a = degrees(copysign(acos((x0 - X)/r), y0 - Y))
b = degrees(copysign(acos((x - X)/r), y - Y))
if g > 0:
e = Part.makeCircle(r, fv(X, Y, 0), fv(0, 0, 1), a, b)
else:
e = Part.makeCircle(r, fv(X, Y, 0), fv(0, 0, 1), b, a)
self.addEdge(e)
Le fichier python est à télécharger ici fer.py.
Pour le faire exécuter par FreeCAD :