Macro Draft Circle 3 Points/it

= Macro Draft Circle 3 Points=

Descrizione
Questa macro crea un cerchio ortogonale 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. Se la forma è una linea, le coordinate sono date dal punto centrale della linea.

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

Opzioni
Quando 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 1
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) indipendentemente dal valore di Z
 * 4) 04/03/2013
 * 5) la formula è presa da
 * 6) http://www-obs.univ-lyon1.fr/labo/fc/Ateliers_archives/ateliers_2005-06/cercle_3pts.pdf
 * 7) leggere le note nel pdf, sull'ordine di selezione dei punti,
 * 8) 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 (in un piano) 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. Vista laterale, piano ZY, rosso; vista frontale, piano ZX, verde; vista dall'alto, piano XY, blu. Viene inoltre disegnato il suo centro (opzione O/1).

Le impostazioni da modificare nello script. # modo predefinito vueChoix=0 e alignerSur=0 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	# 1 per mostrare il centro del cerchio, 0 per non mostrarlo
 * 1) Modificare a piacere i seguenti valori di default:

Script 2
import Draft, Part, FreeCAD, math, PartGui, FreeCADGui from math import sqrt, pi, sin, cos from FreeCAD import Base from PyQt4 import QtCore, QtGui
 * 1) -*- coding: utf-8 -*-
 * 2) creare un cerchio da tre punti selezionati,
 * 3) con le opzioni per costruire il cerchio su un piano a scelta
 * 4) alle coordinate di una delle tre forme selezionate, e
 * 5) mostrare il centro del cerchio O/N
 * 6) 04/03/2013
 * 7) la formula è presa da
 * 8) http://www-obs.univ-lyon1.fr/labo/fc/Ateliers_archives/ateliers_2005-06/cercle_3pts.pdf
 * 9) leggere le note nel pdf, sull'ordine di selezione dei punti,
 * 10) se la formula restituisce un errore (per esempio nel caso di tre punti allineati)

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

# Acquisizione delle variabili if vueChoix==3:		# Vista laterale destra ZY (Rosso) 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:	# Vista frontale ZX (Verde) 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:			# Vista dall'alto XY (Blu) 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]

# Calcolo delle coordinate del centro del cerchio 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")

Anaglifo
Tramite occhiali con filtro Rosso e Ciano in questo anaglifo si possono vedere due diverse posizioni della vista.

Osservare alternativamente con l'occhio destro poi con l'occhio sinistro per vedere le singole viste.



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.