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 edgesself.edges = [] # edges of the shapearg = args[0] # start pointself.x, self.y = arg[0], arg[1] # current point of the drawingfor arg in args[1:]:if len(arg) == 2: # lineself.lineTo(*arg)else: # arcself.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.yself.x, self.y = x, ye = 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 pointdraw an arc from the current point to (x, y)update the current point"""a = radians(alpha)x0, y0 = self.x, self.y # start pointself.x, self.y = x, y # update current start pointp = x*x + y*y - x0*x0 - y0*y0q = 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 arcY = ((x-x0)*q -.5*cos(a)*p) / dr = 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 :