Author Topic: to know the PICKED SEGMENT of a 3DFACE  (Read 1389 times)

0 Members and 1 Guest are viewing this topic.

domenicomaria

  • Swamp Rat
  • Posts: 725
to know the PICKED SEGMENT of a 3DFACE
« on: May 14, 2023, 02:00:38 PM »
I need to select a (triangular) 3dface with entsel
and I need to know what is the segment that I have picked.

So first of all, I need tho know what is the closest point
to the point returned by entsel

But vlax-curve-getClosestPointto is not available !

Is there some workaround ?


ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #1 on: May 14, 2023, 02:05:53 PM »
You could try :

Code: [Select]
...
(setq entpt (entsel "\nPick 3DFACE..."))
(setq ent (car entpt))
(setq pt (osnap (cadr entpt) "_nea"))
...

pt variable should snap to edge like you were using (vlax-curve-getclosestpointto ent ptwcs)...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

domenicomaria

  • Swamp Rat
  • Posts: 725
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #2 on: May 14, 2023, 02:10:12 PM »
yes Ribarm . . .

But I prefer a more elegant solution . . .

Or just a mathematical solution!

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #3 on: May 14, 2023, 04:28:36 PM »
define 'elegance'  with a condition of practical functionality.

and why is it critical to you ?

and how is the solution provided not 'elegant' ?


 :roll:  and why wasn't that condition part of your 'specification' ?
« Last Edit: May 14, 2023, 04:40:16 PM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

domenicomaria

  • Swamp Rat
  • Posts: 725
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #4 on: May 14, 2023, 11:30:53 PM »
suppose we are not in the ACAD environment ... and we have a simple geometry problem ... given a 3d point and a triangle defined by 3 3d points, we want to determine which segment of the triangle is closest to the point ... certainly it is possible to solve this problem ... and there are probably various ways to do it ... that's what I mean, when I talk about more elegant mathematical solution ... that's all

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #5 on: May 14, 2023, 11:52:19 PM »
Yes, I imagine it is possible, but not in 3 lines of code, and not in a form that 'most' lisp programmers would be able to debug.

I'm mildly interested in why you'd prefer a mathematical solution.

Regards,
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #6 on: May 15, 2023, 12:15:05 AM »
>>> and we have a simple geometry problem

Just thinking about it :

In 3D
determine if the triangle vertex's are planar.
determine if the test point is in the same plane.
in sequence, for each of the sides, determine the closest distance from the point and the closest point to that side.
return the chosen point for the closest line.

piece of cake in 2D, 3D is a little more complicated.

definitely more that 3 lines of code.


« Last Edit: May 15, 2023, 02:25:53 AM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #7 on: May 15, 2023, 01:19:49 AM »
Hi,
You can use these functions from the MathGeom library at the bottom of this page.

gc:DistanceTo return the distance from a point (pt) to an infinite line defined by two points (p1 and p2).
Code - Auto/Visual Lisp: [Select]
  1. ;; gc:DistanceTo
  2. ;; Retourne la distance du point pt à la droite p1 p2
  3. ;;
  4. ;; Arguments
  5. ;; pt : le point extérieur à la droite
  6. ;; p1 : un point sur la droite
  7. ;; p2 : un point sur la droite
  8. (defun gc:DistanceTo (pt p1 p2)
  9.   ((lambda (v)
  10.      (/
  11.        (distance '(0. 0. 0.) (gc:CrossProduct (mapcar '- pt p1) v))
  12.        (distance '(0. 0. 0.) v)
  13.      )
  14.    )
  15.     (mapcar '- p2 p1)
  16.   )
  17. )
  18.  
  19. ;; gc:CrossProduct
  20. ;; Retourne le produit vectoriel (vecteur) de deux vecteurs
  21. ;; Arguments
  22. ;; v1, v2 : deux vecteurs
  23. (defun gc:CrossProduct (v1 v2)
  24.   (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2)))
  25.         (- (* (caddr v1) (car v2)) (* (car v1) (caddr v2)))
  26.         (- (* (car v1) (cadr v2)) (* (cadr v1) (car v2)))
  27.   )
  28. )
Speaking English as a French Frog

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #8 on: May 15, 2023, 01:33:23 AM »
Another one still using vector calculus (routines from the same library).
 gc:ProjectOnLine is equivalent to vlax-curve-getClosestPoint when the curve is an Xline.
Code - Auto/Visual Lisp: [Select]
  1. ;; gc:ProjectOnLine
  2. ;; Retourne la projection de pt sur la droite p1 p2
  3. ;;
  4. ;; Arguments
  5. ;; pt : le point à projeter
  6. ;; p1 : un point sur la droite
  7. ;; p2 : un point sur la droite
  8. (defun gc:ProjectOnLine (pt p1 p2)
  9.   ((lambda (u v)
  10.      (mapcar '+ p1 (gc:ScaleVector u (gc:DotProduct u v)))
  11.    )
  12.     (gc:GetUnitVector p1 p2)
  13.     (gc:GetVector p1 pt)
  14.   )
  15. )
  16.  
  17. ;; gc:GetVector
  18. ;; Retourne le vecteur de p1 à p2
  19. ;;
  20. ;; Arguments
  21. ;; p1, p2 : 2 points
  22. (defun gc:GetVector (p1 p2) (mapcar '- p2 p1))
  23.  
  24. ;; gc:ScaleVector
  25. ;; Multiplie le vecteur par un scalaire
  26. ;;
  27. ;; Arguments
  28. ;; v : un vecteur
  29. ;; s : un nombre
  30. (defun gc:ScaleVector (v s)
  31.   (mapcar (function (lambda (x) (* x s))) v)
  32. )
  33.  
  34. ;; gc:DotProduct
  35. ;; Retourne le produit scalaire de deux vecteurs
  36. ;; Arguments
  37. ;; v1, v2 : deux vecteurs
  38. (defun gc:DotProduct (v1 v2) (apply '+ (mapcar '* v1 v2)))
  39.  
  40. ;; gc:GetUnitVector
  41. ;; Retourne le vecteur unitaire de sens p1 p2
  42. ;;
  43. ;; Arguments
  44. ;; p1, p2 : 2 points
  45. (defun gc:GetUnitVector (p1 p2)
  46.   ((lambda (d)
  47.      (if (not (zerop d))
  48.        (mapcar (function (lambda (x1 x2) (/ (- x2 x1) d))) p1 p2)
  49.      )
  50.    )
  51.     (distance p1 p2)
  52.   )
  53. )
Speaking English as a French Frog

domenicomaria

  • Swamp Rat
  • Posts: 725
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #9 on: May 15, 2023, 02:34:35 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun :DXF (code elist) (cdr (assoc code elist)))
  2.  
  3. (defun C:3DF-CLOSEST-SIDE-2PT-GC  (   /
  4.                                      p10 p11 p12 prjctn-lst the-winner-is x-el x-en x-es
  5.                                      x-et x-pt x-pt-10-11 x-pt-11-12 x-pt-12-10
  6.                                  )
  7.    (and
  8.       (setq x-es  (entsel "\nselct a 3DFACE :") )
  9.       (setq x-en  (car x-es) )
  10.       ;   (setq x-pt  (cadr  x-es  ) )
  11.       (setq x-el  (entget x-en ) )
  12.       (setq x-et  (:DXF 0 x-el ) )
  13.       (= x-et "3DFACE")
  14.       (setq p10 (:DXF 10 x-el) p11 (:DXF 11 x-el) p12 (:DXF 12 x-el) )
  15.      
  16.       (setq x-pt (getpoint "\nenter a POINT :") )
  17.      
  18.       (setq x-pt-10-11 (GC:PROJECTONLINE x-pt p10 p11) )
  19.       (setq x-pt-11-12 (GC:PROJECTONLINE x-pt p11 p12) )
  20.       (setq x-pt-12-10 (GC:PROJECTONLINE x-pt p12 p10) )
  21.      
  22.       (setq   prjctn-lst
  23.               (list
  24.                  (list (equal (+ (distance x-pt-10-11 p10) (distance x-pt-10-11 p11))
  25.                               (distance p10 p11)
  26.                               1e-6
  27.                        )
  28.                        x-pt-10-11
  29.                        (distance x-pt-10-11 x-pt)
  30.                        p10
  31.                        p11
  32.                  )
  33.                  (list (equal (+ (distance x-pt-11-12 p11) (distance x-pt-11-12 p12))
  34.                               (distance p11 p12)
  35.                               1e-6
  36.                        )
  37.                        x-pt-11-12
  38.                        (distance x-pt-11-12 x-pt)
  39.                        p11
  40.                        p12
  41.                  )
  42.                  (list (equal (+ (distance x-pt-12-10 p12) (distance x-pt-12-10 p10))
  43.                               (distance p12 p10)
  44.                               1e-6
  45.                        )
  46.                        x-pt-12-10
  47.                        (distance x-pt-12-10 x-pt)
  48.                        p12
  49.                        p10
  50.                  )
  51.               )
  52.       )
  53.  
  54.      
  55.       ;   escluding, external to the sides, projections
  56.       (setq prjctn-lst (vl-remove-if '(lambda (i) (not (car i) ) ) prjctn-lst) )
  57.  
  58.       (setq prjctn-lst (mapcar 'cdr prjctn-lst) )
  59.  
  60.       (setq prjctn-lst (vl-sort prjctn-lst '(lambda (i j) (< (cadr i) (cadr j) ) ) ) )
  61.                                              
  62.       (setq the-winner-is (car prjctn-lst) ) ; ! ! !
  63.  
  64.       (entmakex (list (cons 0 "POINT") (cons 10 (car the-winner-is ) ) ) )
  65.       (grdraw (caddr the-winner-is) (cadddr the-winner-is) 222 0)
  66.    )
  67. )

It seems to work !


Thank you so much Gile !

Your work and lisp functions on your site
they are always very helpful.

ciao
« Last Edit: May 15, 2023, 10:58:26 AM by domenicomaria »

domenicomaria

  • Swamp Rat
  • Posts: 725
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #10 on: May 15, 2023, 02:45:37 AM »
And in any case for practical and daily uses,
I will use Ribarm's solution. . . !

But GILE's suggestion is interesting,
for many other situations!

domenicomaria

  • Swamp Rat
  • Posts: 725
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #11 on: May 15, 2023, 03:04:24 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun c:3DF-CLOSEST-SIDE-2PT-MR  ( /
  2.                          p10 p11 p12 prjctn-lst r x-el x-en x-es x-et x-pt
  3.                      )
  4.    (and
  5.       (setq x-es  (entsel "\nselect a 3DFACE :") )
  6.       (setq x-en  (car x-es) )
  7.       (setq x-pt  (cadr  x-es  ) )
  8.       (setq x-el  (entget x-en ) )
  9.       (setq x-et  (:DXF 0 x-el ) )
  10.       (= x-et "3DFACE")
  11.       (setq p10 (:DXF 10 x-el) p11 (:DXF 11 x-el) p12 (:DXF 12 x-el) )
  12.       (setq x-pt (osnap x-pt "_nea"))
  13.  
  14.       (setq   prjctn-lst
  15.               (list
  16.                  (list (equal (+ (distance x-pt p10) (distance x-pt p11))
  17.                               (distance p10 p11)
  18.                               1e-6
  19.                        )
  20.                        p10
  21.                        p11
  22.                  )
  23.                  (list (equal (+ (distance x-pt p11) (distance x-pt p12))
  24.                               (distance p11 p12)
  25.                               1e-6
  26.                        )
  27.                        p11
  28.                        p12
  29.                  )
  30.                  (list (equal (+ (distance x-pt p12) (distance x-pt p10))
  31.                               (distance p12 p10)
  32.                               1e-6
  33.                        )
  34.                        p12
  35.                        p10
  36.                  )
  37.               )
  38.       )
  39.       (setq prjctn-lst (vl-remove-if '(lambda (i) (not (car i) ) ) prjctn-lst) )
  40.       (setq r (cdar prjctn-lst) )
  41.    )
  42.    
  43.    (if r (grdraw (car r) (cadr r) 222 0) )
  44.    r
  45. )

While this one, is the version using the Ribarm suggestion ...
« Last Edit: May 15, 2023, 05:30:17 AM by domenicomaria »

domenicomaria

  • Swamp Rat
  • Posts: 725
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #12 on: May 15, 2023, 09:17:57 AM »
it is important before the use of osnap
(setq x-pt (osnap x-pt "_nea"))
to check the size of aperture ...

I do this :
(setvar "aperture" (getvar "pickbox") )

ribarm

  • Gator
  • Posts: 3279
  • Marko Ribar, architect
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #13 on: May 15, 2023, 03:33:18 PM »
I just want to point that 3DFACE entity could have 4 vertices instead of 3 like you've imagined; plus that 4th point can be non coplanar giving the shape of small hyperbolic-paraboloid...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

domenicomaria

  • Swamp Rat
  • Posts: 725
Re: to know the PICKED SEGMENT of a 3DFACE
« Reply #14 on: May 15, 2023, 11:35:36 PM »
@Ribarm
I know well that a 3Dface has allways 4 vertices

When it has only 3 sides, is because 2 vertices are coincident.

And the fourth point can be also not complanar to the others.