Bred Posté(e) le 18 juillet 2008 Posté(e) le 18 juillet 2008 Salut,Je n'arrive pas à insérer un bloc en lui donnant une direction par deux points.... Exemple simplifié :- J'ai un bloc = ligne de 0,0,0 à 0,4,0 déjà existant- Je sélectionne 2 points 3D (p1 = 1,2,3 et p2 = 8,9,10 par exemple)- je veux insérer mon bloc au point p1, et qu'il soit "dirigé" vers p2 (donc si l'on continue la ligne de mon bloc, cette ligne passe par p2....) L'insertion du bloc "en 2D" c'est bon...(setq b (vla-insertblock (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object))) (vlax-3d-point (trans p1 1 0)) Nom_Bloc 1 1 1 (angle p1 p2))) Mais après, j'ai tenté vla-mirror3D, vla.rotate3D, et je n'arrives pas à le mettre en place... Il doit y avoir un truc avec vla-put-normal, ou avec vla-TransformBy, mais je n'arrives pas à le réaliser.. Merci d'avance !!!! Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
Bred Posté(e) le 18 juillet 2008 Auteur Posté(e) le 18 juillet 2008 Re,Alors j'arrive en bricilant un truc avec rotate 3D...et grâce à deux routines de (gile)...Mais c'est vraiment du bricolage... - Je test si p2 > Z que p1 et je les inverse au cas où (car la routine ANGLE_3PTS ne retourne qu'un angle +)- Je calcul l'axe de rotation (Perpendiculaire aux 2 points)- Je calcul "l'angle 3D" de rotation- j'insert sur le plan XY, puis je retourne mon bloc.... (if (> (caddr p1) (caddr p2)) (setq p1c p1 p1 p2 p2 p1c)) (setq P1-AxeR (polar p1 (+ (angle p1 p2) (/ pi 2)) 1) ang (angle_3pts p1 (list (car p2) (cadr p2) (caddr p1)) p2)) (setq b (vla-insertblock (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object))) (vlax-3d-point (trans p1 1 0)) NomB 1 1 1 (angle p1 p2))) (vla-Rotate3D b (vlax-3d-point p1) (vlax-3d-point P1-AxeR) (- ang)))))) ;;; routines de (gile) ;;; ANGLE_3PTS Retourne l'angle (radians) défini par son sommet et deux points ;;; L'angle retourné est toujours positif et inférieur à pi radians. (defun angle_3pts (som p1 p2 / d1 d2 d3) (setq d1 (distance som p1) d2 (distance som p2) d3 (distance p1 p2) ) (if (and (< 0 d1) (< 0 d2)) (acos (/ (+ (* d1 d1) (* d2 d2) (- (* d3 d3))) (* 2 d1 d2) ) ) ) ) ;;; ACOS Retourne l'arc cosinus du nombre, en radians (defun ACOS (num) (if (<= -1 num 1) (atan (sqrt (- 1 (expt num 2))) num) (princ "\nErreur: L'argument pour ACOS doit être compris entre -1 et 1" ) ) ) Si vous avez plus beau, je suis preneur !!!!! merci. Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 18 juillet 2008 Posté(e) le 18 juillet 2008 Salut Bred, Je ne comprends pas bien ce que tu veux faire. Tu ne peux pas définir un plan avec seulement 2 points. Un bloc est défini par rapport à un plan (XY du SCG).Quand on l'insère (avec INSERER), on aligne ce plan sur le plan XY du SCU courant, dans lequel on peut spécifier une rotation par rapport à l'axe X. J'avais fait Ins3d (sur cette page) pour insérer un bloc en 3d en spécifiant 3points (comme si on faisait : SCU 3Points puis insertion du bloc en 0,0,0 avec une rotation de 0) :- le premier point = le point d'insertion (origine du SCU)- le second = la rotation du bloc (axe X du SCU)- le troisième (combiné aux deux autres) = le plan d'insertion (zone positive des Y du SCU) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 19 juillet 2008 Auteur Posté(e) le 19 juillet 2008 Salut (gile),Tu ne peux pas définir un plan avec seulement 2 points.En effet... ;) Mais le truc c'est que justement dans ce cas on peut tricher :Mon bloc est une ligne (ou un tube rond) : donc on peut le tourner dans tous les sens sur l'axe des X, on ne fera pas la différence (ma ligne n'est que sur les X) !C'est à dire que sa normale pourrais être dans n'importe quel direction : qu'importe !!Ce qui compte, c'est sa direction vers les X. J'avais fait Ins3d...Je le sais plus que bien, mais mon cas est plus simple je pense. merci dans tous les cas ! Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 19 juillet 2008 Posté(e) le 19 juillet 2008 Je crois que j'ai compris, Pour faire plus élégant, il est plus simple que ton bloc linéaire (ou cylindrique) soit axé sur l'axe Z.Ça permet d'utiliser la Normale du bloc pour l'aligner. Exemple - le bloc "tube" est défini verticalement (perpendiculaire au plan XY) et il a une longueur de 1000 unités.Il est aligné et étiré suivant les deux points spécifiés (defun c:test (/ p1 p2 blk) (setq p1 (getpoint "\nPoint d'insertion: ") p2 (trans (getpoint p1 "\nDirection: ") 1 0) p1 (trans p1 1 0) scl (/ (distance p1 p2) 1000) ) (setq blk (vla-InsertBlock (vla-get-ModelSpace *acdoc*) (vlax-3d-point '(0 0 0)) "tube" 1 1 scl 0 ) ) (vla-put-Normal blk (vlax-3d-point (mapcar '- p2 p1))) (vla-Move blk (vlax-3d-point '(0 0 0)) (vlax-3d-point p1)) (princ) ) [Edité le 19/7/2008 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 19 juillet 2008 Auteur Posté(e) le 19 juillet 2008 ton bloc linéaire (ou cylindrique) soit axé sur l'axe Z.non, ce n'est pas pratique pour moi, car sa position d'insertion la plus fréquente est parallèle au plan XY... L'insertion avec la commande "insérer" est primordiale. merci quand même ! Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 19 juillet 2008 Posté(e) le 19 juillet 2008 Re, J'ai trouvé un truc avec une rotation 3d aussi. dir est le vecteur directeur de la droite p1 p2, '(1 0 0) celui de l'axe des X (donc de l'axe du bloc)S'ils ne sont pas alignés ces 2 vecteurs définissent un plan dont on peut calculer la normale (nor) en faisant le produit vectoriel des 2 vecteursnor servira à définir l'axe de rotation et à traduire dir pour trouver l'angle. (defun c:test (/ p1 p2 dir nor ang bl) (setq p1 (getpoint "\nPoint d'insertion: ") p2 (trans (getpoint p1 "\nDirection: ") 1 0) p1 (trans p1 1 0) dir (mapcar '- p2 p1) nor (v^v '(1 0 0) dir) ) (and (equal '(0 0 0) nor 1e-9) (setq nor '(0 0 1))) ; vecteurs alignés (setq ang (angle '(0 0) (trans dir 0 nor))) ; angle de rotation (and ( (setq bl (vla-InsertBlock (vla-get-ModelSpace *acdoc*) (vlax-3d-point p1) "test" 1 1 1 0 ) ) (vla-Rotate3d bl (vlax-3d-point p1) (vlax-3d-point (mapcar '+ p1 nor)) ang ) (princ) ) ;; V^V ;; Retourne le produit vectoriel (vecteur) de deux vecteurs ;; ;; Arguments : deux vecteurs (defun v^v (v1 v2) (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2))) (- (* (caddr v1) (car v2)) (* (car v1) (caddr v2))) (- (* (car v1) (cadr v2)) (* (cadr v1) (car v2))) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 19 juillet 2008 Auteur Posté(e) le 19 juillet 2008 :D :D :D Génial ! Merci !Vraiment malin !ces 2 vecteurs définissent un plan dont on peut calculer la normaleTu m'épates ! Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
Bred Posté(e) le 19 juillet 2008 Auteur Posté(e) le 19 juillet 2008 Ah ! pour mon code et le tiens : si le SCU est différent du SCG, ça ne fonctionne pas .... Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 19 juillet 2008 Posté(e) le 19 juillet 2008 Ah ! pour mon code et le tiens : si le SCU est différent du SCG, ça ne fonctionne pas .... Je n'avais pas testé... vla-InsertBlock insère le bloc sur le point SCG mais avec la normale du SCU courant (dans son plan XY) :casstet: (defun c:test (/ p1 p2 dir nor ang bl) (setq p1 (getpoint "\nPoint d'insertion: ") p2 (trans (getpoint p1 "\nDirection: ") 1 0) p1 (trans p1 1 0) dir (mapcar '- p2 p1) nor (v^v '(1 0 0) dir) ) (and (equal '(0 0 0) nor 1e-9) (setq nor '(0 0 1))) (setq ang (angle '(0 0) (trans dir 0 nor))) (and ( (setq bl (vla-InsertBlock (vla-get-ModelSpace *acdoc*) (vlax-3d-point '(0 0 0)) "test" 1 1 1 0 ) ) (vla-put-Normal bl (vlax-3d-point '(0 0 1))) (vla-Rotate3d bl (vlax-3d-point '(0 0 0)) (vlax-3d-point nor) ang ) (vla-Move bl (vlax-3d-point '(0 0 0)) (vlax-3d-point p1)) (princ) ) ;; V^V ;; Retourne le produit vectoriel (vecteur) de deux vecteurs ;; ;; Arguments : deux vecteurs (defun v^v (v1 v2) (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2))) (- (* (caddr v1) (car v2)) (* (car v1) (caddr v2))) (- (* (car v1) (cadr v2)) (* (cadr v1) (car v2))) ) ) [Edité le 19/7/2008 par (gile)] [Edité le 19/7/2008 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 19 juillet 2008 Auteur Posté(e) le 19 juillet 2008 ... j'étais en train de chercher la solution...Il ne t'as pas fallu longtemps !Merci, c'est Parfait ! ;) Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 24 juillet 2008 Posté(e) le 24 juillet 2008 Une autre méthode : une première rotation dans le plan XY (sauf si les points décrivent une verticale), puis une rotation 3d.Avec cette méthode, normale du bloc est toujours dans le plan vertical qui contient son axe X, sauf, bien sûr, si l'axe X du bloc est vertical (dans ce cas la normale est (-1 0 0). EDIT : réparé bug dans les SCU non // au SCG (defun c:test (/ p1 p2 v x y z a1 a2 bl) (vl-load-com) (or *acdoc* (setq *acdoc* (vla-get-ActiveDocument (vlax-get-acad-object))) ) (setq p1 (getpoint "\nPoint d'insertion: ") p2 (trans (getpoint p1 "\nDirection: ") 1 0) p1 (trans p1 1 0) v (mapcar '- p2 p1) ) (mapcar '(lambda (x1 x2) (set x1 (eval x2))) '(x y z) v) (setq a1 (atan y x) a2 (atan z (/ x (cos a1))) ) (setq bl (vla-InsertBlock (vla-get-ModelSpace *acdoc*) (vlax-3d-point '(0 0 0)) "test" 1 1 1 0 ) ) (vla-put-Normal bl (vlax-3d-point '(0 0 1))) (if (and (equal x 0 1e-9) (equal y 0 1e-9)) (vla-Rotate3d bl (vlax-3d-point '(0 0 0)) (vlax-3d-point '(0 1 0)) (if (minusp z) (/ pi 2) (/ pi -2) ) ) (progn (vla-Rotate3d bl (vlax-3d-point '(0 0 0)) (vlax-3d-point '(0 0 1)) (setq a (atan y x)) ) (vla-Rotate3d bl (vlax-3d-point '(0 0 0)) (vlax-3d-point (list y (- x) 0)) (if (equal x 0 1e-9) (atan z (abs y)) (atan z (/ x (cos a))) ) ) ) ) (vla-Move bl (vlax-3d-point '(0 0 0)) (vlax-3d-point p1)) (princ) ) [Edité le 24/7/2008 par (gile)] [Edité le 24/7/2008 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 24 juillet 2008 Auteur Posté(e) le 24 juillet 2008 Salut et merci,j'ai un peu tester ta seconde proposition, elle ne semble pas fonctionner si le SCU est "en vrac" (c'est à dire non // au SCG, et aucun des axe dans le sens des 2 points tapés) Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
(gile) Posté(e) le 24 juillet 2008 Posté(e) le 24 juillet 2008 Merci Bred pour le retour.Je pense avoir réparé le problème. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Bred Posté(e) le 24 juillet 2008 Auteur Posté(e) le 24 juillet 2008 Je pense avoir réparé le problème.Je confirme !merci. PS : tu as un *acdoc* non renseigné qui traine. Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant