Aller au contenu

Intersections poly3D


chris_mtp

Messages recommandés

Bonjour à tous,

 

J'ai un axe en plan 2D à Z=0 qui coupe des polylignes 3D.

Serait il possible de créer une polyligne 3D reliant les points d'intersection projetée de la poly2D avec les 3D avec comme altitude des points d'intersections un Z interpolé des deux sommets les plus proches des poly3D avec la poly2D d'origine ?

 

Jusqu'à présent, je calculais des interpolations via Distance et pente, insérer un bloc au point d'intersection avec un Z manuel puis je tracé après la polyligne 3D qui joint les points d'intersection projeté ainsi crées.

 

Mais si on n'a une polyligne qui fait 500m de long avec un point ts les 5m, c'est fastidieux.

 

Merci par avance de votre aide.

John.

Lien vers le commentaire
Partager sur d’autres sites

coucou

 

ta phrase d'explication est compliquée à souhait :(

 

ce que tu veux, c'est l'intersection simplement entre une poly3D et un 2D ?

 

en attendant qu'on t'écrive un lisp,

tu vas pouvoir utiliser une commande native d'AutoCad, l'intersection projetée

 

par exemple pour insérer un bloc sur la position XY de l'intersection

et l'altitude de cette même intersection

_insert

nom du bloc

_appint

cliquer la poly3D à proximité de l'intersection

puis la poly3D à proximité de l'intersection

 

CQFD

 

alicalement

 

Lien vers le commentaire
Partager sur d’autres sites

Attention, je ne veux pas que tu m'écrive un code.

Je commence tout juste à apprendre le lisp. C'est pas en l'écrivant toi même que ca va m'aider.

De plus, je connais l'intersection projeté. Mais je souhaiterais simplement automatiser certaines tâches.

 

Ce que je demande, c'est comment faire (ou du moins avoir une idée de début) pour sans sélectionner les polylignes 3D crée un point tout simple aux intersections de la poly2D et des poly3D.

J'ai commencé à regarder certains lisp de gile et de bonuscad mais je patoge.

 

Voilà tout.

John.

Lien vers le commentaire
Partager sur d’autres sites

coucou

 

il est certain que si tu débutes en lisp

et que tu t'attaques à ce genre de routine

 

c'est comme apprendre à marcher en grimpant l'Everest,

on y arrive mais on se décourage vite.

 

il va d'abord falloir identifier le vertex correspondant à l'intersection

puis isoler les sommets de ces mêmes vertex

ensuite l'intersection sera aisée à trouver

 

mais avec la bouche, hein, on en fait des choses ...

 

si tu as un début de lisp, on va t'aider,

bon courage

 

amicalement

Lien vers le commentaire
Partager sur d’autres sites

C'est pas en l'écrivant toi même que ca va m'aider.

 

Déjà pour simplifier le code, il serait bien de savoir s'il y a des segment d'arc dans ta polyligne2D.

 

Si cela concerne que des segment droit, le code peut être pas trop dur à monter.

avec (entsel) tu sélectionne ta polyline2D

tu récupère dans une liste tous les sommets

avec cette liste tu t'en sers pour faire un jeu de sélection filtré avec ssget sur tes poly3D et l'option trajet (_fence)

Après avec des boucles, obtenir tes intersection2D entre ta poly2D et les segments de poly3D (en les projetant en 2D: Z=0)

 

Une fois les points2D des intersections 2D trouvés, faire l'opération de recherche d'intersection en 3D avec les poly3D et des ligne3D virtuelles (montée avec les point2D d'intersection)

 

Voilà en gros la démarche.

 

S'il y a des arcs cela compliquera beaucoup le code...

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Sérieux c pas simple.

Voila ce que j'ai pu faire à partir de lisp déjà éxistant mais .....

 

 (defun c:inters3d (/ plo)
(setq plo (entsel "\nSélectionnez une polyligne: "))
(l-coor2l-pt (plo))
(defun l-coor2l-pt (lst flag / )
(if lst
(cons (list (car lst) (cadr lst) (if flag (caddr lst) 0.0))
(l-coor2l-pt (if flag (cdddr lst) (cddr lst)) flag)
)
)
)
(prin1)
)

 

j'ai ça comme erreur

erreur: fonction incorrecte: (

7dcce170> (452660.0 221477.0 0.0))

 

John

Lien vers le commentaire
Partager sur d’autres sites

Allez, un p'tit début.

 

Cette ébauche de code retourne la liste des points d'intersection 2D (la dernière évaluée), je te laisse continuer dans la boucle pour obtenir les 3D. Hé oui c'est pas fini.

 

((lambda ( / ent dxf_ent ldxf_10 js n ename l_pt3D l_pt2D l_int2D)
 (defun l-coor2l-pt (lst flag / )
   (if lst
     (cons (list (car lst) (cadr lst) (if flag (caddr lst) 0.0))
       (l-coor2l-pt (if flag (cdddr lst) (cddr lst)) flag)
     )
   )
 )
 (princ "\nChoisir une polyligne2D")
 (while (null (setq ent (entsel))))
 (setq dxf_ent (entget (car ent)))
 (cond
   ((eq (cdr (assoc 0 dxf_ent)) "LWPOLYLINE")
     (setq ldxf_10 (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) dxf_ent)))
     (setq js (ssget "_F" ldxf_10 '((0 . "POLYLINE") (-4 . "&") (70 . 8))))
     (cond
       (js
         (setq n -1)
         (vl-load-com)
         (repeat (sslength js)
           (setq
             ename (vlax-ename->vla-object (ssname js (setq n (1+ n))))
             l_pt3D nil
             l_pt3D (append (l-coor2l-pt (vlax-get ename 'Coordinates) T) l_pt3D)
             l_pt2D (mapcar 'list (mapcar 'car l_pt3D) (mapcar 'cadr l_pt3D))
           )
           (foreach n (mapcar 'list ldxf_10 (cdr ldxf_10))
             (setq l_int2D
               (vl-remove nil
                 (mapcar
                   '(lambda (p3 p4)
                     (setq pt_int (inters (car n) (cadr n) p3 p4 T))
                   )
                   l_pt2D (append (cdr l_pt2d) (list (car l_pt2d)))
                 )
               )
             )
[color=red];ICI on continu[/color]
[color=green];la ligne suivante est juste une ligne de test, elle dessine le point2D à l'intersection (car l_int2D)[/color]
             (if (not (null l_int2d))(command "_.point" "_none" (car l_int2D)))
           )
         )
       )
     )
   )
 )
))

 

[Edité le 9/1/2009 par bonuscad]

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Si j'ai bien compris, les points p3 et p4 sont les points 3D les plus proches à l'intersection de la poly2D.

 

J'ai fait ce lisp.

Je dois pas être loin du fond mais il me manque la forme car quand je lance dans autocad le lisp, il m'indique erreur de syntaxe.

 

 ((lambda ( / ent dxf_ent ldxf_10 js n ename l_pt3D l_pt2D l_int2D)
(defun l-coor2l-pt (lst flag / )
(if lst
(cons (list (car lst) (cadr lst) (if flag (caddr lst) 0.0))
(l-coor2l-pt (if flag (cdddr lst) (cddr lst)) flag)
)
)
)
(princ "\nChoisir une polyligne2D")
(while (null (setq ent (entsel))))
(setq dxf_ent (entget (car ent)))
(cond
((eq (cdr (assoc 0 dxf_ent)) "LWPOLYLINE")
(setq ldxf_10 (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) dxf_ent)))
(setq js (ssget "_F" ldxf_10 '((0 . "POLYLINE") (-4 . "&") (70 . 8))))
(cond
(js
(setq n -1)
(vl-load-com)
(repeat (sslength js)
(setq
ename (vlax-ename->vla-object (ssname js (setq n (1+ n))))
l_pt3D nil
l_pt3D (append (l-coor2l-pt (vlax-get ename 'Coordinates) T) l_pt3D)
l_pt2D (mapcar 'list (mapcar 'car l_pt3D) (mapcar 'cadr l_pt3D))
)
(foreach n (mapcar 'list ldxf_10 (cdr ldxf_10))
(setq l_int2D
(vl-remove nil
(mapcar
'(lambda (p3 p4)
(setq pt_int (inters (car n) (cadr n) p3 p4 T))
)
l_pt2D (append (cdr l_pt2d) (list (car l_pt2d)))
)
)
)
)
)
)
)
)
)
))

(defun c:inters3d (/ dz1 dz2 de1 de2 dist1 dist2 zn)
(setq dz1 (- (caddr p3) (caddr p4)))
(setq de1 (- (car p3) (car p4)))
(setq dn1 (- (cadr p3) (cadr p4)))
(setq dist1 sqrt((+ (* de1 de1) (* dn1 dn1))))
(setq de2 (- (car p3) (car n)))
(setq dn2 (- (cadr p3) (cadr n)))
(setq dist2 sqrt((+ (* de2 de2) (* dn2 dn2))))
(setq dz2 (/ (* dist2 dz1) dist1))
(setq zn (+ dz2 caddr p3))
(command "_osnap" "_appint")
(command "_point" (list(car n cadr n caddr zn)))
(prin1)
)

 

Par contre, je n'ai pas trouver la commande valeur absolue dans l'aide à intégrer après chaque variable à définir pour avoir une interpolation Z correcte.

 

Merci par avance de votre aide et merci encore à ta fonction Bonuscad.

John

Lien vers le commentaire
Partager sur d’autres sites

Petite erreur de ma part, je n'avais pas inclu le calcul dans la boucle mais toujours rien à faire.

Cette fois ci c'est erreur: structure incorrecte de la liste en entrée

 

 (defun c:inters3d ()
((lambda ( / de1 de2 dn1 dn2 dist1 dist2 zn dz1 dz2 ent dxf_ent ldxf_10 js n ename l_pt3D l_pt2D l_int2D)
(defun l-coor2l-pt (lst flag / )
(if lst
(cons (list (car lst) (cadr lst) (if flag (caddr lst) 0.0))
(l-coor2l-pt (if flag (cdddr lst) (cddr lst)) flag)
)
)
)
(princ "\nChoisir une polyligne2D")
(while (null (setq ent (entsel))))
(setq dxf_ent (entget (car ent)))
(cond
((eq (cdr (assoc 0 dxf_ent)) "LWPOLYLINE")
(setq ldxf_10 (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) dxf_ent)))
(setq js (ssget "_F" ldxf_10 '((0 . "POLYLINE") (-4 . "&") (70 . 8))))
(cond
(js
(setq n -1)
(vl-load-com)
(repeat (sslength js)
(setq
ename (vlax-ename->vla-object (ssname js (setq n (1+ n))))
l_pt3D nil
l_pt3D (append (l-coor2l-pt (vlax-get ename 'Coordinates) T) l_pt3D)
l_pt2D (mapcar 'list (mapcar 'car l_pt3D) (mapcar 'cadr l_pt3D))
)
(foreach n (mapcar 'list ldxf_10 (cdr ldxf_10))
(setq l_int2D
(vl-remove nil
(mapcar
'(lambda (p3 p4)
(setq pt_int (inters (car n) (cadr n) p3 p4 T))
)
l_pt2D (append (cdr l_pt2d) (list (car l_pt2d)))
)
)
)
(setq dz1 (- (caddr p3) (caddr p4)))
(setq de1 (- (car p3) (car p4)))
(setq dn1 (- (cadr p3) (cadr p4)))
(setq dist1 sqrt((+ (* de1 de1) (* dn1 dn1))))
(setq de2 (- (car p3) (car n)))
(setq dn2 (- (cadr p3) (cadr n)))
(setq dist2 sqrt((+ (* de2 de2) (* dn2 dn2))))
(setq dz2 (/ (* dist2 dz1) dist1))
(setq zn (+ dz2 caddr p3))
(if (not (null l_int2d))(command "_.point" "_none" list((car l_int2D) (caddr zn)))
)
)
)
)
)
)
))
(prin1)
)

 

Merci par avance piur votre aide.

John.

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Je n'ai pas lu le code, mais "erreur: structure incorrecte de la liste en entrée" veut dire qu'il y a un problème d'appariement de parenthèses.

 

Je ne sais pas si tu utilises un éditeur de code pour écrire test routines ou si tu travailles avec un simple éditeur de texte.

Mais un éditeur de code devrait te permettre d'éviter aisément ce type d'erreurs.

Par exemple, dans l'éditeur Visual LISP fournit avec AutoCAD, grâce au formatage du code et à la sélection par double clic devant une parenthèse ouvrante ou derrière une parenthèse fermante tu devrais pouvoir localiser facilement ce type d'erreur.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Alors un petit peu plus en avant, jusqu'au point 3D

 

(defun c:inters3d ( / ent dxf_ent ldxf_10 js n ename l_pt3D l_pt2D l_int2D)
 (defun l-coor2l-pt (lst flag / )
   (if lst
     (cons (list (car lst) (cadr lst) (if flag (caddr lst) 0.0))
       (l-coor2l-pt (if flag (cdddr lst) (cddr lst)) flag)
     )
   )
 )
 (princ "\nChoisir une polyligne2D")
 (while (null (setq ent (entsel))))
 (setq dxf_ent (entget (car ent)))
 (cond
   ((eq (cdr (assoc 0 dxf_ent)) "LWPOLYLINE")
     (setq ldxf_10 (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) dxf_ent)))
     (setq js (ssget "_F" ldxf_10 '((0 . "POLYLINE") (-4 . "&") (70 . 8))))
     (cond
       (js
         (setq n -1)
         (vl-load-com)
         (repeat (sslength js)
           (setq
             ename (vlax-ename->vla-object (ssname js (setq n (1+ n))))
             l_pt3D nil
             l_pt3D (append (l-coor2l-pt (vlax-get ename 'Coordinates) T) l_pt3D)
             l_pt2D (mapcar 'list (mapcar 'car l_pt3D) (mapcar 'cadr l_pt3D))
           )
           (foreach n (mapcar 'list ldxf_10 (cdr ldxf_10))
             (setq l_int2D
               (vl-remove nil
                 (mapcar
                   '(lambda (p3 p4)
                     (setq pt_int (inters (car n) (cadr n) p3 p4 T))
                   )
                   l_pt2D (append (cdr l_pt2d) (list (last l_pt2d)))
                 )
               )
             )
             (if (not (null l_int2d))
               (progn
                 (setq l_int3D
                   (vl-remove nil
                     (mapcar
                       '(lambda (p3 p4)
                         (setq pt_int
                           (inters
                             (list (caar l_int2d) (cadar l_int2d) 0.0)
                             (list (caar l_int2d) (cadar l_int2d) 100.0)
                             p3 p4
                             nil
                           )
                         )
                       )
                       l_pt3d (append (cdr l_pt3d) (list (last l_pt3d)))
                     )
                   )
                 )
                 [color=blue];ICI on obtient le point 3D dans la boucle[/color]
                 (command "_.point" "_none" (car l_int3d))
               )
             )
           )
         )
       )
     )
   )
 )
 (prin1)
)

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Mais ensuite pour joindre les points en une polyligne 3D, c'est plus compliqué ?

 

Oui et non.

On a les points 3D, donc on peut construire une poly3D.

Le problème est l'ordre des points.

Dans la routine la recherche ce fait (sans pouvoir l'affirmer à 100%) dans l'ordre de création des poly3D, donc les points résultants risquent de suivre le même ordre.

 

Mais je pense quand mettant l'accroche objet à "nodal", tu iras plus vite pour tracer ta poly3D que de chercher à mettre un code (aléatoire) en place. Là au moins c'est toi qui va déterminer l'ordre.

 

Mais si tu veux essayer avec le code, il te suffit de stocker les coordonnées des points trouvés dans la boucle en construisant une liste.

Au lieu de la commande point tu fais (setq list_point (cons (car l_int3d) list_point)

A la fin du code tu fais une condition si la liste existe faire poly3d avec la liste des points

 

Ne pas oublier de déclarer list_point en variable locale dans la fonction (autrement celle-ci va se rallonger à chaque utilisation de la fonction)

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

C'est une autre méthode que tu me proposes là mais mon idée de calculer l'interpolation en Z était valable aussi non ?

 

Tout méthode est valable, mais tu était mal parti.

En effet tu utilisait les point p3 et p4 de la fonction (lambda), mais ceux-ci étaient extraits de la liste de points en 2D, donc....

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

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é