Aller au contenu

Messages recommandés

Posté(e)

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...

Posté(e)

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...

Posté(e)

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

Posté(e)

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...

Posté(e)

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

Posté(e)
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...

Posté(e)

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 vecteurs

nor 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

Posté(e)

:D :D :D

Génial ! Merci !

Vraiment malin !

ces 2 vecteurs définissent un plan dont on peut calculer la normale

Tu m'épates !

 

 

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

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...

Posté(e)

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

Posté(e)

... 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...

Posté(e)

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

Posté(e)

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...

Posté(e)
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...

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 compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité