TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Coder on May 09, 2012, 02:03:16 PM

Title: How to check if coordinates are equal ?
Post by: Coder on May 09, 2012, 02:03:16 PM
Hello .

I would like to check if a coordinate is a member in a list .
Code: [Select]
  (setq mylist (23.337 6.63198) (22.9351 6.23005) (22.9351 8.02967) (16.5646 12.593) (14.5698 8.22248) (9.64711 7.83685) (6.42968 11.661) (6.42968 5.65161))

this code fail >>>>
(mapcar (function (lambda (coord)
  (if (member '(23.337 6.63198) coord)
    (setq num (1+ num))
    )))
    mylist
  )
and this one also >>>>

(mapcar (function (lambda (coord)
  (if (vl-position '(23.337 6.63198) coord)
    (setq num (1+ num))
    )))
    mylist
  )

Thanks
Title: Re: How to check if coordinates are equal ?
Post by: dgorsman on May 09, 2012, 02:29:45 PM
Coordinates may have additional numbers past the displayed precision, so unlike definite information (e.g. "a" always matches "a") its very difficult to get an exact match out of a list with (member...), (vl-position...), etc. which by default do an (= ...) type check which requires an exact match.

Consider rolling your own comparison function using (equal...) so you can specify a fuzz-factor.
Title: Re: How to check if coordinates are equal ?
Post by: gile on May 09, 2012, 02:32:02 PM
Hi,

Code: [Select]
(defun gc:memberFuzz (expr lst fuzz)
  (while (and lst (not (equal (car lst) expr fuzz)))
    (setq lst (cdr lst))
  )
  lst
)
Title: Re: How to check if coordinates are equal ?
Post by: Keith™ on May 09, 2012, 02:39:20 PM
+1 on the roll yer own and "equal"

In your lambda function, try comparing the X and Y coords independently using a fuzz factor

Code: [Select]
(and (equal 23.337 (car coord) 0.0001)(equal 6.63198 (cadr coord) 0.0001))
Title: Re: How to check if coordinates are equal ?
Post by: Lee Mac on May 09, 2012, 03:25:22 PM
Code - Auto/Visual Lisp: [Select]
  1. (defun MemberWithFuzz ( itm lst fuzz )
  2.     (vl-member-if '(lambda ( x ) (equal x itm fuzz)) lst)
  3. )
Title: Re: How to check if coordinates are equal ?
Post by: Coder on May 09, 2012, 03:34:06 PM
Thank you all guys . :-)

What is the best value for fuzz ?
Title: Re: How to check if coordinates are equal ?
Post by: MP on May 09, 2012, 03:37:32 PM
peach
Title: Re: How to check if coordinates are equal ?
Post by: Coder on May 09, 2012, 03:57:41 PM
peach

peach has a value ?
Title: Re: How to check if coordinates are equal ?
Post by: fixo on May 09, 2012, 04:13:04 PM
0.00001 would be enough for your list
Title: Re: How to check if coordinates are equal ?
Post by: dgorsman on May 09, 2012, 04:28:14 PM
I generally aim for one decimal place smaller than the most precise number e.g. coordinates are in millimeters, I would use a fuzz factor of 0.1 (mm).  If coordinates are in meters to three decimal places i.e. m.mmm I would use 0.0001 (m).
Title: Re: How to check if coordinates are equal ?
Post by: Kerry on May 09, 2012, 10:15:55 PM
Thank you all guys . :-)

What is the best value for fuzz ?

Bill's beard.



sorry, you probably had to be there :)
Title: Re: How to check if coordinates are equal ?
Post by: Coder on May 10, 2012, 02:00:39 AM
Thank you all guys . :-)

What is the best value for fuzz ?

Bill's beard.

sorry, you probably had to be there :)

Hi Kerry .

I have no idea about that , can you please be more straight to the point . ?  :wink:

Thank you
Title: Re: How to check if coordinates are equal ?
Post by: Coder on May 13, 2012, 08:22:45 AM
I am sorry guys , I am still don't know how to chose the correct value for the fuzz and how to filter a list of coordinates to
remove the equal one from the list.  :oops:

Thanks
Title: Re: How to check if coordinates are equal ?
Post by: Stefan on May 13, 2012, 08:47:49 AM
Remove a point from a list:
Code - Auto/Visual Lisp: [Select]
  1. (defun remove_point (point lst)
  2.   (if (equal point (car lst) 1e-4)
  3.     (cdr lst)
  4.     (if lst (cons (car lst) (remove_point point (cdr lst))))
  5.     )
  6.   )
  7.  
Code: [Select]
_$ (setq mylist '((23.337 6.63198) (22.9351 6.23005) (22.9351 8.02967) (16.5646 12.593) (14.5698 8.22248) (9.64711 7.83685) (6.42968 11.661) (6.42968 5.65161)))
_$ (remove_point '(16.5646 12.593) mylist)
((23.337 6.63198) (22.9351 6.23005) (22.9351 8.02967) (14.5698 8.22248) (9.64711 7.83685) (6.42968 11.661) (6.42968 5.65161))
A precision of 1e-4 would be enough.
Title: Re: How to check if coordinates are equal ?
Post by: Stefan on May 13, 2012, 09:00:38 AM
Previous lisp will remove only first instance of a point from a list of points.
To remove all points, use this
Code - Auto/Visual Lisp: [Select]
  1. (defun remove_point (point lst)
  2.   (if lst
  3.     (if (equal point (car lst) 1e-4)
  4.       (remove_point point (cdr lst))
  5.       (cons (car lst) (remove_point point (cdr lst)))
  6.       )
  7.     )
  8.   )
Title: Re: How to check if coordinates are equal ?
Post by: Lee Mac on May 13, 2012, 12:19:29 PM
Or simply;

Code - Auto/Visual Lisp: [Select]
  1. (defun _RemoveWithFuzz ( item lst fuzz )
  2.     (vl-remove-if '(lambda ( x ) (equal item x fuzz)) lst)
  3. )
  4.  
Title: Re: How to check if coordinates are equal ?
Post by: VovKa on May 13, 2012, 02:43:23 PM
when dealing with coordinates, i suggest checking distances between them
Code: [Select]
(equal (distance p1 p2) 0 fuzz)i think it's more correct
Title: Re: How to check if coordinates are equal ?
Post by: Keith™ on May 13, 2012, 02:49:12 PM
that is a good idea
Title: Re: How to check if coordinates are equal ?
Post by: irneb on May 14, 2012, 05:10:36 AM
In that same vein, you could then get rid of the equal function itself. All you need to figure is if the distance between the points is smaller than the fuzz:
Code: [Select]
(< (distance p1 p2) fuzz)
Title: Re: How to check if coordinates are equal ?
Post by: dgorsman on May 14, 2012, 05:01:47 PM
Depending on the means used to calculate the distance, it could start throwing errors if the coordinates are far enough away from the WCS origin (we get this quite often with models in mm).  For example, if the numbers need to be squared in the distance calculation.  Progressive checking (e.g. first X, then Y, then Z) may be of some benefit, since if the first value is too far off the rest of the values are irrelevant, same with the second.  Changes it from multiple square/root operations to a comparison of reals.

There may also be some other concerns - doesn't (distance...) use some current dimension style variables for precision?
Title: Re: How to check if coordinates are equal ?
Post by: gile on May 27, 2012, 07:03:38 AM
Hi,

The minFuzz routine returns the minimum fuzz usable with equal according to the point position within the significant digits of a floating point number (http://en.wikipedia.org/wiki/Floating_point).

Code - Lisp: [Select]
  1. (defun minFuzz (n)
  2.   (if (zerop n)
  3.     1e-14
  4.     (expt 10. (- (fix (/ (log (abs n)) (log 10))) 14))
  5.   )
  6. )

(minFuzz 1.234567890123456) returns 1.0e-014
(minFuzz 1234567.890123456) returns 1.0e-008

To compare points whith the greatest minFuzz of the 2 points coordinates:

Code - Lisp: [Select]
  1. (defun equalPoints (p1 p2)
  2.   (equal p1 p2 (apply 'max (mapcar 'minFuzz (append p1 p2))))
  3. )
Title: Re: How to check if coordinates are equal ?
Post by: irneb on May 27, 2012, 07:25:12 AM
That's a very good idea. One thing I'd do though: Calculate the minFuzz only on the coordinate vale which has the largest absolute value:
Code - Auto/Visual Lisp: [Select]
  1. (defun equalPoints (p1 p2)
  2.   (equal p1 p2 (minFuzz (apply 'max (mapcar 'abs (append p1 p2))))))
Don't know if this might be faster, but to me it looks more logical.
Title: Re: How to check if coordinates are equal ?
Post by: irneb on May 27, 2012, 07:35:18 AM
There may also be some other concerns - doesn't (distance...) use some current dimension style variables for precision?
It's the first I've heard of that, aren't you thinking of the rtos function? You have a point about the squaring though, I think the distance function uses the Pythagorean theorem. So it squares all values and then square roots them, thus it might produce larger floating point errors than expected.

On the other hand, comparing xyz values creates a fuzz box in a cube form, while comparing distances fuzzes a sphere. So the same fuzz in xyz might make for a larger distance between two points if they fall in opposite corners of the cube.
Title: Re: How to check if coordinates are equal ?
Post by: irneb on May 27, 2012, 08:08:24 AM
Hi,

The minFuzz routine returns the minimum fuzz usable with equal according to the point position within the significant digits of a floating point number (http://en.wikipedia.org/wiki/Floating_point).

Code - Lisp: [Select]
  1. (defun minFuzz (n)
  2.   (if (zerop n)
  3.     1e-14
  4.     (expt 10. (- (fix (/ (log (abs n)) (log 10))) 14))
  5.   )
  6. )
To get the min Fuzz even smaller, you might want to change the 14 decimal points to 52 binary points. Seeing as the double precision uses 53 bits for the significand, and 11 for the exponent. But that's just splitting hairs ... literally  :lmao: .