TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: ribarm on July 12, 2012, 12:58:59 PM

Title: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 12, 2012, 12:58:59 PM
Hi all, I am pretty stucked here... I've tried to write missing vlax-curve-function, but keep getting error :

Code: [Select]
(setq e (car (entsel))) => picked curve - spline
(setq p (getpoint)) => picked point

Command: (vlax-curve-getfurthestpointto e p)
Hard error occurred ***
internal stack limit reached (simulated)

Here is my function :

Code - Auto/Visual Lisp: [Select]
  1. (defun vlax-curve-getfurthestpointto ( ent pt / f )
  2.   (defun f ( ps pe e p / stpar enpar par1 par2 p1 p2 p3 p4 ptlst ptlstsort )
  3.   (if (null stpar) (setq stpar (vlax-curve-getstartparam e)) (setq stpar (vlax-curve-getparamatpoint e ps)))
  4.   (if (null enpar) (setq enpar (vlax-curve-getendparam e)) (setq enpar (vlax-curve-getparamatpoint e pe)))
  5.   (setq par1 (+ stpar (* (- enpar stpar) (/ 1.0 3.0))))
  6.   (setq par2 (+ stpar (* (- enpar stpar) (/ 2.0 3.0))))
  7.   (setq ptlst (list p1 p2 p3 p4))
  8.   (setq ptlstsort (vl-sort ptlst '(lambda ( a b ) (> (distance p a) (distance p b)))))
  9.   (if (= (length ptlstsort) 4)
  10.     (if (< (vlax-curve-getparamatpoint e (car ptlstsort)) (vlax-curve-getparamatpoint e (cadr ptlstsort)))
  11.       (f (car ptlstsort) (cadr ptlstsort) e p)
  12.       (f (cadr ptlstsort) (car ptlstsort) e p)
  13.     )
  14.     (car ptlstsort)
  15.   )
  16.   )
  17.   (f nil nil ent pt)
  18. )
  19.  

Can someone help?

M.R.
Title: Re: vlax-curve-getfurthestpointto
Post by: BlackBox on July 12, 2012, 02:01:51 PM
Marco,

Perhaps I am not understanding what you are trying to do, but wouldn't the 'furthest point from' be either the start or end point (or both if selecting the midpoint)?  :?
Title: Re: vlax-curve-getfurthestpointto
Post by: ronjonp on July 12, 2012, 02:29:50 PM
Not necessarily...
Title: Re: vlax-curve-getfurthestpointto
Post by: ribarm on July 12, 2012, 02:36:52 PM
I want that algorithm search for the point it's easiest to find...

@Render - I suppose you thought on line as curve or circle and mid or center for point...
Then, like (vlax-curve-getclosestpointto) function retrieves point on circle when picked center as reference point, I want to make (vlax-curve-getfurthestpointto) function...

@Ron - I agree, you can get one solution witch I am searching for...

M.R.
Title: Re: vlax-curve-getfurthestpointto
Post by: BlackBox on July 12, 2012, 02:40:21 PM
I'm still not understanding, so I'll just step back and observe for a bit. All of the smart talk is not computing for me today... Good luck, Marco.
Title: Re: vlax-curve-getfurthestpointto
Post by: zoltan on July 12, 2012, 02:44:32 PM
Shouldn't it be furthest point FROM?  :-D

I think this is going to recurse forever because (length ptlstsort) is always going to be 4.
Title: Re: vlax-curve-getfurthestpointto
Post by: ribarm on July 12, 2012, 02:54:50 PM
Function name isn't so important I thought TO - like closest point to...

My function uses vl-sort function witch should remove duplicates when reaching solution point, so (length ptlstsort) shouldn't be always 4 - that was the main point of my code... But now I see that recursion isn't so good approach as there are cases when length should be 4 and already met opportunities for solution : line with mid or circle, ellipse with center...
Title: Re: vlax-curve-getfurthestpointto
Post by: BlackBox on July 12, 2012, 02:55:14 PM
Not necessarily...

Just saw this, thanks ronjon.  :wink:
Title: Re: vlax-curve-getfurthestpointto
Post by: zoltan on July 12, 2012, 03:14:43 PM
Function name isn't so important I thought TO - like closest point to...

My function uses vl-sort function witch should remove duplicates when reaching solution point, so (length ptlstsort) shouldn't be always 4 - that was the main point of my code... But now I see that recursion isn't so good approach as there are cases when length should be 4 and already met opportunities for solution : line with mid or circle, ellipse with center...

Oh yea.. for some reason I thought VL-Sort would always return a list of the same length.

If I am understanding this correctly, you are dividing the curve into 4 points, the start point, 1/3, 2/3 and the end point.  Then sorting this list by the descending distance from the test point and recursing the function between the furthest point and the second furthest point in a divide-and-concur type approach.

It might take a very long time before the function reaches a local minimum and two distances in the list will be the same because the real number that represents the parameter at the point can be very accurate.  You may need to see if the two distances parameters differ by some tolerance.

The other problem is when the actual furthest point is not between the first and second test points. See attached case:
Title: Re: vlax-curve-getfurthestpointto
Post by: zoltan on July 12, 2012, 05:00:13 PM
Code - Auto/Visual Lisp: [Select]
  1. (Defun ZF-GetFurthestPointFrom (CURVE POINT / FurthestParameter )
  2.  (Defun FurthestParameter (SP EP TOL / params dist )
  3.   (SetQ params (List SP
  4.                      (+ SP (* (- EP SP) (/ 1.0 3.0)) )
  5.                      (+ SP (* (- EP SP) (/ 2.0 3.0)) )
  6.                      EP
  7.                )
  8.   )
  9.  
  10.   (SetQ dist (Vl-Sort-I params
  11.                         (Function
  12.                          (Lambda (a b)
  13.                           (> (Distance POINT (VLAX-Curve-GetPointAtParam CURVE a))
  14.                              (Distance POINT (VLAX-Curve-GetPointAtParam CURVE b))
  15.                           )
  16.                          )
  17.                         )
  18.              )
  19.   )
  20.  
  21.   (If (> (- EP SP) TOL)
  22.    (FurthestParameter
  23.     (If (= (Car dist) 0)
  24.      (Nth (Car dist) params )
  25.      (Nth (1- (Car dist)) params )
  26.     )
  27.     (If (= (Car dist) (1- (Length params)))
  28.      (Nth (Car dist) params )
  29.      (Nth (1+ (Car dist)) params )
  30.     )
  31.     TOL
  32.    )
  33.    (Nth (Car dist) params)
  34.   )
  35.  )
  36.  
  37.  (VLAX-Curve-GetPointAtParam CURVE (FurthestParameter (VLAX-Curve-GetStartParam CURVE) (VLAX-Curve-GetEndParam CURVE) 0.0001) )
  38. )
  39.  
Title: Re: vlax-curve-getfurthestpointto
Post by: ribarm on July 12, 2012, 05:11:39 PM
Thanks, Zoltan... It works very well...

I thought ab tolerance and you were faster and I failed to complete my code... Yours is fine...

M.R. :wink:
Title: Re: vlax-curve-getfurthestpointto
Post by: zoltan on July 12, 2012, 05:30:08 PM
I'm just happy I still remember how to write Lisp!  :lmao:

Minor (anal) revision:
Code - Auto/Visual Lisp: [Select]
  1. (Defun ZF-GetFurthestPointFrom (CURVE POINT / FurthestParameter epsilon )
  2.  (SetQ epsilon 0.0001 )
  3.  (Defun FurthestParameter (SP EP / params furthest )
  4.   (SetQ params (List SP
  5.                      (+ SP (* (- EP SP) (/ 1.0 3.0)) )
  6.                      (+ SP (* (- EP SP) (/ 2.0 3.0)) )
  7.                      EP
  8.                )
  9.   )
  10.  
  11.   (SetQ furthest (Car (Vl-Sort-I params
  12.                                  (Function
  13.                                   (Lambda (a b)
  14.                                    (> (Distance POINT (VLAX-Curve-GetPointAtParam CURVE a))
  15.                                       (Distance POINT (VLAX-Curve-GetPointAtParam CURVE b))
  16.                                    )
  17.                                   )
  18.                                  )
  19.                       )
  20.                  )
  21.   )
  22.  
  23.   (If (> (- EP SP) epsilon)
  24.    (FurthestParameter
  25.     (If (= furthest 0)
  26.      (Nth furthest params )
  27.      (Nth (1- furthest) params )
  28.     )
  29.     (If (= furthest (1- (Length params)))
  30.      (Nth furthest params )
  31.      (Nth (1+ furthest) params )
  32.     )
  33.    )
  34.    (Nth furthest params)
  35.   )
  36.  )
  37.  
  38.  (VLAX-Curve-GetPointAtParam CURVE (FurthestParameter (VLAX-Curve-GetStartParam CURVE) (VLAX-Curve-GetEndParam CURVE)) )
  39. )
  40.  
Title: Re: vlax-curve-getfurthestpointto
Post by: Lee Mac on July 12, 2012, 05:43:06 PM
The process could be more efficient for some entities for which the extrema must lie on the vertices:

Code - Auto/Visual Lisp: [Select]
  1. (defun vlax-curve-getfurthestpointfrom ( ent pt / elst etype )
  2.     (setq elst (entget ent))
  3.     (cond
  4.         (   (= "XLINE" (setq etype (cdr (assoc 0 elst))))
  5.             nil
  6.         )
  7.         (   (= "LINE" etype)
  8.             (if (< (distance pt (cdr (assoc 10 elst)))
  9.                    (distance pt (cdr (assoc 11 elst)))
  10.                 )
  11.                 (cdr (assoc 11 elst))
  12.                 (cdr (assoc 10 elst))
  13.             )
  14.         )
  15.         (   (and
  16.                 (= "LWPOLYLINE" etype)
  17.                 (vl-every '(lambda ( x ) (or (/= 42 (car x)) (zerop (cdr x)))) elst)
  18.             )
  19.             (car
  20.                 (vl-sort (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= 10 (car x))) elst))
  21.                     (function
  22.                         (lambda ( a b ) (> (distance pt a) (distance pt b)))
  23.                     )
  24.                 )
  25.             )
  26.         )
  27.         (   t
  28.             <other entities>
  29.         )
  30.     )
  31. )
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 13, 2012, 01:15:52 AM
Thank you Lee very much... Only skipped "RAY", so my final function with acceptable tolerance for almost if not exact result is 1e-8...

Code - Auto/Visual Lisp: [Select]
  1. (Defun ZF-GetFurthestPointFrom (CURVE POINT TOL / FurthestParameter )
  2. (Defun FurthestParameter (SP EP TOL / params dist )
  3.  (SetQ params (List SP
  4.                     (+ SP (* (- EP SP) (/ 1.0 3.0)) )
  5.                     (+ SP (* (- EP SP) (/ 2.0 3.0)) )
  6.                     EP
  7.               )
  8.  )
  9.  
  10.  (SetQ dist (Vl-Sort-I params
  11.                        (Function
  12.                         (Lambda (a b)
  13.                          (>= (Distance POINT (VLAX-Curve-GetPointAtParam CURVE a))
  14.                              (Distance POINT (VLAX-Curve-GetPointAtParam CURVE b))
  15.                          )
  16.                         )
  17.                        )
  18.             )
  19.  )
  20.  
  21.  (If (> (- EP SP) TOL)
  22.   (FurthestParameter
  23.    (If (< (Nth (Car dist) params) (Nth (Cadr dist) params))
  24.     (Nth (Car dist) params)
  25.     (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth (Car dist) params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr dist) params)) 1e-8))
  26.      (Nth (Cadr dist) params)
  27.      (Nth (Caddr dist) params)
  28.     )
  29.    )
  30.    (If (< (Nth (Car dist) params) (Nth (Cadr dist) params))
  31.     (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth (Car dist) params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr dist) params)) 1e-8))
  32.      (Nth (Cadr dist) params)
  33.      (Nth (Caddr dist) params)
  34.     )
  35.     (Nth (Car dist) params)
  36.    )
  37.    TOL
  38.   )
  39.   (Nth (Car dist) params)
  40.  )
  41. )
  42.  
  43. (VLAX-Curve-GetPointAtParam CURVE (FurthestParameter (VLAX-Curve-GetStartParam CURVE) (VLAX-Curve-GetEndParam CURVE) TOL) )
  44. )
  45.  
  46. (defun vlax-curve-getfurthestpointfrom ( ent pt / elst etype )
  47.        (setq elst (entget ent))
  48.        (cond
  49.            (   (= "XLINE" (setq etype (cdr (assoc 0 elst))))
  50.                nil
  51.            )
  52.            (   (= "RAY" (setq etype (cdr (assoc 0 elst))))
  53.                nil
  54.            )
  55.            (   (= "LINE" etype)
  56.                (if (< (distance pt (cdr (assoc 10 elst)))
  57.                       (distance pt (cdr (assoc 11 elst)))
  58.                    )
  59.                    (cdr (assoc 11 elst))
  60.                    (cdr (assoc 10 elst))
  61.                )
  62.            )
  63.            (   (and
  64.                    (= "LWPOLYLINE" etype)
  65.                    (vl-every '(lambda ( x ) (or (/= 42 (car x)) (zerop (cdr x)))) elst)
  66.                )
  67.                (car
  68.                    (vl-sort (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= 10 (car x))) elst))
  69.                        (function
  70.                            (lambda ( a b ) (> (distance pt a) (distance pt b)))
  71.                        )
  72.                    )
  73.                )
  74.            )
  75.            (   t
  76.                (ZF-GetFurthestPointFrom ent pt 1e-8)
  77.            )
  78.        )
  79. )
  80.  

P.S. You must use (vl-load-com) before lake every other vlax-curve-function...

M.R. :-)
Title: Re: vlax-curve-getfurthestpointfrom
Post by: Kerry on July 13, 2012, 01:26:26 AM

just to be pedantic ...
The vla-, vlax- naming prefix is recognised as the naming convention used by Visual Lisp library functions.

I'd prefer to see a different prefix if the code was to be used on one of my machines.


Regards
kdub.



ps:
probably best not to use kdub:xxxx or kdub-xxxx either   :-)
Title: Re: vlax-curve-getfurthestpointfrom
Post by: zoltan on July 13, 2012, 07:47:00 AM
The vla-, vlax- naming prefix is recognised as the naming convention used by Visual Lisp library functions.

I felt that way too, just decided it was not important enough to mention.  I think we should make it a convention of TheSwamp to always have the name of functions that you post be prefixed with you user name or initials.  That way, when multiple users post various solutions to the same problem, posters can refer to the different functions by name.

Here is a post which gives a good example:
http://www.theswamp.org/index.php?topic=42122.msg473506#msg473506
 
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 13, 2012, 08:18:20 AM
Zoltan, I agree, but this is an exeption - intension was to make real programmers to revide VisualLisp functions as this one was missed... BTW., I've changed your code - little modification as with circle and outside point gave wrong results (it searched for start point of circle, where both start and end parameters gave maximum distance and parameters were sorted so that these were solution to the return value; also changed fuzz factor little more acceptable not to come to hard error)...

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: BlackBox on July 13, 2012, 08:43:36 AM
Zoltan, I agree, but this is an exeption - intension was to make real programmers to revide VisualLisp functions as this one was missed

In that case:

Code - Auto/Visual Lisp: [Select]
  1. ;;;--------------------------------------------------------------------;
  2. ;;; Unprotect symbols:
  3. (pragma '((unprotect-assign vlax-Curve-GetFurthestPointFrom)))
  4. ;;;--------------------------------------------------------------------;
  5. (defun vlax-Curve-GetFurthestPointFrom ()
  6.   ;; <-- blah  
  7.   )
  8. ;;;--------------------------------------------------------------------;
  9. ;;; Protect symbols:
  10. (pragma '((protect-assign vlax-Curve-GetFurthestPointFrom)))
  11.  

... Or, one can always hop into Visual Studio and code an actual LispFunction Method.  ;-)

Title: Re: vlax-curve-getfurthestpointfrom
Post by: PKENEWELL on July 13, 2012, 10:47:42 AM
Thank you Lee very much... Only skipped "RAY", so my final function with acceptable tolerance for almost if not exact result is 1e-8...

Code - Auto/Visual Lisp: [Select]
  1. (Defun ZF-GetFurthestPointFrom (CURVE POINT TOL / FurthestParameter )
  2. (Defun FurthestParameter (SP EP TOL / params dist )
  3.  (SetQ params (List SP
  4.                     (+ SP (* (- EP SP) (/ 1.0 3.0)) )
  5.                     (+ SP (* (- EP SP) (/ 2.0 3.0)) )
  6.                     EP
  7.               )
  8.  )
  9.  
  10.  (SetQ dist (Vl-Sort-I params
  11.                        (Function
  12.                         (Lambda (a b)
  13.                          (>= (Distance POINT (VLAX-Curve-GetPointAtParam CURVE a))
  14.                              (Distance POINT (VLAX-Curve-GetPointAtParam CURVE b))
  15.                          )
  16.                         )
  17.                        )
  18.             )
  19.  )
  20.  
  21.  (If (> (- EP SP) TOL)
  22.   (FurthestParameter
  23.    (If (< (Nth (Car dist) params) (Nth (Cadr dist) params))
  24.     (Nth (Car dist) params)
  25.     (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth (Car dist) params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr dist) params)) 1e-8))
  26.      (Nth (Cadr dist) params)
  27.      (Nth (Caddr dist) params)
  28.     )
  29.    )
  30.    (If (< (Nth (Car dist) params) (Nth (Cadr dist) params))
  31.     (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth (Car dist) params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr dist) params)) 1e-8))
  32.      (Nth (Cadr dist) params)
  33.      (Nth (Caddr dist) params)
  34.     )
  35.     (Nth (Car dist) params)
  36.    )
  37.    TOL
  38.   )
  39.   (Nth (Car dist) params)
  40.  )
  41. )
  42.  
  43. (VLAX-Curve-GetPointAtParam CURVE (FurthestParameter (VLAX-Curve-GetStartParam CURVE) (VLAX-Curve-GetEndParam CURVE) TOL) )
  44. )
  45.  
  46. (defun vlax-curve-getfurthestpointfrom ( ent pt / elst etype )
  47.        (setq elst (entget ent))
  48.        (cond
  49.            (   (= "XLINE" (setq etype (cdr (assoc 0 elst))))
  50.                nil
  51.            )
  52.            (   (= "RAY" (setq etype (cdr (assoc 0 elst))))
  53.                nil
  54.            )
  55.            (   (= "LINE" etype)
  56.                (if (< (distance pt (cdr (assoc 10 elst)))
  57.                       (distance pt (cdr (assoc 11 elst)))
  58.                    )
  59.                    (cdr (assoc 11 elst))
  60.                    (cdr (assoc 10 elst))
  61.                )
  62.            )
  63.            (   (and
  64.                    (= "LWPOLYLINE" etype)
  65.                    (vl-every '(lambda ( x ) (or (/= 42 (car x)) (zerop (cdr x)))) elst)
  66.                )
  67.                (car
  68.                    (vl-sort (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= 10 (car x))) elst))
  69.                        (function
  70.                            (lambda ( a b ) (> (distance pt a) (distance pt b)))
  71.                        )
  72.                    )
  73.                )
  74.            )
  75.            (   t
  76.                (ZF-GetFurthestPointFrom (vlax-ename->vla-object ent) pt 1e-8)
  77.            )
  78.        )
  79. )
  80.  

P.S. You must use (vl-load-com) before lake every other vlax-curve-function...

M.R. :-)

@ribarm:

Nice code! One slight issue - when you call all the "vlax-curve" functions you need to supply your "CURVE" argument as a VLA-Object, rather than an entity name
I corrected your call to "ZF-GetFurthestPointFrom" in the quote above to use (vlax-ename->vla-object ent).

- Phil
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 13, 2012, 11:00:48 AM
If you didn't noticed vlax-curve-functions don't need VLA-OBJECT as argument - it is totally acceptable for argument to be ENAME... And no it's not nice code at all, it only works for circle and point that is not center and gives approx. correct result, but in all other cases of curves and I mean real curves not line, pline, xline... it will probably fail... This topic is only ilustrative - to point out that there is important missing vlax-curve function in VLisp... And who will provide solution, real one with exact return value like vlax-curve-getclosestpointto, I don't know, suppose the one that made vlax-curve-getclosestpointto (I would change sign of evaluating distances from < to > and I mean that this is probably the case... Only thing is how to make that someone that knows to do that to really do that...

All best, sincerely M.R. (arch. not programmer) (I know that I've tried, and maybe my effort won't be pointless)
Title: Re: vlax-curve-getfurthestpointfrom
Post by: BlackBox on July 13, 2012, 11:17:51 AM
@ribarm:

Nice code! One slight issue - when you call all the "vlax-curve" functions you need to supply your "CURVE" argument as a VLA-Object, rather than an entity name

@Phil - Your statement, and the developer documentation, are both incorrect.

Vlax-Curve-* functions _do_ accept both Vla-Object* and Ename as an acceptable argument... Try it for yourself.

** Edit - I made the same mistake when I started learning Vl* code. It happens.

I corrected your call to "ZF-GetFurthestPointFrom" in the quote above to use (vlax-ename->vla-object ent).

@Phil - Instead of correcting another's code when quoting them, consider posting _your own_ code block, as changing another's words/code, etc. is misleading.

** Edit - I don't believe this was your intention. Just trying to help.

All best, sincerely M.R. (arch. not programmer) (I know that I've tried, and maybe my effort won't be pointless)

@Marco -

Don't take it personal, my friend; you well know that we appreciate your programming efforts, and attempt(s) to further (no pun intended) the Visual LISP code library of sorts.

Cheers! :beer:

Title: Re: vlax-curve-getfurthestpointfrom
Post by: PKENEWELL on July 13, 2012, 11:21:45 AM
If you didn't noticed vlax-curve-functions don't need VLA-OBJECT as argument - it is totally acceptable for argument to be ENAME... And no it's not nice code at all, it only works for circle and point that is not center and gives approx. correct result, but in all other cases of curves and I mean real curves not line, pline, xline... it will probably fail... This topic is only ilustrative - to point out that there is important missing vlax-curve function in VLisp... And who will provide solution, real one with exact return value like vlax-curve-getclosestpointto, I don't know, suppose the one that made vlax-curve-getclosestpointto (I would change sign of evaluating distances from < to > and I mean that this is probably the case... Only thing is how to make that someone that knows to do that to really do that...

All best, sincerely M.R. (arch. not programmer) (I know that I've tried, and maybe my effort won't be pointless)

 :-( Sorry. Guess I should've tested it more, but It did work nicely on the spline I tried it on. Forgive me for trying to give a compliment...  :ugly:

Also - I always assumed that the (vlax-curve... functions excepted only a VLA-object since that is what the argument refers to in AutoCAD's developer help and never tried putting and entity name on them. Since I always proof read code before trying it, I just made the correction and I did not realize they would also take an ENAME as well - thanks for the bit of knowledge.

- Phil.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ronjonp on July 13, 2012, 11:27:16 AM
If I remember correctly, the performance of supplying an ename over a vla-object is quite significant too  8-)
Title: Re: vlax-curve-getfurthestpointfrom
Post by: zoltan on July 13, 2012, 11:38:55 AM
Thank you Lee very much... Only skipped "RAY", so my final function with acceptable tolerance for almost if not exact result is 1e-8...

ribarm , You are still recursing the function between the furthest test point and the second furthest test point as in your first example.  You should be recursing between the test point before the furthest test point and the test point after the furthest test point.

Look again at the curve in the example I posted here:
http://www.theswamp.org/index.php?topic=42246.msg473876#msg473876

If the actual furthest point is not between the furthest and second furthest test points, it will produce incorrect results.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 13, 2012, 01:27:44 PM
Zoltan, it doesn't matter between witch points routine performs recursion, as there are cases where this method isn't good...
Look in picture I uploaded and you'll see that this method is useless... Only way to find correct result is to check every point or param. on curve.
I suppose this is how (vlax-curve-getclosestpointto) works, and only thing that should be done is inverse algorithm for vlax-curve-getclosestpointto to check distances that are > - larger, rather then < - smaller...

I've deliberately put my version into code to point that code isn't working...

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: zoltan on July 13, 2012, 02:24:54 PM
Zoltan, it doesn't matter between witch points routine performs recursion, as there are cases where this method isn't good...
Look in picture I uploaded and you'll see that this method is useless... Only way to find correct result is to check every point or param. on curve.

I see.  This problem just got more interesting.

It is not possible to test every parameter on the curve, because there is an infinite number of them (well, as many as there are real numbers in Lisp).  The divide-and-concur method should still work if we dividing the cure into many more points than just 4.  We will have to think of a logic to determine the number of points to give the best trade-off between speed and accuracy.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: BlackBox on July 13, 2012, 03:04:04 PM
Zoltan, it doesn't matter between witch points routine performs recursion, as there are cases where this method isn't good...
Look in picture I uploaded and you'll see that this method is useless... Only way to find correct result is to check every point or param. on curve.

I see.  This problem just got more interesting.

It is not possible to test every parameter on the curve, because there is an infinite number of them (well, as many as there are real numbers in Lisp).  The divide-and-concur method should still work if we dividing the cure into many more points than just 4.  We will have to think of a logic to determine the number of points to give the best trade-off between speed and accuracy.

Agreed; after ronjon's hint back on the first page I realized that this was going to be heavily dependent on precision. Perhaps as a starting point, we can use the ActiveDocument's current LUPREC (http://exchange.autodesk.com/autocad/enu/online-help/browse#WS1a9193826455f5ffa23ce210c4a30acaf-4f54.htm) value?

Also worthy of consideration, is mitigating the potential to overload the Stack (perhaps GC (http://exchange.autodesk.com/autocad/enu/online-help/browse#WS1a9193826455f5ff1a32d8d10ebc6b7ccc-6a18.htm) will help?).   :?

Otherwise, we'd need to use Linq + Lambda in .NET (to minimize the iterations to calculate result), no? Example (http://www.theswamp.org/index.php?topic=41911.0) (Sorry, you'll have to read through, don't have time to find exact post).
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 13, 2012, 03:25:12 PM
Vl-sort-i or vl-sort seems can't handle more elements in a list...

This isn't working also :

Code: [Select]
(Defun ZF-GetFurthestPointFrom (CURVE POINT TOL / FurthestParameter )
(Defun FurthestParameter (SP EP TOL / params dist )
 (SetQ params (List SP
                    (+ SP (* (- EP SP) (/ 1.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 2.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 3.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 4.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 5.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 6.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 7.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 8.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 9.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 10.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 11.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 12.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 13.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 14.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 15.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 16.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 17.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 18.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 19.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 20.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 21.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 22.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 23.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 24.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 25.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 27.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 28.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 29.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 30.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 31.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 32.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 33.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 34.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 35.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 36.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 37.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 38.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 39.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 40.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 41.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 42.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 43.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 44.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 45.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 46.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 47.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 48.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 49.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 50.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 51.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 52.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 53.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 54.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 55.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 56.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 57.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 58.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 59.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 60.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 61.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 62.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 63.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 64.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 65.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 66.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 67.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 68.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 69.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 70.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 71.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 72.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 73.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 74.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 75.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 76.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 77.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 78.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 79.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 80.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 81.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 82.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 83.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 84.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 85.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 86.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 87.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 88.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 89.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 90.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 91.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 92.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 93.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 94.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 95.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 96.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 97.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 98.0 100.0)) )
                    (+ SP (* (- EP SP) (/ 99.0 100.0)) )
                    EP
              )
 )
 
 (SetQ dist (Vl-Sort-I params
                       (Function
                        (Lambda (a b)
                         (>= (Distance POINT (VLAX-Curve-GetPointAtParam CURVE a))
                             (Distance POINT (VLAX-Curve-GetPointAtParam CURVE b))
                         )
                        )
                       )
            )
 )
 
 (If (> (- EP SP) TOL)
  (FurthestParameter
   (If (< (Nth (Car dist) params) (Nth (Cadr dist) params))
    (Nth (Car dist) params)
    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth (Car dist) params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr dist) params)) 1e-8))
     (Nth (Cadr dist) params)
     (Nth (Caddr dist) params)
    )
   )
   (If (< (Nth (Car dist) params) (Nth (Cadr dist) params))
    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth (Car dist) params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr dist) params)) 1e-8))
     (Nth (Cadr dist) params)
     (Nth (Caddr dist) params)
    )
    (Nth (Car dist) params)
   )
   TOL
  )
  (Nth (Car dist) params)
 )
)
 
(VLAX-Curve-GetPointAtParam CURVE (FurthestParameter (VLAX-Curve-GetStartParam CURVE) (VLAX-Curve-GetEndParam CURVE) TOL) )
)

(defun vlax-curve-getfurthestpointfrom ( ent pt / elst etype )
       (setq elst (entget ent))
       (cond
           (   (= "XLINE" (setq etype (cdr (assoc 0 elst))))
               nil
           )
           (   (= "RAY" (setq etype (cdr (assoc 0 elst))))
               nil
           )
           (   (= "LINE" etype)
               (if (< (distance pt (cdr (assoc 10 elst)))
                      (distance pt (cdr (assoc 11 elst)))
                   )
                   (cdr (assoc 11 elst))
                   (cdr (assoc 10 elst))
               )
           )
           (   (and
                   (= "CIRCLE" etype)
                   (equal pt (cdr (assoc 10 elst)) 1e-8)
               )
               (polar pt 0.0 (cdr (assoc 40 elst)))
           )
           (   (and
                   (= "ELLIPSE" etype)
                   (equal pt (cdr (assoc 10 elst)) 1e-8)
               )
               (ZF-GetFurthestPointFrom ent (mapcar '+ pt (list 1e-2 1e-2 0.0)) 1e-8)
           )
           (   (and
                   (= "LWPOLYLINE" etype)
                   (vl-every '(lambda ( x ) (or (/= 42 (car x)) (zerop (cdr x)))) elst)
               )
               (car
                   (vl-sort (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= 10 (car x))) elst))
                       (function
                           (lambda ( a b ) (> (distance pt a) (distance pt b)))
                       )
                   )
               )
           )
           (   t
               (ZF-GetFurthestPointFrom ent pt 1e-8)
           )
       )
)

M.R.
 :cry:
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 13, 2012, 03:31:25 PM
I don't know in previous ACAD session it didn't work, and now it works...

Strange, Friday 13th symptom...
 :-o

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: zoltan on July 13, 2012, 06:09:55 PM
Code - Auto/Visual Lisp: [Select]
  1. (Defun ZF-Curve-GetFurthestPointFrom ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag)
  2.  (SetQ samples 100
  3.        tolerance 1e-10
  4.  )
  5.  
  6.  (Defun IsFurther ( A B P )
  7.   (> (Distance A P) (Distance B P))
  8.  )
  9.  
  10.  (Defun FurthestParameter (SP EP / seg params furthest )
  11.   (SetQ params (List SP))
  12.   (SetQ seg 0.0)
  13.  
  14.   (Repeat (1- samples)
  15.    (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
  16.   )
  17.  
  18.   (SetQ furthest (Car
  19.                   (Vl-Sort-I
  20.                    params
  21.                    (Function
  22.                     (Lambda (a b)
  23.                      (IsFurther
  24.                       (VLAX-Curve-GetPointAtParam CURVE a)
  25.                       (VLAX-Curve-GetPointAtParam CURVE b)
  26.                       POINT
  27.                      )
  28.                     )
  29.                    )
  30.                   )
  31.                  )
  32.   )
  33.  
  34.   (If (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance)
  35.    (FurthestParameter
  36.     (If (= furthest 0)
  37.      (Nth furthest params)
  38.      (Nth (1- furthest) params)
  39.      )
  40.     (If (= furthest (1- (Length params)))
  41.      (Nth furthest params)
  42.      (Nth (1+ furthest) params)
  43.      )
  44.     )
  45.    (Nth furthest params)
  46.   )
  47.  )
  48.  
  49.  (SetQ elst (entget CURVE))
  50.  
  51.  (Cond
  52.   ((= "XLINE" (SetQ etype (Cdr (Assoc 0 elst))))
  53.    nil
  54.   )
  55.   ((= "RAY" etype)
  56.    nil
  57.   )
  58.   ((= "LINE" etype)
  59.    (If (IsFurther (Cdr (Assoc 10 elst)) (Cdr (Assoc 11 elst)) POINT)
  60.     (Cdr (Assoc 10 elst))
  61.     (Cdr (Assoc 11 elst))
  62.    )
  63.   )
  64.   ((= "CIRCLE" etype)
  65.    (If (Equal POINT (SetQ cent (Cdr (Assoc 10 elst))))
  66.     nil
  67.     (ProgN
  68.      (SetQ rad (Cdr (Assoc 40 elst)) )
  69.      (SetQ vec (List (- (Car cent) (Car POINT)) (- (Cadr cent) (Cadr POINT)) (- (Caddr cent) (Caddr POINT))))
  70.      (SetQ mag (Sqrt (+ (* (Car vec) (Car vec)) (* (Cadr vec) (Cadr vec)) (* (Caddr vec) (Caddr vec)))))
  71.      (List (+ (Car cent) (* (/ (Car vec) mag) rad)) (+ (Cadr cent) (* (/ (Cadr vec) mag) rad)) (+ (Caddr cent) (* (/ (Caddr vec) mag) rad)))
  72.     )
  73.    )
  74.   )
  75.   ((And
  76.     (= "LWPOLYLINE" etype)
  77.     (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  78.    )
  79.    (Car
  80.     (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  81.              (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  82.     )
  83.    )
  84.   )
  85.   (T
  86.     CURVE
  87.     (FurthestParameter
  88.      (VLAX-Curve-GetStartParam CURVE)
  89.      (VLAX-Curve-GetEndParam CURVE)
  90.     )
  91.    )
  92.   )
  93.  )
  94. )
  95.  

I still need to come up with a way to reliably determine the number of samples and tolerance from the length of the curve or something.

 I also added a case for circles, because they have a closed form solution that does not require approximation.  I'm afraid, however, that it will not work correctly if the input point is not planar to the circle.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: Lee Mac on July 13, 2012, 07:24:50 PM
Some alternatives for the Circle solution:

Code - Auto/Visual Lisp: [Select]
  1. (   (= "CIRCLE" etype)
  2.     (if (not (equal point (setq cen (cdr (assoc 10 elst)))))
  3.         (progn
  4.             (setq d (/ (cdr (assoc 40 elst)) (distance point cen)))
  5.             (mapcar (function (lambda ( a b ) (+ a (* b d)))) cen (mapcar '- cen point))
  6.         )
  7.     )
  8. )

Code - Auto/Visual Lisp: [Select]
  1. (   (= "CIRCLE" etype)
  2.     (if (not (equal point (setq cen (cdr (assoc 10 elst)))))
  3.         (polar cen (angle point cen) (cdr (assoc 40 elst)))
  4.     )
  5. )
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 14, 2012, 01:16:56 AM
Based on Zoltan's code, here is mine version - my recursion between 2 furthest points... And look for CIRCLE and ELLIPSE solutions (main routine should calc. result) - only exception is when point is center, then I changed little center point, just slightly translation, so that main routine can calc. result...

Code - Auto/Visual Lisp: [Select]
  1. (Defun MR-Curve-GetFurthestPointFrom ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag)
  2. (SetQ samples 200
  3.      tolerance 1e-8
  4. )
  5.  
  6. (Defun FurthestParameter (SP EP / seg params par furthest )
  7. (SetQ params (List SP))
  8. (SetQ seg 0.0)
  9.  
  10. (Defun IsFurther ( A B P )
  11.  (>= (Distance A P) (Distance B P))
  12. )
  13.  
  14. (Repeat (1- samples)
  15.  (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
  16. )
  17.  
  18. (SetQ furthest (Car (SetQ par
  19.                 (Vl-Sort-I
  20.                  params
  21.                  (Function
  22.                   (Lambda (a b)
  23.                    (IsFurther
  24.                     (VLAX-Curve-GetPointAtParam CURVE a)
  25.                     (VLAX-Curve-GetPointAtParam CURVE b)
  26.                     POINT
  27.                    )
  28.                   )
  29.                  )
  30.                 ))
  31.                )
  32. )
  33.  
  34. (If (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance)
  35.  (FurthestParameter
  36.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  37.    (Nth furthest params)
  38.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  39.     (Nth (Cadr par) params)
  40.     (Nth (Caddr par) params)
  41.    )
  42.   )
  43.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  44.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  45.     (Nth (Cadr par) params)
  46.     (Nth (Caddr par) params)
  47.    )
  48.    (Nth furthest params)
  49.   )
  50.  )
  51.  (Nth furthest params)
  52. )
  53. )
  54.  
  55.   CURVE
  56.   (FurthestParameter
  57.   )
  58.  )
  59.  
  60. )
  61.  
  62. (defun vlax-curve-getfurthestpointfrom ( CURVE POINT / elst etype 2dtype lstn )
  63.  
  64. (Defun IsFurther ( A B P )
  65.  (>= (Distance A P) (Distance B P))
  66. )
  67.  
  68. (defun _polyvertices ( lst )
  69.   (_vertices2 (entnext (cdr (assoc -1 lst))))
  70. )
  71.  
  72. (defun _vertices2 ( e )
  73.   (if (eq "VERTEX" (cdr (assoc 0 (entget e))))
  74.     (progn
  75.       (setq lstn (cons (assoc 10 (entget e)) lstn))
  76.       (setq lstn (cons (assoc 42 (entget e)) lstn))
  77.       (_vertices2 (entnext e))
  78.     )
  79.   )
  80.   (reverse lstn)
  81. )
  82.  
  83. (defun member-fuzz (expr lst fuzz)
  84.   (while (and lst (not (equal (car lst) expr fuzz)))
  85.     (setq lst (cdr lst))
  86.   )
  87.   lst
  88. )
  89.  
  90. (defun _plcents ( ent / enpar n p1 p2 bulge rad cen cenlst )
  91.   (setq enpar (vlax-curve-getendparam ent))
  92.   (setq n -1)
  93.   (repeat (fix enpar)
  94.     (setq n (1+ n))
  95.     (setq p2 (vlax-curve-getpointatparam ent (float (1+ n))))
  96.     (setq bulge (vla-getbulge (vlax-ename->vla-object ent) (float n)))
  97.     (if (/= bulge 0.0)
  98.       (progn
  99.         (setq rad (/ (distance p1 p2) (* 2 (sin (* 2 (atan bulge))))))
  100.         (setq cen (polar p1 (+ (angle p1 p2) (- (/ pi 2.0) (* 2 (atan bulge)))) rad))
  101.         (setq cenlst (cons cen cenlst))
  102.       )
  103.     )
  104.   )
  105.   (reverse cenlst)
  106. )
  107.  
  108. (SetQ elst (entget CURVE))
  109. (SetQ etype (Cdr (Assoc 0 elst)))
  110.  
  111. ((= "XLINE" etype)
  112.  nil
  113. )
  114. ((= "RAY" etype)
  115.  nil
  116. )
  117. ((= "LINE" etype)
  118.  (If (IsFurther (Cdr (Assoc 10 elst)) (Cdr (Assoc 11 elst)) POINT)
  119.   (Cdr (Assoc 10 elst))
  120.   (Cdr (Assoc 11 elst))
  121.  )
  122. )
  123. ((And
  124.   (= "ARC" etype)
  125.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  126.  )
  127.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  128. )
  129. ((And
  130.   (= "CIRCLE" etype)
  131.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  132.  )
  133.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  134. )
  135. ((And
  136.   (= "ELLIPSE" etype)
  137.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  138.  )
  139.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  140. )
  141. ((And
  142.   (= "LWPOLYLINE" etype)
  143.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  144.  )
  145.  (Car
  146.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  147.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  148.   )
  149.  )
  150. )
  151. ((And
  152.   (= "LWPOLYLINE" etype)
  153.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  154.   (member-fuzz POINT (_plcents CURVE) 1e-8)
  155.  )
  156.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  157. )
  158. ((And
  159.   (= "POLYLINE" etype)
  160.   (SetQ 2dtype (Cdr (Assoc 100 (Reverse elst))))
  161.   (SetQ elst (_polyvertices elst))
  162.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  163.   (If (= 2dtype "AcDb2dPolyline") (member-fuzz POINT (_plcents CURVE) 1e-8))
  164.  )
  165.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  166. )
  167. ((And
  168.   (= "POLYLINE" etype)
  169.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  170.  )
  171.  (MR-Curve-GetFurthestPointFrom CURVE POINT)
  172. )
  173. ((And
  174.   (= "POLYLINE" etype)
  175.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  176.  )
  177.  (Car
  178.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  179.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  180.   )
  181.  )
  182. )
  183. (T
  184.  (MR-Curve-GetFurthestPointFrom CURVE POINT)
  185. )
  186. )
  187. )
  188.  

P.S. I like your way of dealing with tolerances and enlarging list of parameters with segmentation... BTW I took 200 samples, tolerance 1e-8...

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 15, 2012, 05:41:12 AM
The more time passes, I figure that both logics and mine and Zoltans have their benefits... So I combined them into one single function (vlax-curve-getfurthestpointfrom) - for now I couldn't think of better name as it describes what should real missing VLisp function do...

Code - Auto/Visual Lisp: [Select]
  1. (Defun ZF-Curve-GetFurthestPointFrom ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag)
  2. (SetQ samples 200
  3.      tolerance 1e-8
  4. )
  5.  
  6. (Defun FurthestParameter (SP EP / seg params par furthest )
  7. (SetQ params (List SP))
  8. (SetQ seg 0.0)
  9.  
  10. (Defun IsFurther ( A B P )
  11.  (>= (Distance A P) (Distance B P))
  12. )
  13.  
  14. (Repeat (1- samples)
  15.  (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
  16. )
  17.  
  18. (SetQ furthest (Car (SetQ par
  19.                 (Vl-Sort-I
  20.                  params
  21.                  (Function
  22.                   (Lambda (a b)
  23.                    (IsFurther
  24.                     (VLAX-Curve-GetPointAtParam CURVE a)
  25.                     (VLAX-Curve-GetPointAtParam CURVE b)
  26.                     POINT
  27.                    )
  28.                   )
  29.                  )
  30.                 ))
  31.                )
  32. )
  33.  
  34. (If (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance)
  35.  (FurthestParameter
  36.   (If (< (Nth (Cadr par) params) (Nth (Caddr par) params))
  37.    (Nth (Cadr par) params)
  38.    (Nth (Caddr par) params)
  39.   )
  40.   (If (< (Nth (Cadr par) params) (Nth (Caddr par) params))
  41.    (Nth (Caddr par) params)
  42.    (Nth (Cadr par) params)
  43.   )
  44.  )
  45.  (Nth furthest params)
  46. )
  47. )
  48.  
  49.   CURVE
  50.   (FurthestParameter
  51.   )
  52.  )
  53.  
  54. )
  55.  
  56.  
  57. (Defun MR-Curve-GetFurthestPointFrom ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag)
  58. (SetQ samples 200
  59.      tolerance 1e-8
  60. )
  61.  
  62. (Defun FurthestParameter (SP EP / seg params par furthest )
  63. (SetQ params (List SP))
  64. (SetQ seg 0.0)
  65.  
  66. (Defun IsFurther ( A B P )
  67.  (>= (Distance A P) (Distance B P))
  68. )
  69.  
  70. (Repeat (1- samples)
  71.  (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
  72. )
  73.  
  74. (SetQ furthest (Car (SetQ par
  75.                 (Vl-Sort-I
  76.                  params
  77.                  (Function
  78.                   (Lambda (a b)
  79.                    (IsFurther
  80.                     (VLAX-Curve-GetPointAtParam CURVE a)
  81.                     (VLAX-Curve-GetPointAtParam CURVE b)
  82.                     POINT
  83.                    )
  84.                   )
  85.                  )
  86.                 ))
  87.                )
  88. )
  89.  
  90. (If (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance)
  91.  (FurthestParameter
  92.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  93.    (Nth furthest params)
  94.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  95.     (Nth (Cadr par) params)
  96.     (Nth (Caddr par) params)
  97.    )
  98.   )
  99.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  100.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  101.     (Nth (Cadr par) params)
  102.     (Nth (Caddr par) params)
  103.    )
  104.    (Nth furthest params)
  105.   )
  106.  )
  107.  (Nth furthest params)
  108. )
  109. )
  110.  
  111.   CURVE
  112.   (FurthestParameter
  113.   )
  114.  )
  115.  
  116. )
  117.  
  118. (defun vlax-curve-getfurthestpointfrom ( CURVE POINT / elst etype 2dtype lstn )
  119.  
  120. (Defun IsFurther ( A B P )
  121.  (>= (Distance A P) (Distance B P))
  122. )
  123.  
  124. (defun _polyvertices ( lst )
  125.   (_vertices2 (entnext (cdr (assoc -1 lst))))
  126. )
  127.  
  128. (defun _vertices2 ( e )
  129.   (if (eq "VERTEX" (cdr (assoc 0 (entget e))))
  130.     (progn
  131.       (setq lstn (cons (assoc 10 (entget e)) lstn))
  132.       (setq lstn (cons (assoc 42 (entget e)) lstn))
  133.       (_vertices2 (entnext e))
  134.     )
  135.   )
  136.   (reverse lstn)
  137. )
  138.  
  139. (defun member-fuzz (expr lst fuzz)
  140.   (while (and lst (not (equal (car lst) expr fuzz)))
  141.     (setq lst (cdr lst))
  142.   )
  143.   lst
  144. )
  145.  
  146. (defun _plcents ( ent / enpar n p1 p2 bulge rad cen cenlst )
  147.   (setq enpar (vlax-curve-getendparam ent))
  148.   (setq n -1)
  149.   (repeat (fix enpar)
  150.     (setq n (1+ n))
  151.     (setq p2 (vlax-curve-getpointatparam ent (float (1+ n))))
  152.     (setq bulge (vla-getbulge (vlax-ename->vla-object ent) (float n)))
  153.     (if (/= bulge 0.0)
  154.       (progn
  155.         (setq rad (/ (distance p1 p2) (* 2 (sin (* 2 (atan bulge))))))
  156.         (setq cen (polar p1 (+ (angle p1 p2) (- (/ pi 2.0) (* 2 (atan bulge)))) rad))
  157.         (setq cenlst (cons cen cenlst))
  158.       )
  159.     )
  160.   )
  161.   (reverse cenlst)
  162. )
  163.  
  164. (SetQ elst (entget CURVE))
  165. (SetQ etype (Cdr (Assoc 0 elst)))
  166.  
  167. ((= "XLINE" etype)
  168.  nil
  169. )
  170. ((= "RAY" etype)
  171.  nil
  172. )
  173. ((= "LINE" etype)
  174.  (If (IsFurther (Cdr (Assoc 10 elst)) (Cdr (Assoc 11 elst)) POINT)
  175.   (Cdr (Assoc 10 elst))
  176.   (Cdr (Assoc 11 elst))
  177.  )
  178. )
  179. ((And
  180.   (= "ARC" etype)
  181.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  182.  )
  183.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  184. )
  185. ((And
  186.   (= "CIRCLE" etype)
  187.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  188.  )
  189.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  190. )
  191. ((And
  192.   (= "ELLIPSE" etype)
  193.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  194.  )
  195.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  196. )
  197. ((And
  198.   (= "LWPOLYLINE" etype)
  199.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  200.  )
  201.  (Car
  202.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  203.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  204.   )
  205.  )
  206. )
  207. ((And
  208.   (= "LWPOLYLINE" etype)
  209.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  210.   (member-fuzz POINT (_plcents CURVE) 1e-8)
  211.  )
  212.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  213. )
  214. ((And
  215.   (= "POLYLINE" etype)
  216.   (SetQ 2dtype (Cdr (Assoc 100 (Reverse elst))))
  217.   (SetQ elst (_polyvertices elst))
  218.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  219.   (If (= 2dtype "AcDb2dPolyline") (member-fuzz POINT (_plcents CURVE) 1e-8))
  220.  )
  221.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  222. )
  223. ((And
  224.   (= "POLYLINE" etype)
  225.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  226.  )
  227.  (MR-Curve-GetFurthestPointFrom CURVE POINT)
  228. )
  229. ((And
  230.   (= "POLYLINE" etype)
  231.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  232.  )
  233.  (Car
  234.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  235.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  236.   )
  237.  )
  238. )
  239. ((= "SPLINE" etype)
  240.  (ZF-Curve-GetFurthestPointFrom CURVE POINT)
  241. )
  242. (T
  243.  (MR-Curve-GetFurthestPointFrom CURVE POINT)
  244. )
  245. )
  246. )
  247.  

Regards, once again M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 15, 2012, 10:00:46 AM
Code updated to cover all possible combinations of CURVE objects and POINT argument...

And not to forget - giving accreditation to Gile for his subfunction (member-fuzz) as it was used in above posted code and it was taken from Giles website... Link is list manipulations - list subfunctions :

Listes (http://gile.pagesperso-orange.fr/LISP/Listes.lsp)

M.R.

Also, many thanks to Lee Mac for participation and his suggestions in this thread... My final code would never been created without his useful help... So all kudos to Lee too...

Marko
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 15, 2012, 05:22:43 PM
No use... Still my subfunction is more reliable in finding approx correct solution...

So my final conclusion is updated code :
http://www.theswamp.org/index.php?topic=42246.msg474040#msg474040

or attached *.lsp

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 16, 2012, 10:45:40 AM
Code corrected once more... No need to convert old heavy 2d polyline to lwpolyline...

Both variants are acceptable, though I suggest smaller one - MR variant...

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: chlh_jd on July 24, 2012, 02:33:06 AM
For Circle , this way ?
Code: [Select]
((= "CIRCLE" etype)
  ((lambda (p c r)
     (polar p (angle p c) (* 2. r))
   )
    (vlax-curve-getclosestpointto curve point)
    (cdr (Assoc 10 elst))
    (cdr (assoc 40 elst))
  )
)
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 21, 2012, 08:42:04 AM
For Circle , this way ?
Code: [Select]
((= "CIRCLE" etype)
  ((lambda (p c r)
     (polar p (angle p c) (* 2. r))
   )
    (vlax-curve-getclosestpointto curve point)
    (cdr (Assoc 10 elst))
    (cdr (assoc 40 elst))
  )
)

Yes, chlh_jd, that would sure solve the case, but I wonder how no one didn't saw that in my code - Zoltan's also is written (repeat (1- samples) ...), and should be (repeat samples ...)... So here is my slightly modifications :

Code - Auto/Visual Lisp: [Select]
  1. (Defun MR-Curve-GetFurthestPointFrom ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag)
  2. (SetQ samples 200
  3.      tolerance 1e-14
  4. )
  5.  
  6. (Defun FurthestParameter (SP EP / seg params par furthest f ff )
  7. (SetQ params (List SP))
  8. (SetQ seg 0.0)
  9.  
  10. (Defun IsFurther ( A B P )
  11.  (>= (Distance A P) (Distance B P))
  12. )
  13.  
  14. (Repeat samples
  15.  (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
  16. )
  17.  
  18. (SetQ furthest (Car (SetQ par
  19.                 (Vl-Sort-I
  20.                  params
  21.                  (Function
  22.                   (Lambda (a b)
  23.                    (IsFurther
  24.                     (VLAX-Curve-GetPointAtParam CURVE a)
  25.                     (VLAX-Curve-GetPointAtParam CURVE b)
  26.                     POINT
  27.                    )
  28.                   )
  29.                  )
  30.                 ))
  31.                )
  32. )
  33.  
  34. (setq f (nth furthest params))
  35.  
  36. (If (and (/= f ff) (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance))
  37.  (setq ff (FurthestParameter
  38.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  39.    (Nth furthest params)
  40.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  41.     (Nth (Cadr par) params)
  42.     (Nth (Caddr par) params)
  43.    )
  44.   )
  45.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  46.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  47.     (Nth (Cadr par) params)
  48.     (Nth (Caddr par) params)
  49.    )
  50.    (Nth furthest params)
  51.   )
  52.  ))
  53.  (setq ff (Nth furthest params))
  54. )
  55.  
  56. ff
  57. )
  58.  
  59.   CURVE
  60.   (FurthestParameter
  61.   )
  62.  )
  63.  
  64. )
  65.  
  66. (defun vlax-curve-getfurthestpointfrom ( CURVE POINT / elst etype 2dtype lstn )
  67.  
  68. (Defun IsFurther ( A B P )
  69.  (>= (Distance A P) (Distance B P))
  70. )
  71.  
  72. (defun _polyvertices ( lst )
  73.   (_vertices2 (entnext (cdr (assoc -1 lst))))
  74. )
  75.  
  76. (defun _vertices2 ( e )
  77.   (if (eq "VERTEX" (cdr (assoc 0 (entget e))))
  78.     (progn
  79.       (setq lstn (cons (assoc 10 (entget e)) lstn))
  80.       (setq lstn (cons (assoc 42 (entget e)) lstn))
  81.       (_vertices2 (entnext e))
  82.     )
  83.   )
  84.   (reverse lstn)
  85. )
  86.  
  87. (defun member-fuzz (expr lst fuzz)
  88.   (while (and lst (not (equal (car lst) expr fuzz)))
  89.     (setq lst (cdr lst))
  90.   )
  91.   lst
  92. )
  93.  
  94. (defun _plcents ( ent / enpar n p1 p2 bulge rad cen cenlst )
  95.   (setq enpar (vlax-curve-getendparam ent))
  96.   (setq n -1)
  97.   (repeat (fix enpar)
  98.     (setq n (1+ n))
  99.     (setq p2 (vlax-curve-getpointatparam ent (float (1+ n))))
  100.     (setq bulge (vla-getbulge (vlax-ename->vla-object ent) (float n)))
  101.     (if (/= bulge 0.0)
  102.       (progn
  103.         (setq rad (/ (distance p1 p2) (* 2 (sin (* 2 (atan bulge))))))
  104.         (setq cen (polar p1 (+ (angle p1 p2) (- (/ pi 2.0) (* 2 (atan bulge)))) rad))
  105.         (setq cenlst (cons cen cenlst))
  106.       )
  107.     )
  108.   )
  109.   (reverse cenlst)
  110. )
  111.  
  112. (SetQ elst (entget CURVE))
  113. (SetQ etype (Cdr (Assoc 0 elst)))
  114.  
  115. ((= "XLINE" etype)
  116.  nil
  117. )
  118. ((= "RAY" etype)
  119.  nil
  120. )
  121. ((= "LINE" etype)
  122.  (If (IsFurther (Cdr (Assoc 10 elst)) (Cdr (Assoc 11 elst)) POINT)
  123.   (Cdr (Assoc 10 elst))
  124.   (Cdr (Assoc 11 elst))
  125.  )
  126. )
  127. ((And
  128.   (= "ARC" etype)
  129.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  130.  )
  131.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  132. )
  133. ((And
  134.   (= "CIRCLE" etype)
  135.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  136.  )
  137.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  138. )
  139. ((And
  140.   (= "ELLIPSE" etype)
  141.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  142.  )
  143.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  144. )
  145. ((And
  146.   (= "LWPOLYLINE" etype)
  147.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  148.  )
  149.  (Car
  150.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  151.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  152.   )
  153.  )
  154. )
  155. ((And
  156.   (= "LWPOLYLINE" etype)
  157.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  158.   (member-fuzz POINT (_plcents CURVE) 1e-8)
  159.  )
  160.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  161. )
  162. ((And
  163.   (= "POLYLINE" etype)
  164.   (SetQ 2dtype (Cdr (Assoc 100 (Reverse elst))))
  165.   (SetQ elst (_polyvertices elst))
  166.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  167.   (If (= 2dtype "AcDb2dPolyline") (member-fuzz POINT (_plcents CURVE) 1e-8))
  168.  )
  169.  (MR-Curve-GetFurthestPointFrom CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  170. )
  171. ((And
  172.   (= "POLYLINE" etype)
  173.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  174.  )
  175.  (MR-Curve-GetFurthestPointFrom CURVE POINT)
  176. )
  177. ((And
  178.   (= "POLYLINE" etype)
  179.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  180.  )
  181.  (Car
  182.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  183.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  184.   )
  185.  )
  186. )
  187. (T
  188.  (MR-Curve-GetFurthestPointFrom CURVE POINT)
  189. )
  190. )
  191. )
  192.  

And I also made revision for usage without spline objects - little slower, but exact results (too bad you can't draw circle that tang snap spline)... Autodesk should seriously revise spline osnaps - you can't get int snap when self-crossed and you can't use tan snap with circles like in this mine case...
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 21, 2012, 10:08:44 AM
And here is my most recent revision with circle subfunction and with normal subfunction combined into single (vlax-curve-getfurthestpointfrom)... Little slower, but till now probably the most exact results - only thing that remains is spline, but here also result is near expected but not exact...

Code - Auto/Visual Lisp: [Select]
  1. (Defun MR-Curve-GetFurthestPointFromCircle ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag pt )
  2. (SetQ samples 200
  3.      tolerance 1e-14
  4. )
  5.  
  6. (Defun FurthestParameter (SP EP / seg params par furthest f ff )
  7. (SetQ params (List SP))
  8. (SetQ seg 0.0)
  9.  
  10. (Defun IsFurther ( A B P )
  11.  (>= (Distance A P) (Distance B P))
  12. )
  13.  
  14. (Repeat samples
  15.  (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
  16. )
  17.  
  18. (SetQ furthest (Car (SetQ par
  19.                 (Vl-Sort-I
  20.                  params
  21.                  (Function
  22.                   (Lambda (a b)
  23.                    (IsFurther
  24.                     (VLAX-Curve-GetPointAtParam CURVE a)
  25.                     (VLAX-Curve-GetPointAtParam CURVE b)
  26.                     POINT
  27.                    )
  28.                   )
  29.                  )
  30.                 ))
  31.                )
  32. )
  33.  
  34. (setq f (nth furthest params))
  35.  
  36. (If (and (/= f ff) (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance))
  37.  (setq ff (FurthestParameter
  38.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  39.    (Nth furthest params)
  40.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  41.     (Nth (Cadr par) params)
  42.     (Nth (Caddr par) params)
  43.    )
  44.   )
  45.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  46.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  47.     (Nth (Cadr par) params)
  48.     (Nth (Caddr par) params)
  49.    )
  50.    (Nth furthest params)
  51.   )
  52.  ))
  53.  (setq ff (Nth furthest params))
  54. )
  55.  
  56. ff
  57. )
  58.  
  59. (Setq pt
  60.   CURVE
  61.   (FurthestParameter
  62.   )
  63.  )
  64. )
  65. (setq osm (getvar 'osmode))
  66. (setvar 'osmode 257)
  67. (vl-cmdf "_.CIRCLE" point pt)
  68. (setq pt (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object (entlast)) acExtendNone))
  69. (setvar 'osmode osm)
  70. pt
  71. )
  72.  
  73. (Defun MR-Curve-GetFurthestPointFrom ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag)
  74. (SetQ samples 200
  75.      tolerance 1e-14
  76. )
  77.  
  78. (Defun FurthestParameter (SP EP / seg params par furthest f ff )
  79. (SetQ params (List SP))
  80. (SetQ seg 0.0)
  81.  
  82. (Defun IsFurther ( A B P )
  83.  (>= (Distance A P) (Distance B P))
  84. )
  85.  
  86. (Repeat samples
  87.  (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
  88. )
  89.  
  90. (SetQ furthest (Car (SetQ par
  91.                 (Vl-Sort-I
  92.                  params
  93.                  (Function
  94.                   (Lambda (a b)
  95.                    (IsFurther
  96.                     (VLAX-Curve-GetPointAtParam CURVE a)
  97.                     (VLAX-Curve-GetPointAtParam CURVE b)
  98.                     POINT
  99.                    )
  100.                   )
  101.                  )
  102.                 ))
  103.                )
  104. )
  105.  
  106. (setq f (nth furthest params))
  107.  
  108. (If (and (/= f ff) (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance))
  109.  (setq ff (FurthestParameter
  110.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  111.    (Nth furthest params)
  112.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  113.     (Nth (Cadr par) params)
  114.     (Nth (Caddr par) params)
  115.    )
  116.   )
  117.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  118.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  119.     (Nth (Cadr par) params)
  120.     (Nth (Caddr par) params)
  121.    )
  122.    (Nth furthest params)
  123.   )
  124.  ))
  125.  (setq ff (Nth furthest params))
  126. )
  127.  
  128. ff
  129. )
  130.  
  131.   CURVE
  132.   (FurthestParameter
  133.   )
  134.  )
  135.  
  136. )
  137.  
  138. (defun vlax-curve-getfurthestpointfrom ( CURVE POINT / elst etype 2dtype lstn )
  139.  
  140. (Defun IsFurther ( A B P )
  141.  (>= (Distance A P) (Distance B P))
  142. )
  143.  
  144. (defun _polyvertices ( lst )
  145.   (_vertices2 (entnext (cdr (assoc -1 lst))))
  146. )
  147.  
  148. (defun _vertices2 ( e )
  149.   (if (eq "VERTEX" (cdr (assoc 0 (entget e))))
  150.     (progn
  151.       (setq lstn (cons (assoc 10 (entget e)) lstn))
  152.       (setq lstn (cons (assoc 42 (entget e)) lstn))
  153.       (_vertices2 (entnext e))
  154.     )
  155.   )
  156.   (reverse lstn)
  157. )
  158.  
  159. (defun member-fuzz (expr lst fuzz)
  160.   (while (and lst (not (equal (car lst) expr fuzz)))
  161.     (setq lst (cdr lst))
  162.   )
  163.   lst
  164. )
  165.  
  166. (defun _plcents ( ent / enpar n p1 p2 bulge rad cen cenlst )
  167.   (setq enpar (vlax-curve-getendparam ent))
  168.   (setq n -1)
  169.   (repeat (fix enpar)
  170.     (setq n (1+ n))
  171.     (setq p2 (vlax-curve-getpointatparam ent (float (1+ n))))
  172.     (setq bulge (vla-getbulge (vlax-ename->vla-object ent) (float n)))
  173.     (if (/= bulge 0.0)
  174.       (progn
  175.         (setq rad (/ (distance p1 p2) (* 2 (sin (* 2 (atan bulge))))))
  176.         (setq cen (polar p1 (+ (angle p1 p2) (- (/ pi 2.0) (* 2 (atan bulge)))) rad))
  177.         (setq cenlst (cons cen cenlst))
  178.       )
  179.     )
  180.   )
  181.   (reverse cenlst)
  182. )
  183.  
  184. (SetQ elst (entget CURVE))
  185. (SetQ etype (Cdr (Assoc 0 elst)))
  186.  
  187. ((= "XLINE" etype)
  188.  nil
  189. )
  190. ((= "RAY" etype)
  191.  nil
  192. )
  193. ((= "LINE" etype)
  194.  (If (IsFurther (Cdr (Assoc 10 elst)) (Cdr (Assoc 11 elst)) POINT)
  195.   (Cdr (Assoc 10 elst))
  196.   (Cdr (Assoc 11 elst))
  197.  )
  198. )
  199. ((And
  200.   (= "ARC" etype)
  201.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  202.  )
  203.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  204. )
  205. ((And
  206.   (= "CIRCLE" etype)
  207.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  208.  )
  209.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  210. )
  211. ((And
  212.   (= "ELLIPSE" etype)
  213.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  214.  )
  215.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  216. )
  217. ((And
  218.   (= "LWPOLYLINE" etype)
  219.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  220.  )
  221.  (Car
  222.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  223.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  224.   )
  225.  )
  226. )
  227. ((And
  228.   (= "LWPOLYLINE" etype)
  229.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  230.   (member-fuzz POINT (_plcents CURVE) 1e-8)
  231.  )
  232.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  233. )
  234. ((And
  235.   (= "POLYLINE" etype)
  236.   (SetQ 2dtype (Cdr (Assoc 100 (Reverse elst))))
  237.   (SetQ elst (_polyvertices elst))
  238.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  239.   (If (= 2dtype "AcDb2dPolyline") (member-fuzz POINT (_plcents CURVE) 1e-8))
  240.  )
  241.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  242. )
  243. ((And
  244.   (= "POLYLINE" etype)
  245.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  246.  )
  247.  (MR-Curve-GetFurthestPointFromCircle CURVE POINT)
  248. )
  249. ((And
  250.   (= "POLYLINE" etype)
  251.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  252.  )
  253.  (Car
  254.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  255.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  256.   )
  257.  )
  258. )
  259. (T
  260.  (MR-Curve-GetFurthestPointFrom CURVE POINT)
  261. )
  262. )
  263. )
  264.  

Regards, M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 22, 2012, 05:44:33 AM
My final revision, you should get exact result and for splines...

Code - Auto/Visual Lisp: [Select]
  1. (Defun MR-Curve-GetFurthestPointFromCircleSpline ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag pt )
  2. (SetQ samples 200
  3.      tolerance 1e-8
  4. )
  5.  
  6. (Defun FurthestParameter (SP EP / seg params par furthest f ff ci cidata rad r rr k )
  7. (SetQ params (List SP))
  8. (SetQ seg 0.0)
  9.  
  10. (Defun IsFurther ( A B P )
  11.  (>= (Distance A P) (Distance B P))
  12. )
  13.  
  14. (Repeat samples
  15.  (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
  16. )
  17.  
  18. (SetQ furthest (Car (SetQ par
  19.                 (Vl-Sort-I
  20.                  params
  21.                  (Function
  22.                   (Lambda (a b)
  23.                    (IsFurther
  24.                     (VLAX-Curve-GetPointAtParam CURVE a)
  25.                     (VLAX-Curve-GetPointAtParam CURVE b)
  26.                     POINT
  27.                    )
  28.                   )
  29.                  )
  30.                 ))
  31.                )
  32. )
  33.  
  34. (setq f (nth furthest params))
  35.  
  36. (If (and (/= f ff) (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance))
  37.  (setq ff (FurthestParameter
  38.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  39.    (Nth furthest params)
  40.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  41.     (Nth (Cadr par) params)
  42.     (Nth (Caddr par) params)
  43.    )
  44.   )
  45.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  46.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  47.     (Nth (Cadr par) params)
  48.     (Nth (Caddr par) params)
  49.    )
  50.    (Nth furthest params)
  51.   )
  52.  ))
  53.  (setq ff (Nth furthest params))
  54. )
  55.  
  56. ff
  57. )
  58.  
  59. (Setq pt
  60.   CURVE
  61.   (FurthestParameter
  62.   )
  63.  )
  64. )
  65.  
  66. (setq osm (getvar 'osmode))
  67. (setvar 'osmode 0)
  68. (vl-cmdf "_.CIRCLE" point pt)
  69. (setq rad (cdr (assoc 40 (setq cidata (entget (setq ci (entlast)))))))
  70. (setq pt (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object ci) acExtendNone))
  71. (setq k 0.0)
  72. (while (> (length pt) 3)
  73.  (setq r (+ rad (* 1e-8 (setq k (1+ k)))))
  74.  (entmod (subst (cons 40 r) (assoc 40 cidata) cidata))
  75.  (entupd ci)
  76.  (setq pt (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object ci) acExtendNone))
  77. )
  78. (setq k 0.0)
  79. (setq r (cdr (assoc 40 cidata)))
  80. (while (/= (length pt) 3)
  81.  (setq rr (- r (* 1e-10 (setq k (1+ k)))))
  82.  (entmod (subst (cons 40 rr) (assoc 40 cidata) cidata))
  83.  (entupd ci)
  84.  (setq pt (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object ci) acExtendNone))
  85. )
  86. (entdel ci)
  87. (setvar 'osmode osm)
  88. pt
  89. )
  90.  
  91. (Defun MR-Curve-GetFurthestPointFromCircle ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag pt )
  92. (SetQ samples 200
  93.      tolerance 1e-8
  94. )
  95.  
  96. (Defun FurthestParameter (SP EP / seg params par furthest f ff )
  97. (SetQ params (List SP))
  98. (SetQ seg 0.0)
  99.  
  100. (Defun IsFurther ( A B P )
  101.  (>= (Distance A P) (Distance B P))
  102. )
  103.  
  104. (Repeat samples
  105.  (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
  106. )
  107.  
  108. (SetQ furthest (Car (SetQ par
  109.                 (Vl-Sort-I
  110.                  params
  111.                  (Function
  112.                   (Lambda (a b)
  113.                    (IsFurther
  114.                     (VLAX-Curve-GetPointAtParam CURVE a)
  115.                     (VLAX-Curve-GetPointAtParam CURVE b)
  116.                     POINT
  117.                    )
  118.                   )
  119.                  )
  120.                 ))
  121.                )
  122. )
  123.  
  124. (setq f (nth furthest params))
  125.  
  126. (If (and (/= f ff) (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance))
  127.  (setq ff (FurthestParameter
  128.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  129.    (Nth furthest params)
  130.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  131.     (Nth (Cadr par) params)
  132.     (Nth (Caddr par) params)
  133.    )
  134.   )
  135.   (If (< (Nth furthest params) (Nth (Cadr par) params))
  136.    (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
  137.     (Nth (Cadr par) params)
  138.     (Nth (Caddr par) params)
  139.    )
  140.    (Nth furthest params)
  141.   )
  142.  ))
  143.  (setq ff (Nth furthest params))
  144. )
  145.  
  146. ff
  147. )
  148.  
  149. (Setq pt
  150.   CURVE
  151.   (FurthestParameter
  152.   )
  153.  )
  154. )
  155. (setq osm (getvar 'osmode))
  156. (setvar 'osmode 257)
  157. (vl-cmdf "_.CIRCLE" point pt)
  158. (setq pt (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object (entlast)) acExtendNone))
  159. (setvar 'osmode osm)
  160. pt
  161. )
  162.  
  163. (defun vlax-curve-getfurthestpointfrom ( CURVE POINT / elst etype 2dtype lstn )
  164.  
  165. (Defun IsFurther ( A B P )
  166.  (>= (Distance A P) (Distance B P))
  167. )
  168.  
  169. (defun _polyvertices ( lst )
  170.   (_vertices2 (entnext (cdr (assoc -1 lst))))
  171. )
  172.  
  173. (defun _vertices2 ( e )
  174.   (if (eq "VERTEX" (cdr (assoc 0 (entget e))))
  175.     (progn
  176.       (setq lstn (cons (assoc 10 (entget e)) lstn))
  177.       (setq lstn (cons (assoc 42 (entget e)) lstn))
  178.       (_vertices2 (entnext e))
  179.     )
  180.   )
  181.   (reverse lstn)
  182. )
  183.  
  184. (defun member-fuzz (expr lst fuzz)
  185.   (while (and lst (not (equal (car lst) expr fuzz)))
  186.     (setq lst (cdr lst))
  187.   )
  188.   lst
  189. )
  190.  
  191. (defun _plcents ( ent / enpar n p1 p2 bulge rad cen cenlst )
  192.   (setq enpar (vlax-curve-getendparam ent))
  193.   (setq n -1)
  194.   (repeat (fix enpar)
  195.     (setq n (1+ n))
  196.     (setq p2 (vlax-curve-getpointatparam ent (float (1+ n))))
  197.     (setq bulge (vla-getbulge (vlax-ename->vla-object ent) (float n)))
  198.     (if (/= bulge 0.0)
  199.       (progn
  200.         (setq rad (/ (distance p1 p2) (* 2 (sin (* 2 (atan bulge))))))
  201.         (setq cen (polar p1 (+ (angle p1 p2) (- (/ pi 2.0) (* 2 (atan bulge)))) rad))
  202.         (setq cenlst (cons cen cenlst))
  203.       )
  204.     )
  205.   )
  206.   (reverse cenlst)
  207. )
  208.  
  209. (SetQ elst (entget CURVE))
  210. (SetQ etype (Cdr (Assoc 0 elst)))
  211.  
  212. ((= "XLINE" etype)
  213.  nil
  214. )
  215. ((= "RAY" etype)
  216.  nil
  217. )
  218. ((= "LINE" etype)
  219.  (If (IsFurther (Cdr (Assoc 10 elst)) (Cdr (Assoc 11 elst)) POINT)
  220.   (Cdr (Assoc 10 elst))
  221.   (Cdr (Assoc 11 elst))
  222.  )
  223. )
  224. ((And
  225.   (= "ARC" etype)
  226.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  227.  )
  228.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  229. )
  230. ((And
  231.   (= "CIRCLE" etype)
  232.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  233.  )
  234.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  235. )
  236. ((And
  237.   (= "ELLIPSE" etype)
  238.   (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
  239.  )
  240.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  241. )
  242. ((And
  243.   (= "LWPOLYLINE" etype)
  244.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  245.  )
  246.  (Car
  247.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  248.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  249.   )
  250.  )
  251. )
  252. ((And
  253.   (= "LWPOLYLINE" etype)
  254.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  255.   (member-fuzz POINT (_plcents CURVE) 1e-8)
  256.  )
  257.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  258. )
  259. ((And
  260.   (= "POLYLINE" etype)
  261.   (SetQ 2dtype (Cdr (Assoc 100 (Reverse elst))))
  262.   (SetQ elst (_polyvertices elst))
  263.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  264.   (If (= 2dtype "AcDb2dPolyline") (member-fuzz POINT (_plcents CURVE) 1e-8))
  265.  )
  266.  (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
  267. )
  268. ((And
  269.   (= "POLYLINE" etype)
  270.   (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  271.  )
  272.  (MR-Curve-GetFurthestPointFromCircle CURVE POINT)
  273. )
  274. ((And
  275.   (= "POLYLINE" etype)
  276.   (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
  277.  )
  278.  (Car
  279.   (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
  280.            (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  281.   )
  282.  )
  283. )
  284. (T
  285.  (MR-Curve-GetFurthestPointFromCircleSpline CURVE POINT)
  286. )
  287. )
  288. )
  289.  

Regards, M.R.
 8-)
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 22, 2012, 07:11:11 AM
Important note :

- For 3d curve and point you should use :
http://www.theswamp.org/index.php?topic=42246.msg477514#msg477514
vlax-curve-getfurthestpointfrom-MR-rev.lsp
and result may have imperfections...

- For 2d curve and point that lie in WCS you should use :
http://www.theswamp.org/index.php?topic=42246.msg477659#msg477659
vlax-curve-getfurthestpointfrom-MR-revision-new.lsp
and result should be exactly correct...

Regards, M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 22, 2012, 01:53:56 PM
Although it not too much wise, combined into single function (vlax-curve-getfurthestpointfrom) for 2d geometry + 3d geometry.

M.R.

[EDIT: some minor modifications - till now there was 14 downloads - replaced *.lsp]
Title: Re: vlax-curve-getfurthestpointfrom
Post by: chlh_jd on August 22, 2012, 04:44:24 PM
For Circle , this way ?
Code: [Select]
((= "CIRCLE" etype)
  ((lambda (p c r)
     (polar p (angle p c) (* 2. r))
   )
    (vlax-curve-getclosestpointto curve point)
    (cdr (Assoc 10 elst))
    (cdr (assoc 40 elst))
  )
)

Yes, chlh_jd, that would sure solve the case, but I wonder how no one didn't saw that in my code - Zoltan's also is written (repeat (1- samples) ...), and should be (repeat samples ...)... So here is my slightly modifications :
Glad you can be in favor of .
However , If distance from point to curve is far enough away, such as must use light-years to desribe , this maximum distance lost meaning . I guess this is why autocad  put the 'getfurthestpointfrom' function  into .
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 23, 2012, 07:12:54 AM
Glad you can be in favor of .
However , If distance from point to curve is far enough away, such as must use light-years to desribe , this maximum distance lost meaning . I guess this is why autocad  put the 'getfurthestpointfrom' function  into .

I intended to create this function with some purpose in process of working with AutoCAD. I guess no one will draw entities so far away from checked point... As a matter a fact I already posted one possible usage of this function on www.cadtutor.net (you may google it) and it was with normal demands of CAD (Computer Aided Design)...

BTW. I changed my last attached *.lsp with some minor modifications (checked point may not be in plane, but if curve is, it finds furthest point from projected check point onto WCS using (vlax-curve-getfurthestpointfrom2d) subfunction... Also turned off echoing of (vl-cmdf "_.CIRCLE" point pt) while computing inside subfunctions...

Quote
And finally make sure checked point is transformed into WCS coordinates before calculations begin (trans point 1 0) - so you may start function no matter what UCS is currently active...

[EDIT : I've checked (vlax-curve-getclosestpointto) for some random UCS, and it assumed that checked point is in WCS and returned point in WCS, so I returned back my function to work the same way...]

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 23, 2012, 11:57:15 AM
I've decided to post *.lsp in code view since it was modified several times... Sorry for this, but this modifications are unavoidable...

Code: [Select]
(Defun MR-Curve-GetFurthestPointFromCircle ( CURVE POINT / osm cmde samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag pt )
(SetQ samples 200
     tolerance 1e-8
)
 
(Defun FurthestParameter (SP EP / seg params par furthest f ff ci cidata rad r rr k )
(SetQ params (List SP))
(SetQ seg 0.0)

(Defun IsFurther ( A B P )
 (>= (Distance A P) (Distance B P))
)
 
(Repeat samples
 (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
)
 
(SetQ furthest (Car (SetQ par
                (Vl-Sort-I
                 params
                 (Function
                  (Lambda (a b)
                   (IsFurther
                    (VLAX-Curve-GetPointAtParam CURVE a)
                    (VLAX-Curve-GetPointAtParam CURVE b)
                    POINT
                   )
                  )
                 )
                ))
               )
)

(setq f (nth furthest params))

(If (and (/= f ff) (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance))
 (setq ff (FurthestParameter
  (If (< (Nth furthest params) (Nth (Cadr par) params))
   (Nth furthest params)
   (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
    (Nth (Cadr par) params)
    (Nth (Caddr par) params)
   )
  )
  (If (< (Nth furthest params) (Nth (Cadr par) params))
   (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
    (Nth (Cadr par) params)
    (Nth (Caddr par) params)
   )
   (Nth furthest params)
  )
 ))
 (setq ff (Nth furthest params))
)

ff
)

(Setq pt
 (VLAX-Curve-GetPointAtParam
  CURVE
  (FurthestParameter
   (VLAX-Curve-GetStartParam CURVE)
   (VLAX-Curve-GetEndParam CURVE)
  )
 )
)

(setq cmde (getvar 'cmdecho))
(setq osm (getvar 'osmode))
(setvar 'cmdecho 0)
(setvar 'osmode 0)
(vl-cmdf "_.CIRCLE" (trans point 0 1) (trans pt 0 1))
(setq rad (cdr (assoc 40 (setq cidata (entget (setq ci (entlast)))))))
(setq pt (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object ci) acExtendNone))
(setq k 0.0)
(while (> (length pt) 3)
 (setq r (+ rad (* 1e-4 (setq k (1+ k)))))
 (entmod (subst (cons 40 r) (assoc 40 cidata) cidata))
 (entupd ci)
 (setq pt (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object ci) acExtendNone))
)
(setq k 0.0)
(setq r (cdr (assoc 40 cidata)))
(while (/= (length pt) 3)
 (setq rr (- r (* 1e-8 (setq k (1+ k)))))
 (entmod (subst (cons 40 rr) (assoc 40 cidata) cidata))
 (entupd ci)
 (setq pt (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object ci) acExtendNone))
)
(entdel ci)
(setvar 'osmode osm)
(setvar 'cmdecho cmde)
(list (car pt) (cadr pt) (caddr pt))
)

(defun vlax-curve-getfurthestpointfrom2d ( CURVE POINT / elst etype 2dtype lstn )

(Defun IsFurther ( A B P )
 (>= (Distance A P) (Distance B P))
)
 
(defun _polyvertices ( lst )
  (_vertices2 (entnext (cdr (assoc -1 lst))))
)
 
(defun _vertices2 ( e )
  (if (eq "VERTEX" (cdr (assoc 0 (entget e))))
    (progn
      (setq lstn (cons (assoc 10 (entget e)) lstn))
      (setq lstn (cons (assoc 42 (entget e)) lstn))
      (_vertices2 (entnext e))
    )
  )
  (reverse lstn)
)
 
(defun member-fuzz (expr lst fuzz)
  (while (and lst (not (equal (car lst) expr fuzz)))
    (setq lst (cdr lst))
  )
  lst
)
 
(defun _plcents ( ent / enpar n p1 p2 bulge rad cen cenlst )
  (setq enpar (vlax-curve-getendparam ent))
  (setq n -1)
  (repeat (fix enpar)
    (setq n (1+ n))
    (setq p1 (vlax-curve-getpointatparam ent (float n)))
    (setq p2 (vlax-curve-getpointatparam ent (float (1+ n))))
    (setq bulge (vla-getbulge (if (eq (type ent) 'ENAME) (vlax-ename->vla-object ent) ent) (float n)))
    (if (/= bulge 0.0)
      (progn
        (setq rad (/ (distance p1 p2) (* 2 (sin (* 2 (atan bulge))))))
        (setq cen (polar p1 (+ (angle p1 p2) (- (/ pi 2.0) (* 2 (atan bulge)))) rad))
        (setq cenlst (cons cen cenlst))
      )
    )
  )
  (reverse cenlst)
)
 
(SetQ elst (entget CURVE))
(SetQ etype (Cdr (Assoc 0 elst)))

(Cond
((And
  (= "ARC" etype)
  (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
 )
 (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
)
((And
  (= "CIRCLE" etype)
  (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
 )
 (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
)
((And
  (= "ELLIPSE" etype)
  (Equal POINT (Cdr (Assoc 10 elst)) 1e-8)
 )
 (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
)
((And
  (= "LWPOLYLINE" etype)
  (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
 )
 (Car
  (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
           (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  )
 )
)
((And
  (= "LWPOLYLINE" etype)
  (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  (member-fuzz POINT (_plcents (if vla-curve vla-CURVE CURVE)) 1e-8)
 )
 (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
)
((And
  (= "LWPOLYLINE" etype)
  (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  (not (member-fuzz POINT (_plcents (if vla-curve vla-CURVE CURVE)) 1e-8))
 )
 (MR-Curve-GetFurthestPointFromCircle CURVE POINT)
)
((And
  (= "POLYLINE" etype)
  (SetQ 2dtype (Cdr (Assoc 100 (Reverse elst))))
  (SetQ elst (_polyvertices elst))
  (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  (and (= 2dtype "AcDb2dPolyline") (member-fuzz POINT (_plcents (if vla-curve vla-CURVE CURVE)) 1e-8))
 )
 (MR-Curve-GetFurthestPointFromCircle CURVE (Mapcar '+ POINT (List -1e-3 -1e-3 0.0)))
)
((And
  (= "POLYLINE" etype)
  (not (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst))
  (not (member-fuzz POINT (_plcents (if vla-curve vla-CURVE CURVE)) 1e-8))
 )
 (MR-Curve-GetFurthestPointFromCircle CURVE POINT)
)
((And
  (= "POLYLINE" etype)
  (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
 )
 (Car
  (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
           (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  )
 )
)
(T
 (MR-Curve-GetFurthestPointFromCircle CURVE POINT)
)
)
)

(Defun MR-Curve-GetFurthestPointFrom ( CURVE POINT / samples tolerance IsFurther FurthestParameter elst etype cent rad vec mag )
(SetQ samples 200
     tolerance 1e-14
)
 
(Defun FurthestParameter (SP EP / seg params par furthest f ff )
(SetQ params (List SP))
(SetQ seg 0.0)

(Defun IsFurther ( A B P )
 (>= (Distance A P) (Distance B P))
)
 
(Repeat samples
 (SetQ params (Cons (+ SP (SetQ seg (+ seg (/ (- EP SP) samples)))) params))
)
 
(SetQ furthest (Car (SetQ par
                (Vl-Sort-I
                 params
                 (Function
                  (Lambda (a b)
                   (IsFurther
                    (VLAX-Curve-GetPointAtParam CURVE a)
                    (VLAX-Curve-GetPointAtParam CURVE b)
                    POINT
                   )
                  )
                 )
                ))
               )
)

(setq f (nth furthest params))

(If (and (/= f ff) (> (- (VLAX-Curve-GetDistAtParam CURVE EP) (VLAX-Curve-GetDistAtParam CURVE SP)) tolerance))
 (setq ff (FurthestParameter
  (If (< (Nth furthest params) (Nth (Cadr par) params))
   (Nth furthest params)
   (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
    (Nth (Cadr par) params)
    (Nth (Caddr par) params)
   )
  )
  (If (< (Nth furthest params) (Nth (Cadr par) params))
   (If (not (equal (VLAX-Curve-GetPointAtParam CURVE (Nth furthest params)) (VLAX-Curve-GetPointAtParam CURVE (Nth (Cadr par) params)) 1e-8))
    (Nth (Cadr par) params)
    (Nth (Caddr par) params)
   )
   (Nth furthest params)
  )
 ))
 (setq ff (Nth furthest params))
)

ff
)
 
 (VLAX-Curve-GetPointAtParam
  CURVE
  (FurthestParameter
   (VLAX-Curve-GetStartParam CURVE)
   (VLAX-Curve-GetEndParam CURVE)
  )
 )
 
)
 
(defun vlax-curve-getfurthestpointfrom3d ( CURVE POINT / elst etype 2dtype lstn )

(Defun IsFurther ( A B P )
 (>= (Distance A P) (Distance B P))
)
 
(defun _polyvertices ( lst )
  (_vertices2 (entnext (cdr (assoc -1 lst))))
)
 
(defun _vertices2 ( e )
  (if (eq "VERTEX" (cdr (assoc 0 (entget e))))
    (progn
      (setq lstn (cons (assoc 10 (entget e)) lstn))
      (setq lstn (cons (assoc 42 (entget e)) lstn))
      (_vertices2 (entnext e))
    )
  )
  (reverse lstn)
)
 
(defun member-fuzz (expr lst fuzz)
  (while (and lst (not (equal (car lst) expr fuzz)))
    (setq lst (cdr lst))
  )
  lst
)
 
(defun _plcents ( ent / enpar n p1 p2 bulge rad cen cenlst )
  (setq enpar (vlax-curve-getendparam ent))
  (setq n -1)
  (repeat (fix enpar)
    (setq n (1+ n))
    (setq p1 (vlax-curve-getpointatparam ent (float n)))
    (setq p2 (vlax-curve-getpointatparam ent (float (1+ n))))
    (setq bulge (vla-getbulge (vlax-ename->vla-object ent) (float n)))
    (if (/= bulge 0.0)
      (progn
        (setq rad (/ (distance p1 p2) (* 2 (sin (* 2 (atan bulge))))))
        (setq cen (polar p1 (+ (angle p1 p2) (- (/ pi 2.0) (* 2 (atan bulge)))) rad))
        (setq cenlst (cons cen cenlst))
      )
    )
  )
  (reverse cenlst)
)
 
(SetQ elst (entget CURVE))
(SetQ etype (Cdr (Assoc 0 elst)))

(Cond
((= "XLINE" etype)
 nil
)
((= "RAY" etype)
 nil
)
((= "LINE" etype)
 (If (IsFurther (Cdr (Assoc 10 elst)) (Cdr (Assoc 11 elst)) POINT)
  (Cdr (Assoc 10 elst))
  (Cdr (Assoc 11 elst))
 )
)
((And
  (= "POLYLINE" etype)
  (VL-Every (Function (Lambda ( x ) (Or (/= 42 (Car x)) (ZeroP (Cdr x))))) elst)
 )
 (Car
  (VL-Sort (MapCar (Function Cdr) (VL-Remove-If-Not (Function (Lambda ( x ) (= 10 (Car x)))) elst))
           (Function (Lambda ( a b ) (IsFurther a b POINT)) )
  )
 )
)
(T
 (MR-Curve-GetFurthestPointFrom CURVE POINT)
)
)
)

;; Vector Cross Product - Lee Mac
;; Args: u,v - vectors in R^3

(defun v^v ( u v )
  (list
    (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
    (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
    (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
  )
)

;; Collinear-p  -  Lee Mac
;; Returns T if p1,p2,p3 are collinear

(defun LM:Collinear-p ( p1 p2 p3 )
    (
        (lambda ( a b c )
            (or
                (equal (+ a b) c 1e-8)
                (equal (+ b c) a 1e-8)
                (equal (+ c a) b 1e-8)
            )
        )
        (distance p1 p2) (distance p2 p3) (distance p1 p3)
    )
)

;; Project Point onto Plane  -  Lee Mac
;; Projects pt onto the plane defined by its origin and normal

(defun LM:ProjectPointToPlane ( pt org nm )
    (setq pt  (trans pt  0 nm)
          org (trans org 0 nm)
    )
    (trans (list (car pt) (cadr pt) (caddr org)) nm 0)
)

(defun vlax-curve-getfurthestpointfrom ( curve point / vla-curve flagarc flaglw cmde pt pt1 pt2 pt3 pt4 )
  (setq cmde (getvar 'cmdecho))
  (if (eq (type curve) 'VLA-OBJECT)
    (progn
      (setq vla-curve curve)
      (setq curve (vlax-vla-object->ename vla-curve))
    )
  )
  (if (eq (cdr (assoc 0 (entget curve))) "ARC")
    (progn
      (setq flagarc T)
      (setvar 'cmdecho 0)
      (vl-cmdf "_.COPY" curve "" '(0.0 0.0 0.0) '(0.0 0.0 0.0))
      (vl-cmdf "_.PEDIT" (entlast) "" "")
      (setq curve (entlast))
      (setvar 'cmdecho cmde)
    )
  )
  (if (eq (cdr (assoc 0 (entget curve))) "LWPOLYLINE")
    (progn
      (setq flaglw T)
      (setvar 'cmdecho 0)
      (vl-cmdf "_.CONVERTPOLY" "H" curve "")
      (setq vla-curve (vlax-ename->vla-object curve))
      (setvar 'cmdecho cmde)
    )
  )
  (setq pt1 (vlax-curve-getpointatparam curve (+ (if (not (vl-catch-all-apply 'vlax-curve-getstartparam (list curve))) 0.0 (vlax-curve-getstartparam curve)) (* 1.0 (/ (- (if (not (vl-catch-all-apply 'vlax-curve-getendparam (list curve))) 3.0 (vlax-curve-getendparam curve)) (if (not (vl-catch-all-apply 'vlax-curve-getstartparam (list curve))) 0.0 (vlax-curve-getstartparam curve))) 3.0)))))
  (setq pt2 (vlax-curve-getpointatparam curve (+ (if (not (vl-catch-all-apply 'vlax-curve-getstartparam (list curve))) 0.0 (vlax-curve-getstartparam curve)) (* 2.0 (/ (- (if (not (vl-catch-all-apply 'vlax-curve-getendparam (list curve))) 3.0 (vlax-curve-getendparam curve)) (if (not (vl-catch-all-apply 'vlax-curve-getstartparam (list curve))) 0.0 (vlax-curve-getstartparam curve))) 3.0)))))
  (setq pt3 (vlax-curve-getpointatparam curve (+ (if (not (vl-catch-all-apply 'vlax-curve-getstartparam (list curve))) 0.0 (vlax-curve-getstartparam curve)) (* 3.0 (/ (- (if (not (vl-catch-all-apply 'vlax-curve-getendparam (list curve))) 3.0 (vlax-curve-getendparam curve)) (if (not (vl-catch-all-apply 'vlax-curve-getstartparam (list curve))) 0.0 (vlax-curve-getstartparam curve))) 3.0)))))
  (setq pt4 (vlax-curve-getstartpoint curve))
  (if (and (not (LM:Collinear-p pt1 pt2 pt3)) (not (LM:Collinear-p pt1 pt2 pt4)) (vlax-curve-isplanar curve))
    (cond ((not (and (equal (caddr pt1) 0.0 1e-8) (equal (caddr pt2) 0.0 1e-8) (equal (caddr pt3) 0.0 1e-8) (equal (caddr pt4) 0.0 1e-8)))
      (progn
        (setvar 'cmdecho 0)
        (vl-cmdf "_.UCS" "w")
        (vl-cmdf "_.UCS" "za" "" (v^v (mapcar '- pt2 pt1) (mapcar '- pt3 pt1)))
        (vl-cmdf "_.UCS" "m" (trans pt1 0 1))
        (setq pt (vlax-curve-getfurthestpointfrom2d curve (LM:ProjectPointToPlane point (trans '(0.0 0.0 0.0) 1 0) (mapcar '- (trans '(0.0 0.0 1.0) 1 0) (trans '(0.0 0.0 0.0) 1 0)))))
        (vl-cmdf "_.UCS" "p")
        (vl-cmdf "_.UCS" "p")
        (vl-cmdf "_.UCS" "p")
        (setvar 'cmdecho cmde)
      ))
      ((and (equal (caddr pt1) 0.0 1e-8) (equal (caddr pt2) 0.0 1e-8) (equal (caddr pt3) 0.0 1e-8) (equal (caddr pt4) 0.0 1e-8) (eq (getvar 'worlducs) 0))
      (progn
        (setvar 'cmdecho 0)
        (vl-cmdf "_.UCS" "w")
        (setq pt (vlax-curve-getfurthestpointfrom2d curve (LM:ProjectPointToPlane point '(0.0 0.0 0.0) '(0.0 0.0 1.0))))
        (vl-cmdf "_.UCS" "p")
        (setvar 'cmdecho cmde)
      ))
      ((and (equal (caddr pt1) 0.0 1e-8) (equal (caddr pt2) 0.0 1e-8) (equal (caddr pt3) 0.0 1e-8) (equal (caddr pt4) 0.0 1e-8) (eq (getvar 'worlducs) 1))
      (setq pt (vlax-curve-getfurthestpointfrom2d curve (LM:ProjectPointToPlane point '(0.0 0.0 0.0) '(0.0 0.0 1.0))))
      )
    )
    (setq pt (vlax-curve-getfurthestpointfrom3d curve point))
  )
  (setvar 'cmdecho 0)
  (gc)
  (if flaglw (vl-cmdf "_.CONVERTPOLY" "L" curve ""))
  (if flagarc (vl-cmdf "_.ERASE" (entlast) ""))
  (setvar 'cmdecho cmde)
  pt
)

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 24, 2012, 05:14:31 AM
The code was completely updated, it may not work with LWPOLYLINE or POLYLINE VLA-OBJECT with ARC-s... Also XLINE or RAY curve objects may break function, but their furthest point from is in infinity, so never mind; all other cases are computed... Also LWPOLYLINE curve is during execution of function converted to HEAVY POLYLINE, because of bug, but after it's converted back to LWPOLYLINE...

Sincerely, M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 24, 2012, 06:37:52 AM
The code was completely updated, it may not work with LWPOLYLINE or POLYLINE VLA-OBJECT with ARC-s... Also XLINE or RAY curve objects may break function, but their furthest point from is in infinity, so never mind; all other cases are computed... Also LWPOLYLINE curve is during execution of function converted to HEAVY POLYLINE, because of bug, but after it's converted back to LWPOLYLINE...

Sincerely, M.R.

All problems removed, you can download *.lsp...

Regards, M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 25, 2012, 04:17:56 AM
For those 3 latest downloads, my apology for one last modification... You have to insert line (gc) before end of code to make sure conversion of LWPOLYLINE is correct - in property palette (ctrl+1) you should get data as normal after execution of function...

M.R.
 8-) :-)
Title: Re: vlax-curve-getfurthestpointfrom
Post by: chlh_jd on August 28, 2012, 07:59:15 AM
Glad you can be in favor of .
However , If distance from point to curve is far enough away, such as must use light-years to desribe , this maximum distance lost meaning . I guess this is why autocad  put the 'getfurthestpointfrom' function  into .
I intended to create this function with some purpose in process of working with AutoCAD. I guess no one will draw entities so far away from checked point... As a matter a fact I already posted one possible usage of this function on www.cadtutor.net (you may google it) and it was with normal demands of CAD (Computer Aided Design)...
Now I didn't know it doing yet , but still in favor of you improving this function . :-)

For Arc perhaps
Code: [Select]
((= "ARC" etype)
  ((lambda (p c r)   
     (vlax-curve-getclosestpointto curve (polar p (angle p c) (+ r r)))     
     )
    (vlax-curve-getclosestpointto curve point)
    (cdr (assoc 10 elst))
    (cdr (assoc 40 elst))   
    )   
  )
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on August 28, 2012, 10:32:40 AM
Now I didn't know it doing yet , but still in favor of you improving this function . :-)

For Arc perhaps
Code: [Select]
((= "ARC" etype)
  ((lambda (p c r)   
     (vlax-curve-getclosestpointto curve (polar p (angle p c) (+ r r)))     
     )
    (vlax-curve-getclosestpointto curve point)
    (cdr (assoc 10 elst))
    (cdr (assoc 40 elst))   
    )   
  )

Thanks, chlh_jd for your reply... I thought that function was correct, but thanks to you I've updated it once more... It wasn't working with ARCs, so for those 4 latest downloads I've changed the code and file for download... Once again, my apology - you may test it now, and if you find any mistake, or error, please reply and report me...

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: chlh_jd on September 01, 2012, 02:11:46 AM
For Ellipse  (To solve quartic equation , See http://www.theswamp.org/index.php?topic=42656.msg478640#msg478640 )
Code: [Select]

((= "ELLIPSE" etype)
  ((lambda (p1 p2 e / foo ang a b)
     (defun foo (p a b / m n c aa bb cc dd ee xl)
       ;;get furthest point of ellipse which is initialized by Origin and X-axis .
       (setq m (car p)
     n (cadr p)
     c (- (* a a) (* b b))
     aa (* c c)
     bb (* -2 m a a c)
     cc (+ (* n n a a b b) (* m m a a a a) (* -1. a a c c))
     dd (* 2 m a a a a c)
     ee (* -1. m m (expt a 6))
     xl (->eq^4 aa bb cc dd ee)
     xl (mapcar
  (function
    (lambda (x / z)
      (setq z (* b (sqrt (- 1. (expt (/ x a) 2)))))
      (list (list x z) (list x (- z)))))
  xl)
     xl (apply 'append xl))
       (car
(vl-sort xl
  (function (lambda (e1 e2)
      (> (distance p e1) (distance p e2))))))
       )
     (setq ang (angle p2 (list 0 0 0))
   a   (distance p2 (list 0 0 0))
   b   (* a e))
     (vlax-curve-getclosestpointto
       curve
       (gsls-ab->xy (foo (gsls-xy->ab p p1 ang) a b) p1 ang))
     )
    (cdr (assoc 10 elst))
    (cdr (assoc 11 elst))
    (cdr (assoc 40 elst))
    )
  )
;;;将点AB坐标换算为XY坐标,AB坐标的原点为PT0,转角为R0
;;;X=X0+AcosR0-BsinR0
;;;Y=Y0+AsinR0+BcosR0
(defun gsls-AB->XY (pt pt0 ANG / X Y)
  (setq X (+ (car pt0)
     (* (car pt) (cos ANG))
     (* -1 (cadr pt) (sin ANG))
  )
Y (+ (cadr pt0)
     (* (car pt) (sin ANG))
     (* (cadr pt) (cos ANG))
  )
  )
  (list X Y 0.0)
)
;;;将点XY坐标换算为AB坐标,AB坐标的原点为PT0,转角为R0
;;;A=(X-X0)cosR0+(Y-Y0)sinR0
;;;B=(Y-Y0)cosR0-(X-X0)sinR0
(defun gsls-XY->AB (pt pt0 ANG / A B)
  (setq A (+ (* (- (car pt) (car pt0)) (cos ANG))
     (* (- (cadr pt) (cadr pt0)) (sin ANG))
  )
B (- (* (- (cadr pt) (cadr pt0)) (cos ANG))
     (* (- (car pt) (car pt0)) (sin ANG))
  )
  )
  (list A B 0.0)
)
It can be solve by New ELLipse equation which not need trans the point .
Code: [Select]
[(x-x0)cosθ+(y-y0)sinθ]²/a² + [(y-y0)cosθ-(x-x0)sinθ]²/b²=1
Title: Re: vlax-curve-getfurthestpointfrom
Post by: DEVITG on September 01, 2012, 04:52:00 PM
MR, could you please , upload the lisp , or give the link where it is.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on September 03, 2012, 02:28:36 AM
If you can't download it from here :
http://www.theswamp.org/index.php?topic=42246.msg477718#msg477718
(you are not logged)
Then copy+paste the code from here :
http://www.theswamp.org/index.php?topic=42246.msg477835#msg477835
to notepad and save it as vlax-curve-getfurthestpointfrom.lsp

Load *.lsp with appload, and activate vla-functions (vl-load-com)
1. pick point : (setq p (getpoint))
2. pick curve : (setq e (car (entsel))) or if you want you can use VLA-OBJECT also (setq e (vlax-ename->vla-object (car (entsel))))

3. calculate point : (setq pp (vlax-curve-gettfurthestpointfrom e p))

M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: chlh_jd on September 03, 2012, 04:35:15 AM
Hi ribarm , how about new for Ellipse .
Code: [Select]
((= "ELLIPSE" etype)
  ;;For 3d method
  ((lambda (p1 p2 e norm / foo ang a b p)
     (defun foo (p a b / m n c aa bb cc dd ee xl)
       ;;get furthest point of ellipse which is initialized by Origin and X-axis .
       (setq m (car p)
      n (cadr p)
      c (- (* a a) (* b b))
      aa (* c c)
      bb (* -2 m a a c)
      cc (+ (* n n a a b b) (* m m a a a a) (* -1. a a c c))
      dd (* 2 m a a a a c)
      ee (* -1. m m (expt a 6))
      xl (->eq^4 aa bb cc dd ee)
      xl (mapcar
   (function
     (lambda (x / z)
       (setq z (* b (sqrt (- 1. (expt (/ x a) 2)))))
       (list (list x z) (list x (- z)))))
   xl)
      xl (apply 'append xl))
       (car
(vl-sort xl
   (function (lambda (e1 e2)
       (> (distance p e1) (distance p e2))))))
       )
     (setq  a   (distance p2 (list 0 0 0))
    b   (* a e)
    p (mapcar (function -) (trans point 0 norm) (trans p1 0 norm))    
            p (foo (list (cadr p) (- (car p))) a b)             
    p (trans (mapcar (function +) (list (- (cadr p)) (car p) 0.0) (trans p1 0 norm)) norm 0))
     (vlax-curve-getclosestpointto    curve  p)
     )
    (cdr (assoc 10 elst))
    (cdr (assoc 11 elst))
    (cdr (assoc 40 elst))
    (cdr (assoc 210 elst))
    )
  )
I think you are tired to edit this function  :-D
The vla-intersectwith method  will take so much time in recursion , perhaps this way  : get boundingbox , cal max included circle ,and then cal the point of the circle which closest to the given curve  .
Title: Re: vlax-curve-getfurthestpointfrom
Post by: chlh_jd on September 04, 2012, 07:22:32 AM
Hi ribarm , how about new for Ellipse .
Code: [Select]
((= "ELLIPSE" etype)
  ;;For 3d method
  ((lambda (p1 p2 e norm / foo ang a b p)
     (defun foo (p a b / m n c aa bb cc dd ee xl)
       ;;get furthest point of ellipse which is initialized by Origin and X-axis .
       ...  )
I think you are tired to edit this function  :-D
The vla-intersectwith method  will take so much time in recursion , perhaps this way  : get boundingbox , cal max included circle ,and then cal the point of the circle which closest to the given curve  .
I found the code I often is not really work for 3D, and it's Accuracy just 1e-3 , perhaps by solve the equation method has much deviation .
Ribarm's thoughts is right .
However , I yet want to post my code for Circle or Arc for 3D  .
Code: [Select]
((= "ARC" etype)
     ((lambda (p c)
(vlax-curve-getclosestpointto
  curve
  (pt+ p (pt* (pt- c p) 2.)))
)
       (vlax-curve-getclosestpointto curve point)
       (cdr (assoc 10 elst))       
       )
     )
    ((= "CIRCLE" etype)
     ((lambda (p c)
(vlax-curve-getclosestpointto curve (pt+ p (pt* (pt- c p) 2.)))
)
       (vlax-curve-getclosestpointto curve point)
       (cdr (Assoc 10 elst))       
       )
     )
;;;Vector +
(defun pt+ (pt1 pt2)
  (mapcar (function +)
  pt1
  pt2
  )
)
;;;Vector -
(defun pt- (pt2 pt1)
  (mapcar (function -)
  pt2
  pt1
  )
)
;;;Vector *
(defun pt* (v sc)
  (mapcar (function (lambda (x)
      (* x sc)
    )
  )
  v
  )
)
Title: Re: vlax-curve-getfurthestpointfrom
Post by: chlh_jd on September 04, 2012, 07:50:13 AM
This flower LwPolyLine has 8 furthest points if the given point is center .
Routine loop not end .
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on September 04, 2012, 08:21:14 AM
For this case, you had not to relay on computations, but you'll have to input different point than center (any other point that lies on axises I drawn from center - see my jpg)...
Title: Re: vlax-curve-getfurthestpointfrom
Post by: chlh_jd on September 13, 2012, 08:16:38 AM
My version , Use the method on the reply #53
Code: [Select]
(defun c:test  (/ en pt p2)
  (setq en (car (entsel)))
  (setq pt (trans (getpoint) 1 0)) 
  (if (setq p2 (getfurthestpointfrom en pt))
    (progn
      (entmake (list (cons 0 "LINE")
     (cons 10 pt)
     (cons 11 p2)
     (cons 62 1)))
      (princ (strcat "\n Maxdistance = " (rtos (distance pt p2) 2 8)))
      ))
  (princ)
  )
(defun getfurthestpointfrom  (en pt / en ent etype pt p1 p R p2 d d1 d2 p3 p4 p5 p6)
  ;;; GetFurthestpointfrom for 3D curve .
  ;;; For Periodic Curve ( not for LINE , Xline ...)
  ;;; GSLS(SS) 2012-9-13
  (if (and en
   pt
   (setq ent (entget en))
   (not (member (setq etype (strcase (dxf 0 ent))) (list "LINE" "XLINE" "RAY"))))      
    (progn
      ((lambda (obj / minpt maxpt box)
(vla-GetBoundingBox
   obj
   (quote minpt)
   (quote maxpt))
(setq minPt (vlax-safearray->list minPt)
       maxPt (vlax-safearray->list maxPt))
(setq box (vlex-ex2con (list minpt maxpt)))
(setq
   p (car
       (vl-sort
box
(function
   (lambda (p1 p2)
     (> (distance pt p1) (distance pt p2)))))))
(vlax-release-object obj))
(vlax-ename->vla-object en))
      (setq R  (distance pt p)
    p2 (vlax-curve-getclosestpointto en p))
      (setq d (distance pt p2))
      (while (< d
(setq
  d1 (distance pt
       (setq p3
      (vlax-curve-getclosestpointto
en
(pt+
  pt
  (pt* (v2u (mapcar (function -) p2 pt))
       r)))))))
(setq d d1
      p2 p3))
      (while
(< d
   (setq
     d1 (distance
  pt
  (setq
    p4 (vlax-curve-getclosestpointto
en
(midpt p2 p3))))))
(setq d  d1
       p3 p2
       p2 p4))
      (while (or (< d
    (setq d1
   (distance
     pt
     (setq p5 (vlax-curve-getclosestpointto
en
(midpt p2 p4))))))
(< d
    (setq d2
   (distance
     pt
     (setq p6 (vlax-curve-getclosestpointto
en
(midpt p3 p4)))))))
(if p6
  (setq d  d2
p2 p4)
  (setq d  d1
p3 p4))
(setq p4 (vlax-curve-getclosestpointto en (midpt p2 p3))
      p5 nil
      p6 nil)))
      (if (= etype "LINE")
(if (> (distance pt (setq p1 (dxf 10 ent))) (distance pt (setq p2 (dxf 11 ent))))
    (setq p2 p1)))
    )
   p2
  )
;;;-----------------------------
;;; Use functions
(defun dxf (n l)
  (cdr (assoc n l)))
 
(defun midpt (pta ptb)
  (mapcar (function (lambda (x y)
      (/ (+ x y) 2.0)
    )
  )
  pta
  ptb
  )
)
;;;Vector +
(defun pt+ (pt1 pt2)
  (mapcar (function +)
  pt1
  pt2
  )
)
;;;Vector -
(defun pt- (pt2 pt1)
  (mapcar (function -)
  pt2
  pt1
  )
)
;;;Vector *
(defun pt* (v sc)
  (mapcar (function (lambda (x)
      (* x sc)
    )
  )
  v
  )
)
;;; Vector Unit
(defun v2u (v / d)
 (setq d (sqrt (apply (function +) (mapcar (function *) v v))))
 (if (/= d 0)   
   (mapcar (function (lambda (x) (/ x d))) v)   
   )
)
(defun vlex-ex2con  (pts / 2dbox)
  (defun 2dbox (p1 p2)
    (list p1
  (cons (car p2) (cdr p1))
  p2
  (cons (car p1) (cdr p2))))
  (setq pts (mapcar (function (lambda (x) (trans x 0 0))) pts))
  (if (= (caddar pts) (caddr (cadr pts)))
    (2dbox (car pts) (cadr pts))
    (append
      (2dbox
(car pts)
(list (caadr pts) (cadadr pts) (caddar pts)))
      (2dbox
(list (caar pts) (cadar pts) (caddr (cadr pts)))
(cadr pts)))
    ))
Title: Re: vlax-curve-getfurthestpointfrom
Post by: chlh_jd on September 13, 2012, 08:59:57 AM
No closed spline is not Periodic , I update codes on up post.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on July 27, 2013, 04:09:26 AM
I've rewritten this function to be more concise and better for usage...

This version is little larger, and may fail in some cases like the one posted above.
So I don't guarantee for this one, but if works on 2d curves, result is the most precise :

Code: [Select]
(defun vlax-curve-getfurthestpointfrom ( curve pt / _precise LM:ProjectPointToPlane
                                                     sd ed dd p1 p2 d1 d2 d p pc rad ci k r rr )

  (setq sd (vlax-curve-getdistatparam curve (vlax-curve-getstartparam curve)))
  (setq ed (vlax-curve-getdistatparam curve (vlax-curve-getendparam curve)))
  (setq p1 T p2 T dd 0.0)
  (while (and p1 p2)
    (setq p1 (vlax-curve-getpointatdist curve (+ sd dd)))
    (setq dd (+ dd (/ ed 100.0)))
    (setq d1 (distance pt p1))
    (setq p2 (vlax-curve-getpointatdist curve (+ sd dd)))
    (if (>= (+ sd dd) ed) (setq p2 (vlax-curve-getendpoint curve)))
    (setq d2 (distance pt p2))
    (if (null p) (setq p p1))
    (if (> d1 (distance pt p)) (setq p p1))
    (if (> d2 (distance pt p)) (setq p p2))
    (if (> (+ sd dd) ed) (setq p1 nil p2 nil))
  )

  (defun _precise ( fact / p1 p2 dd d )
    (setq p1 T p2 T dd 0.0 d nil)
    (while (and p1 p2)
      (if (not (equal p (vlax-curve-getstartpoint curve) 1e-8))
        (progn
          (setq p1 (vlax-curve-getpointatdist curve (+ (if (null d) (setq d (- (vlax-curve-getdistatpoint curve p) (/ ed fact))) d) dd)))
          (setq dd (+ dd (/ ed fact 100.0)))
          (setq d1 (distance pt p1))
          (setq p2 (vlax-curve-getpointatdist curve (+ d dd)))
          (if (>= (+ d dd) ed) (setq p2 (vlax-curve-getendpoint curve)))
          (setq d2 (distance pt p2))
          (if (> d2 d1) (setq p p2) (setq p1 nil p2 nil))
        )
        (setq p1 nil p2 nil)
      )
    )
  )

  (_precise (expt 100.0 1.0))
  (_precise (expt 100.0 2.0))
  (_precise (expt 100.0 3.0))
  (_precise (expt 100.0 4.0))
  (_precise (expt 100.0 5.0))
  (_precise (expt 100.0 6.0))
  (_precise (expt 100.0 7.0))
  (_precise (expt 100.0 8.0))
  (_precise (expt 100.0 9.0))
  (_precise (expt 100.0 10.0))

  (defun LM:ProjectPointToPlane ( pt org nm )
    (setq pt  (trans pt  0 nm)
          org (trans org 0 nm)
    )
    (trans (list (car pt) (cadr pt) (caddr org)) nm 0)
  )

  (if (eq (vlax-curve-isplanar curve) T)
    (progn
      (setq pc (LM:ProjectPointToPlane pt (vlax-curve-getstartpoint curve) (cdr (assoc 210 (entget curve)))))
      (setq rad (distance pc p))
      (setq pc (trans pc 0 (cdr (assoc 210 (entget curve)))))
      (setq ci (entmakex (list (cons 0 "CIRCLE") (cons 10 pc) (cons 40 rad) (assoc 210 (entget curve)))))
      (setq cid (entget ci))
      (while (not (setq p (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object ci) acExtendNone)))
        (entmod (subst (list 10 (if (equal (cadr (assoc 10 cid)) 0.0 1e-8) 0.0 (cadr (assoc 10 cid))) (if (equal (caddr (assoc 10 cid)) 0.0 1e-8) 0.0 (caddr (assoc 10 cid))) (if (equal (cadddr (assoc 10 cid)) 0.0 1e-8) 0.0 (cadddr (assoc 10 cid)))) (assoc 10 cid) cid))
        (entupd ci)
      )
      (setq k 0.0)
      (while (> (length p) 3)
        (setq r (+ rad (* 5e-8 (setq k (1+ k)))))
        (entmod (subst (cons 40 r) (assoc 40 cid) cid))
        (entupd ci)
        (setq p (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object ci) acExtendNone))
      )
      (setq k 0.0)
      (setq r (cdr (assoc 40 (entget ci))))
      (while (/= (length p) 3)
        (setq rr (- r (* 5e-11 (setq k (1+ k)))))
        (entmod (subst (cons 40 rr) (assoc 40 cid) cid))
        (entupd ci)
        (setq p (vlax-invoke (vlax-ename->vla-object curve) 'IntersectWith (vlax-ename->vla-object ci) acExtendNone))
      )
      (entdel ci)
      p
    )
    p
  )
)

So instead of this one, I strongly suggest that you use this one even shorter, but applicable in all cases,
although not so precise, but until Autodesk launch real version, this one is the most advanced until now :

Code - Auto/Visual Lisp: [Select]
  1. (defun vlax-curve-getfurthestpointfrom ( curve pt / _precise sd ed dd p1 p2 d1 d2 d p )
  2.   (setq p1 T p2 T dd 0.0)
  3.   (while (and p1 p2)
  4.     (setq p1 (vlax-curve-getpointatdist curve (+ sd dd)))
  5.     (setq dd (+ dd (/ ed 100.0)))
  6.     (setq d1 (distance pt p1))
  7.     (setq p2 (vlax-curve-getpointatdist curve (+ sd dd)))
  8.     (if (>= (+ sd dd) ed) (setq p2 (vlax-curve-getendpoint curve)))
  9.     (setq d2 (distance pt p2))
  10.     (if (null p) (setq p p1))
  11.     (if (> d1 (distance pt p)) (setq p p1))
  12.     (if (> d2 (distance pt p)) (setq p p2))
  13.     (if (> (+ sd dd) ed) (setq p1 nil p2 nil))
  14.   )
  15.  
  16.   (defun _precise ( fact / p1 p2 dd d )
  17.     (setq p1 T p2 T dd 0.0 d nil)
  18.     (while (and p1 p2)
  19.       (if (not (equal p (vlax-curve-getstartpoint curve) 1e-8))
  20.         (progn
  21.           (setq p1 (vlax-curve-getpointatdist curve (+ (if (null d) (setq d (- (vlax-curve-getdistatpoint curve p) (/ ed fact))) d) dd)))
  22.           (setq dd (+ dd (/ ed fact 100.0)))
  23.           (setq d1 (distance pt p1))
  24.           (setq p2 (vlax-curve-getpointatdist curve (+ d dd)))
  25.           (if (>= (+ d dd) ed) (setq p2 (vlax-curve-getendpoint curve)))
  26.           (setq d2 (distance pt p2))
  27.           (if (> d2 d1) (setq p p2) (setq p1 nil p2 nil))
  28.         )
  29.         (setq p1 nil p2 nil)
  30.       )
  31.     )
  32.   )
  33.  
  34.   (_precise (expt 100.0 1.0))
  35.   (_precise (expt 100.0 2.0))
  36.   (_precise (expt 100.0 3.0))
  37.   (_precise (expt 100.0 4.0))
  38.   (_precise (expt 100.0 5.0))
  39.   (_precise (expt 100.0 6.0))
  40.   (_precise (expt 100.0 7.0))
  41.   (_precise (expt 100.0 8.0))
  42.   (_precise (expt 100.0 9.0))
  43.   (_precise (expt 100.0 10.0))
  44.  
  45.   p
  46. )
  47.  

Regards, all the best in using (vlax-curve-getfurthestpointfrom)
M.R.
Title: Re: vlax-curve-getfurthestpointfrom
Post by: ribarm on November 04, 2013, 09:04:50 PM
Little late, but better ever than never... I should have added final touch much much earlier... So here is final (vlax-curve-getfurthestpointfrom)... From my testings, it should return exact point that is furthest from desired point anywhere in 3D...

Code - Auto/Visual Lisp: [Select]
  1. (defun vlax-curve-getfurthestpointfrom ( curve pt / _precise sd ed dd p1 p2 d1 d2 d ptt pp p )
  2.   (setq p1 T p2 T dd 0.0)
  3.   (while (and p1 p2)
  4.     (setq p1 (vlax-curve-getpointatdist curve (+ sd dd)))
  5.     (setq dd (+ dd (/ ed 100.0)))
  6.     (setq d1 (distance pt p1))
  7.     (setq p2 (vlax-curve-getpointatdist curve (+ sd dd)))
  8.     (if (>= (+ sd dd) ed) (setq p2 (vlax-curve-getendpoint curve)))
  9.     (setq d2 (distance pt p2))
  10.     (if (null p) (setq p p1))
  11.     (if (> d1 (distance pt p)) (setq p p1))
  12.     (if (> d2 (distance pt p)) (setq p p2))
  13.     (if (> (+ sd dd) ed) (setq p1 nil p2 nil))
  14.   )
  15.  
  16.   (defun _precise ( fact / p1 p2 dd d )
  17.     (setq p1 T p2 T dd 0.0 d nil)
  18.     (while (and p1 p2)
  19.       (if (not (equal p (vlax-curve-getstartpoint curve) 1e-8))
  20.         (progn
  21.           (setq p1 (vlax-curve-getpointatdist curve (+ (if (null d) (setq d (- (vlax-curve-getdistatpoint curve p) (/ ed fact))) d) dd)))
  22.           (setq dd (+ dd (/ ed fact 100.0)))
  23.           (setq d1 (distance pt p1))
  24.           (setq p2 (vlax-curve-getpointatdist curve (+ d dd)))
  25.           (if (>= (+ d dd) ed) (setq p2 (vlax-curve-getendpoint curve)))
  26.           (setq d2 (distance pt p2))
  27.           (if (> d2 d1) (setq p p2) (setq p1 nil p2 nil))
  28.         )
  29.         (setq p1 nil p2 nil)
  30.       )
  31.     )
  32.   )
  33.  
  34.   (_precise (expt 100.0 1.0))
  35.   (_precise (expt 100.0 2.0))
  36.   (_precise (expt 100.0 3.0))
  37.   (_precise (expt 100.0 4.0))
  38.   (_precise (expt 100.0 5.0))
  39.   (_precise (expt 100.0 6.0))
  40.   (_precise (expt 100.0 7.0))
  41.   (_precise (expt 100.0 8.0))
  42.   (_precise (expt 100.0 9.0))
  43.   (_precise (expt 100.0 10.0))
  44.  
  45.   (setq ptt (mapcar '+ pt (mapcar '* '(2.0 2.0 2.0) (mapcar '- p pt))))
  46.   (while (not (equal p pp 1e-50))
  47.     (setq p pp)
  48.     (setq ptt (mapcar '+ pt (mapcar '* '(2.0 2.0 2.0) (mapcar '- p pt))))
  49.     (setq pp (vlax-curve-getclosestpointto curve ptt))
  50.   )
  51.   p
  52. )
  53.  

M.R.
 8-) 8-) 8-)