Aller au contenu

Messages recommandés

Posté(e)

Bonjour,

 

Je bute sur un truc tout con, ça doit être devant mes yeux, mais je n'y arrive pas.

Je dispose d'une polyligne 3D (avec Z différent à chaque sommet) et d'un point XY (Z=0) qui est planimétriquement sur la poly3D et je cherche le Z correspondant à ce point 2D.

J'ai essayé le vlax-curve-getClosestPointTo, mais comme l'accrochage 3D, ça calcule la plus courte distance en 3D et non à la verticale

J'ai essayé le vlax-curve-getClosestPointToProjection en passant la normale à '(0.0 0.0 1.0), mais ça ne me donne pas le bon résultat. D'après l'aide, ça projette la courbe sur le plan à la normale fournie, puis ça calcule le point proche et ça le reprojette sur la courbe originale, donc ça donne à priori la même chose que précédemment.

Je peux tenter le coup en construisant une ligne verticale pour rechercher l'intersection, ou bien me balader sur chaque segment jusqu'à trouver le bon et faire l'interpolation simple, mais je pense qu'il doit y avoir une autre solution, tellement simple que je ne la vois pas.

Merci si vous pouvez m'éclairer.

 

Olivier

Posté(e)

Bonjour,

Pour avoir la liste des points

; getpt3dpol, récupère la liste des points d'une polyligne 2D ou 3D
(defun getpt3dpol (ent / n pts)
    (setq n (1+ (fix (vlax-curve-getEndParam ent))))
    (repeat n
        (setq pts (cons (vlax-curve-getPointAtParam ent (setq n (1- n))) pts)))
)

(getpt3dpol (car (entsel "\nSéléctionnez une polyligne")))

Cordialement

Posté(e)

Merci @Fraid,

 

Récupérer les sommets d'une poly3D, pas de souci, ça je sais faire. Mais c'est la suite, à savoir calculer le Z pour un XY quelconque (sur la polyligne en vue de dessus).

Actuellement, je calcule le Z par interpolation sur le segment sur lequel se trouve mon point, mais comme j'ai 300 poly3D ayant chacune en 20 et 500 sommets et que je vais devoir faire 3500 calculs de Z, ça me prend un peu de temps, d'où ma recherche d'une fonction native, sûrement plus rapide.

 

Olivier

Posté(e)

Bonjour, peut être en deux fois:

pour avoir l'absice du point sur la poly (vlax-curve-getDistAtPoint courbe-obj point )

puis (vlax-curve-getPointAtParam courbe-obj (resultat précedent))

Posté(e)
il y a 24 minutes, Olivier Eckmann a dit :

XY quelconque

J'avais compris sur les poignées...

Sinon c'est de la trigo. 

Mais il faut aller lire les coordonnées du point d'après.

Ce qui te permet de calculer l'angle du segment, puis avec la distance entre la premiere poignée et le point, la difference de hauteur.

Posté(e)

Oui, toutes les fonctions de type vlax-curve qui demande un point nécessite que le point soit sur la courbe. Or dans mon cas, il y est en XY, mais pas en Z.

Donc OK, je passe par la recherche du segment et l'interpolation par règle de 3 sur le segment concerné.

Je verrais si je peux améliorer les performances.

 

Olivier

Posté(e)

Bonjour @Olivier Eckmann

Je te propose de calculer l'intersection d'une ligne verticale issue du point en 2D.
Amicalement

(setq ent (vlax-ename->vla-object(car (entsel"\nChoix de la polyligne \n"))))
(setq pt (getpoint "\nChoix du point \n"))
(command "_line" pt "@0,0,1" "")
(setq ent2 (vlax-ename->vla-object (entlast)))
(setq inter (vla-IntersectWith ent ent2 acExtendOtherEntity))
(setq ptz (vlax-safearray->list (vlax-variant-value inter)))
(entdel (entlast))

C'est un squelette, mais on peut utiliser une liste de points.

Posté(e)

Je me permet d'insister. vlax-curve-getClosestPointToProjection ne renvoie pas le même résultat que vlax-curve-getClosestPointTo.

Essaye cette routine.

(defun c:test (/ pl dxf pt)
  (if
    (and
      (setq pl (car (entsel "\nSélectionnez une polyligne 3d: ")))
      (= (cdr (assoc 0 (setq dxf (entget pl)))) "POLYLINE")
      (= 8 (logand 8 (cdr (assoc 70 dxf))))
    )
     (while (setq pt (getpoint "\nSpécifiez un point: "))
       (setq pt (trans pt 1 0))
       (entmake
	 (list '(0 . "LINE")
	       '(62 . 3)
	       (cons 10 pt)
	       (cons 11
		     (vlax-curve-getClosestPointToProjection
		       pl
		       pt
		       '(0 0 1)
		     )
	       )
	 )
       )
       (entmake
	 (list '(0 . "LINE")
	       '(62 . 1)
	       (cons 10 pt)
	       (cons 11
		     (vlax-curve-getClosestPointTo
		       pl
		       pt
		     )
	       )
	 )
       )
     )
  )
  (princ)
)

image.thumb.png.35789756af16e389aa7125e94a757d7a.png

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

Posté(e)

Bonjour Olivier,

Je ne sais si ça pourra d'être d'utilité pour toi, mais j'ai fait ce code pour insérer un sommet (en boucle) sur une poly3D selon un point donné graphiquement; qu'il soit exactement sur la 3Dpoly ou proche, l'alignement du vertex impacté n'est pas changé. Le Z est interpolé.

(defun l-coor2l-pt (obj lst flag / )
  (if lst
    (cons
      (list
        (car lst)
        (cadr lst)
        (if flag
          (+ (if (vlax-property-available-p obj 'Elevation) (vlax-get obj 'Elevation) 0.0) (caddr lst))
          (if (vlax-property-available-p obj 'Elevation) (vlax-get obj 'Elevation) 0.0)
        )
      )
      (l-coor2l-pt obj (if flag (cdddr lst) (cddr lst)) flag)
    )
  )
)
(defun c:add_vertex-3D ( / ss AcDoc Space obj_vla l_coor last_p pt pt_vtx new_vtx prm indx flag nw_coor)
  (princ "\nSélection d'une polyligne non lissée")
  (while (null (setq ss (ssget "_+.:E:S" '((0 . "POLYLINE") (-4 . "<AND") (-4 . "&") (70 . 8) (-4 . "<NOT") (-4 . "&") (70 . 4) (-4 . "NOT>") (-4 . "AND>"))))))
  (setq
    AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))
    Space
    (if (eq (getvar "CVPORT") 1)
      (vla-get-PaperSpace AcDoc)
      (vla-get-ModelSpace AcDoc)
    )
    obj_vla (vlax-ename->vla-object (ssname ss 0))
    l_coor (l-coor2l-pt obj_vla (vlax-get obj_vla 'Coordinates) T)
    last_p (last l_coor)
  )
  (initget 8)
  (while (setq pt (getpoint "\nNouveau sommet au point : "))
    (setq
      pt_vtx (vlax-curve-getClosestPointToProjection obj_vla (trans pt 1 0) '(0 0 1) nil)
      new_vtx (vlax-3d-point last_p)
      prm (vlax-curve-getParamAtPoint obj_vla pt_vtx)
      indx -1
    )
    (cond
      ((and (not (equal pt_vtx (vlax-curve-getStartPoint obj_vla) 1E-08)) (not (equal pt_vtx (vlax-curve-getEndPoint obj_vla) 1E-08)))
        (vla-AppendVertex obj_vla new_vtx)
        (repeat (if (vlax-curve-isClosed obj_vla) (fix (vlax-curve-getEndParam obj_vla)) (1+ (fix (vlax-curve-getEndParam obj_vla))))
          (setq indx (1+ indx))
          (if (or (not (eq indx (1+ (fix prm)))) flag)
            (setq nw_coor (cons (vlax-curve-getPointAtParam obj_vla indx) nw_coor))
            (setq nw_coor (cons pt_vtx nw_coor) indx (1- indx) flag T)
          )
        )
        (setq indx -1)
        (foreach e (reverse nw_coor)
          (vlax-put-property obj_vla 'Coordinate (setq indx (1+ indx)) (vlax-3d-point e))
        )
        (setq
          l_coor (l-coor2l-pt obj_vla (vlax-get obj_vla 'Coordinates) T)
          last_p (last l_coor)
          nw_coor nil
          flag nil
        )
        (sssetfirst nil ss)
      )
      (T (princ "\nPoint confondu à une des extrémités."))
    )
    (initget 8)
  )
  (sssetfirst nil nil)
  (prin1)
)

 

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

Posté(e)

Salut @(gile),

 

Tu as bien fait d'insister, car je n'avais pas vu ton 1er message. Je viens de tester ta fonction sur ma poly3D et ça ne fonctionne pas.

Les projections sont bien différentes, mais aucune n'est verticale, ou alors, je n'ai pas compris comment l'utiliser.

Je joins le fichier pour test. J'ai essayé de déplacer vers 0,0 car je suis en grande coordonnées topo (RGF93.CC49) pour l'Ile de France, mais pas mieux.

https://www.swisstransfer.com/d/b73ddcce-c04e-41a2-a102-3cf6ea5b5766

 

@bonuscad, j'ai vu dans ton code que tu utilises aussi GetClosestPointToProjection, donc j'ai peur que ça ne me génère le même souci que le code de Gilles et ce que j'avais testé initialement.

 

Olivier

Posté(e)

Effectivement avec ton fichier en première instance ma routine ne fonctionne pas (rien ne se passe)

Mais si j'utilise OVERKILL (tu as de nombreux sommets dupliqués, jusqu'à 4 fois), ma routine a fonctionné par la suite sans me rapprocher du zéro en origine.

J'espère que mon analyse te fera avancer...

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

Posté(e)

Merci @bonuscad pour ton analyse, je savais bien qu'il y avait un schmilblick quelque part, mais je n'ai pas du tout pensé aux sommets superposés.

C'est quand même dingue que des sommets superposés mettent en l'air l'API. En tout cas, je vais pouvoir avancer sur mon projet, c'est cool.

@didier, oui, j'avais déjà constaté que dans les grandes coordonnées la fonction IntersectWith me renvoyait des intersections qui n'existaient pas ou pas d'intersection, alors qu'il y en avait bien une. C'est vraiment embêtant cette histoire. On est les seuls en France a travaillé avec de tels systèmes? ou tout le monde s'en fout chez Autodesk?

 

Merci à tous, je vais poursuivre et garder cette histoire de sommets superposés en mémoire pour penser à nettoyer désormais mes géométries avant de travailler dessus.

 

Olivier

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é