Macro Draft Circle 3 Points/it

= Macro Draft Circle 3 Points=

Descrizione
Questa macro crea un cerchio orthogonale passante per tre punti selezionati. I punti possono anche essere oggetti quali cubi, cilindri, ecc., in questi casi sono considerate e utilizzate le coordinate del centro di queste forme.

Utilizzo
Selezionare 3 punti o forme nella vista 3D ed eseguire la macro.

Se la forma è una linea, le coordinate sono date dal punto centrale della linea.

Opzioni
Se gli oggetti selezionati sono su piani diversi, (xy Z10,xy Z2,xy Z5) il cerchio viene costruito sul piano x,y Z=0.

Se tutti gli oggetti selezionati hanno la stessa coordinata Z (xy Z5,xy Z5,xy Z5), il cerchio viene costruito sul piano della coordinata Z comune (x,y Z=5).

Script
Draft_Circle_3_Points.FCMacro

import Draft, Part, FreeCAD, math, PartGui, FreeCADGui from math import sqrt, pi, sin, cos from FreeCAD import Base
 * 1) -*- coding: utf-8 -*-
 * 2) creare un cerchio da tre punti selezionati nel piano X,Y
 * 3) 04/03/2013
 * 4) la formula è presa da
 * 5) http://www-obs.univ-lyon1.fr/labo/fc/Ateliers_archives/ateliers_2005-06/cercle_3pts.pdf
 * 6) leggere le note nel pdf, sull'ordine di selezione dei punti,
 * 7) oppure se la formula restituisce un errore (per esempio nel caso di tre punti allineati)

sel = FreeCADGui.Selection.getSelection i=0 centreX=0 centreY=0 rayon=0 if len(sel)==3 : i=0 ta=[0,0,0,0,0,0,0,0,0] for obj in sel: x=(obj.Shape.BoundBox.Center) ta[i+0]=(x.x)		ta[i+1]=(x.y)		ta[i+2]=(x.z)		i=i+3 x_point_1=ta[0] y_point_1=ta[1] z_point_1=ta[2] x_point_2=ta[3] y_point_2=ta[4] z_point_2=ta[5] x_point_3=ta[6] y_point_3=ta[7] z_point_3=ta[8] centreX =((x_point_3**2-x_point_2**2+y_point_3**2-y_point_2**2)/(2*(y_point_3-y_point_2))-(x_point_2**2-x_point_1**2+y_point_2**2-y_point_1**2)/(2*(y_point_2-y_point_1)))/((x_point_3-x_point_2)/(y_point_3-y_point_2)-(x_point_2-x_point_1)/(y_point_2-y_point_1)) centreY =-(x_point_2-x_point_1)/(y_point_2-y_point_1)*centreX+(x_point_2**2-x_point_1**2+y_point_2**2-y_point_1**2)/(2*(y_point_2-y_point_1)) rayon =sqrt((x_point_1-centreX)**2+(y_point_1-centreY)**2) if z_point_1==z_point_2 and z_point_2==z_point_3: centreZ=z_point_1 else: centreZ=0 pl=FreeCAD.Placement pl.Rotation.Q=(0.0,-0.0,-0.0,1.0) pl.Base=FreeCAD.Vector(centreX,centreY,centreZ) Draft.makeCircle((rayon),placement=pl,face=False,support=None) FreeCAD.Console.PrintMessage("Coordonnée X : "+str(centreX)+"\r\n") FreeCAD.Console.PrintMessage("Coordonnée Y : "+str(centreY)+"\r\n") FreeCAD.Console.PrintMessage("Coordonnée Z : "+str(centreZ)+"\r\n") FreeCAD.Console.PrintMessage("Rayon       : "+str(rayon  )+"\r\n") else: FreeCAD.Console.PrintError("Selezionare 3 punti e ripetere\r\n")
 * 1) acquisire gli oggetti selezionati
 * 1) Se ci sono 3 punti selezionati, allora..
 * 1) Assegnazione delle variabili
 * 1) Calcolo delle coordinate del centro del cerchio
 * 1) Definizione della coordinata Z
 * 2) Se tutte le coordinate Z sono uguali il centro Z vale Z
 * 1) Se una delle coordinate Z è diversa dalle altre allora  Z=0
 * 1) Creazione del cerchio
 * 1) Visualizzare il risultato nel Rapporto di FreeCAD
 * 1) ... se la condizione (tre punti selezionati) non è soddisfatta, ripetere

Versione migliorata
Oltre alle funzionalità della macro precedente, questa versione produce un cerchio ortogonale allineato a scelta con ciascuna delle e posizionato sul piano XY, YZ o XZ selezionato.

Il cerchio prende il colore dell'asse corrispondente, indipendentemente dal colore corrente e viene disegnato il suo centro (opzione On/Off).

Le impostazioni da modificare. # vueChoix=0 (per la vista) e alignerSur=0 (per l'allineamento) vueChoix=0	# scelta della vista Dall'alto=1 XY, vista Frontale=2 ZX, vista Laterale destra=3 ZY	alignerSur=0	# allineamento del cerchio su una forma a scelta (1,2 o 3) oppure su Z=0 afficherPoint=1	# mostrare il centro del cerchio import Draft, Part, FreeCAD, math, PartGui, FreeCADGui from math import sqrt, pi, sin, cos from FreeCAD import Base from PyQt4 import QtCore, QtGui
 * 1) Modificare i seguenti valori di default:
 * 1) -*- coding: utf-8 -*-
 * 2) créer un cercle à partir de 3 points sélectionnes
 * 3) avec comme options le cercle peut être construit sur un plans au choix
 * 4) à la coordonnée d'une des trois formes sélectionnées au choix
 * 5) et création du point central O/N
 * 6) 04/03/2013
 * 7) la formule provient de
 * 8) http://www-obs.univ-lyon1.fr/labo/fc/Ateliers_archives/ateliers_2005-06/cercle_3pts.pdf
 * 9) lire la note dans le pdf, sur l'ordre de sélection des points,
 * 10) si la formule renvoie une erreur (exemple les 3 points dans le même alignement)

def errorDialog(msg): # Create a simple dialog QMessageBox # The first argument indicates the icon used: one of QtGui.QMessageBox.{NoIcon, Information, Warning, Critical, Question} diag = QtGui.QMessageBox(QtGui.QMessageBox.Critical,u"Error Message",msg) diag.setWindowModality(QtCore.Qt.ApplicationModal) diag.exec_

def affiche(x,y,z,rayon,r,v,b,afficherPoint): pl.Base=FreeCAD.Vector(x,y,z) Draft.makeCircle((rayon),placement=pl,face=False,support=None) FreeCADGui.activeDocument.activeObject.LineColor = (r,v,b) if afficherPoint==1: Draft.makePoint(x,y,z) diag = QtGui.QMessageBox(QtGui.QMessageBox.Information,u"Coordonnées",u"Coordonnée X : "+str(x)+"\r\n"+u"Coordonnée Y : "+str(y)+"\n"+u"Coordonnée Z : "+str(z)+"\nRayon\t    : "+str(rayon)) diag.setWindowModality(QtCore.Qt.ApplicationModal) diag.exec_

sel = FreeCADGui.Selection.getSelection i=0 centreX=0;centreY=0;rayon=0
 * 1) prendre les objets sélectionnés

if len(sel)==3 : i=0 ta=[0,0,0,0,0,0,0,0,0] for obj in sel: x=(obj.Shape.BoundBox.Center) ta[i+0]=(x.x)		ta[i+1]=(x.y)		ta[i+2]=(x.z)		i=i+3 # vueChoix=0 et alignerSur=0 mode par défaut vueChoix=0		# choix de la vue Dessus=1 XY, vue Face=2 ZX, vue Droite=3 ZY	alignerSur=0	# aligne le cercle sur une forme au choix (1,2 ou 3) ou sur Z=0 afficherPoint=1	# affiche le point central du cercle
 * 1) S'il y a 3 points sélectionnés alors..
 * 1) Modifier les valeurs ci dessous

# Affectation des variables if vueChoix==3:		# Vue de droite ZY (Rouge) z_point_1=ta[0] x_point_1=ta[1] y_point_1=ta[2] z_point_2=ta[3] x_point_2=ta[4] y_point_2=ta[5] z_point_3=ta[6] x_point_3=ta[7] y_point_3=ta[8]

elif vueChoix==2:	# Vue de face ZX (Vert) y_point_1=ta[0] z_point_1=ta[1] x_point_1=ta[2] y_point_2=ta[3] z_point_2=ta[4] x_point_2=ta[5] y_point_3=ta[6] z_point_3=ta[7] x_point_3=ta[8]

else:			# Vue de dessus XY (Bleu) x_point_1=ta[0] y_point_1=ta[1] z_point_1=ta[2] x_point_2=ta[3] y_point_2=ta[4] z_point_2=ta[5] x_point_3=ta[6] y_point_3=ta[7] z_point_3=ta[8]

# Calcul des coordonnées du centre du cercle try: centreX =((x_point_3**2-x_point_2**2+y_point_3**2-y_point_2**2)/(2*(y_point_3-y_point_2))-(x_point_2**2-x_point_1**2+y_point_2**2-y_point_1**2)/(2*(y_point_2-y_point_1)))/((x_point_3-x_point_2)/(y_point_3-y_point_2)-(x_point_2-x_point_1)/(y_point_2-y_point_1)) centreY =-(x_point_2-x_point_1)/(y_point_2-y_point_1)*centreX+(x_point_2**2-x_point_1**2+y_point_2**2-y_point_1**2)/(2*(y_point_2-y_point_1)) rayon =sqrt((x_point_1-centreX)**2+(y_point_1-centreY)**2) except: errorDialog(u"Calcul impossible trop d'élements alignés") else: #finally: sera TOUJOURS exécuté # Définition de la coordonnée Z		centreZ=0 # Création du cercle pl=FreeCAD.Placement if vueChoix==1:	# Plan XY Dessus pl.Rotation.Q=(0,0,0,1.0) if alignerSur==1: affiche(centreX,centreY,z_point_1,rayon,0.0,0.0,1.0,afficherPoint) elif alignerSur==2: affiche(centreX,centreY,z_point_2,rayon,0.0,0.0,1.0,afficherPoint) elif alignerSur==3: affiche(centreX,centreY,z_point_3,rayon,0.0,0.0,1.0,afficherPoint) elif vueChoix==2: # Plan XZ Face pl.Rotation.Q=(1,0,0,1.0) if alignerSur==1: affiche(centreY,z_point_1,centreX,rayon,0.0,1.0,0.0,afficherPoint) elif alignerSur==2: affiche(centreY,z_point_2,centreX,rayon,0.0,1.0,0.0,afficherPoint) elif alignerSur==3: affiche(centreY,z_point_3,centreX,rayon,0.0,1.0,0.0,afficherPoint) elif vueChoix==3: # Plan YZ Droite pl.Rotation.Q=(0,1,0,1.0) if alignerSur==1: affiche(z_point_1,centreX,centreY,rayon,1.0,0.0,0.0,afficherPoint) elif alignerSur==2: affiche(z_point_2,centreX,centreY,rayon,1.0,0.0,0.0,afficherPoint) elif alignerSur==3: affiche(z_point_3,centreX,centreY,rayon,1.0,0.0,0.0,afficherPoint) else:	# modifier pour avoir XYZ # si les coordonnées Z sont égales alors le cercle s'aligne à Z			if z_point_1==z_point_2 and z_point_2==z_point_3: centreZ=z_point_1 affiche(centreX,centreY,z_point_1,rayon,0.0,0.0,0.0,afficherPoint) else: # Si une coordonnée est différente alors Z=0 affiche(centreX,centreY,0,rayon,0.0,0.0,0.0,afficherPoint)

else: # Si la condition n'est pas remplie, recommencez errorDialog(u"Sélectionnez 3 points et recommencez") #FreeCAD.Console.PrintError("Sélectionnez 3 points et recommencez\r\n")

Contributi
La genesi della macro Draft_Circle_3_Points nel forum (PYTHON) coordonnées d'un point aiutato de flachyjoe che ringrazio.

La formula è presa da cercle_3pts.pdf e utilizzata per gentile concessione dell'autore.