sathalex Posted April 17, 2017 Share Posted April 17, 2017 Hello! In my drawing there are 200 primitives "point", how would I quickly find the highest and the lowest of them? Quote Link to comment Share on other sites More sharing options...
Tharwat Posted April 17, 2017 Share Posted April 17, 2017 Hi, Easily you can do that by retrieving the coordinates of each point then sort them with their Maximum Y coordinate, then finally the first and the last items in the list would be the Highest & Lowest. Quote Link to comment Share on other sites More sharing options...
David Bethel Posted April 17, 2017 Share Posted April 17, 2017 If the points have been compiled as a list then (apply 'max (mapcar 'caddr pt_list)) (apply 'min (mapcar 'caddr pt_list)) There are several other metheods available as well. -David Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 17, 2017 Share Posted April 17, 2017 Sorting should be avoided when trying to determine the extrema of a point set, as the set need only be processed once. This may therefore be performed with O(n) efficiency, whereas sorting is generally on the order of O(n log n). I would therefore suggest something like: (defun maxmin ( lst / mni mxa zco zmi zmx ) (setq mni (car lst) zmi (caddr mni) mxa mni zmx zmi) (foreach itm (cdr lst) (setq zco (caddr itm)) (cond ( (< zmx zco) (setq mxa itm zmx zco) ) ( (< zco zmi) (setq mni itm zmi zco) ) ) ) (list mni mxa) ) Quote Link to comment Share on other sites More sharing options...
sathalex Posted April 17, 2017 Author Share Posted April 17, 2017 Sorting should be avoided when trying to determine the extrema of a point set, as the set need only be processed once. This may therefore be performed with O(n) efficiency, whereas sorting is generally on the order of O(n log n). I would therefore suggest something like: (defun maxmin ( lst / mni mxa zco zmi zmx ) (setq mni (car lst) zmi (caddr mni) mxa mni zmx zmi) (foreach itm (cdr lst) (setq zco (caddr itm)) (cond ( (< zmx zco) (setq mxa itm zmx zco) ) ( (< zco zmi) (setq mni itm zmi zco) ) ) ) (list mni mxa) ) At the command prompt Error: too few arguments ((( Quote Link to comment Share on other sites More sharing options...
BIGAL Posted April 18, 2017 Share Posted April 18, 2017 Worked for me (SETQ LST (LIST (LIST 10 20 30)(LIST 20 20 20)(LIST 10 10 100))) (maxmin lst) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 18, 2017 Share Posted April 18, 2017 At the command prompt Error: too few arguments ((( The function is for use in other programs, it does not define an AutoCAD command. Quote Link to comment Share on other sites More sharing options...
Grrr Posted April 18, 2017 Share Posted April 18, 2017 Awesome (effective) function Lee, Just figured out: Why don't write something more global using the same algorithm, like accepting function and list arguments (just like vl-sort), i.e.: (foo (lambda (r x) (< r x)) '(3 8 9 1 5 6 2 7) ) -> 1 where lambda is a test function and takes two arguments for comparing: r - item to be returned x - comparsion item Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 18, 2017 Share Posted April 18, 2017 Thanks Grrr - as for a generic function, consider the following: (defun extremum ( cmp lst / rtn ) (setq rtn (car lst)) (foreach itm (cdr lst) (if (apply cmp (list itm rtn)) (setq rtn itm)) ) rtn ) _$ (extremum '< '(3 8 9 1 5 6 2 7)) 1 _$ (extremum '(lambda ( a b ) (< (caddr a) (caddr b))) '((1.2 5.7 8.3) (9.4 2.6 0.3) (5.7 6.6 7.2))) (9.4 2.6 0.3) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 18, 2017 Share Posted April 18, 2017 Or recursively: (defun extremum ( cmp lst ) ( (lambda ( foo ) (if (cdr lst) (foo (car lst) (extremum cmp (cdr lst))) (car lst))) (lambda ( a b ) (if (apply cmp (list a b)) a b)) ) ) Quote Link to comment Share on other sites More sharing options...
Grrr Posted April 18, 2017 Share Posted April 18, 2017 Thanks Lee! It looks quite useful, for example finding the nearest/furthest distance between point list and origin: _$ (extremum '(lambda ( a b ) (< (distance '(0. 0. 0.) a)(distance '(0. 0. 0.) b))) '((1.2 5.7 8.3) (9.4 2.6 0.3) (5.7 6.6 7.2))) (9.4 2.6 0.3) More expanded idea for usage would be constructing assoc list of (distN . enameN) to find the nearest/furthest entity. I see it as a combination between vl-some and vl-sort (like doing something like: (vl-some 'min lst) ). I'd say good job! Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 19, 2017 Share Posted April 19, 2017 Thanks Grrr. In practice however, the function could be optimised, as the result of the comparison function when applied to the current extremum would be known and would therefore not need to be recalculated for each item in the list (this is demonstrated by the 'zmx' & 'zmi' variables used in my earlier function which returns the points with minimum & maximum z-coordinate values). This optimisation is not possible when an arbitrary comparison function is used. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.