aloy Posted April 29, 2014 Posted April 29, 2014 (edited) Hi everybody, I want to eliminate duplicates as well as other nearby points within a certain radius and a difference in height (fuzz). However the following code while eliminating the duplicate does not delete the nearby points which appear to be selected: (defun remove_dups (lst / out l) (setq h 0.2) (setq dx 0.5) (setq l (cdr lst)) (while lst (While (cdr l) (setq out (cons (car lst) out)) (if (and (equal (caddr (car lst)) (caddr (car l)) h) ( ) (progn (setq lst (vl-remove (car l) (cdr lst))) (princ (car l)) ) (Progn (setq lst (vl-remove (car lst) (cdr lst))) ) ) (setq l(cdr l)) ) ) (reverse out) ) The result I get are as follows: Command: (remove_dups ptlist) (3.0 2.0 1.4)(10.0 12.0 1.5)((2.0 3.0 1.2) (3.0 2.0 1.5) (3.0 2.0 1.4) (10.0 12.0 1.5)) Command: Command: Command: _vlide Command: Command: !ptlist ((2.0 3.0 1.2) (3.0 2.0 1.5) (2.0 3.0 1.2) (3.0 2.0 1.4) (10.0 12.0 1.5) (10.0 12.0 1.5)) As can be seen the point (3.0 2.0 1.4) has been selected but not deleted from the list. How can I make it work?. Thanking in advance. Aloy Edited April 29, 2014 by aloy Quote
marko_ribar Posted April 29, 2014 Posted April 29, 2014 (defun remove_dups ( lst / h dx out l ) (setq h 0.2) (setq dx 0.5) (setq l (cdr lst) out lst) (while lst (While (cdr l) (if (and (equal (caddr (car lst)) (caddr (car l)) h) (< (distance (car l) (car lst)) dx) ) (progn (setq lst (vl-remove (car l) (cdr lst))) (setq out (vl-remove (car l) out)) (princ (car l)) ) (progn (setq lst (vl-remove (car lst) (cdr lst))) ) ) (setq l (cdr l)) ) ) out ) (remove_dups '((2.0 3.0 1.2) (3.0 2.0 1.5) (2.0 3.0 1.2) (3.0 2.0 1.4) (10.0 12.0 1.5) (10.0 12.0 1.5))) (3.0 2.0 1.4)(10.0 12.0 1.5)((2.0 3.0 1.2) (3.0 2.0 1.5) (2.0 3.0 1.2)) Quote
aloy Posted April 29, 2014 Author Posted April 29, 2014 Marko, this is not the desired solution. The list 'out' which has been returned is not correct. Quote
Bhull1985 Posted April 29, 2014 Posted April 29, 2014 http://www.lee-mac.com/uniqueduplicate.html#listdupes Lee Mac's website. Here is his LM:ListDupes ;; List Duplicates - Lee Mac ;; Returns a list of items appearing more than once in a supplied list (defun LM:ListDupes ( l ) (if l (if (member (car l) (cdr l)) (cons (car l) (LM:ListDupes (vl-remove (car l) (cdr l)))) (LM:ListDupes (vl-remove (car l) (cdr l))) ) ) ) Worked for my needs. Quote
aloy Posted April 29, 2014 Author Posted April 29, 2014 bhull1985, Thanks for the reply. I have already seen it at the link given below: http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Removing-duplicates-from-a-list/td-p/4800513 What I am trying to do is to adopt DCBroad's version to suit my purpose. I want to be able to remove points within a given radius if the level difference are not much. These values are to be given from outside by the user in response to a 'getreal' statement or entered through a dialog. Regards, Quote
marko_ribar Posted April 29, 2014 Posted April 29, 2014 Aloy, what output should return out variable with given list ptlist? Quote
SLW210 Posted April 29, 2014 Posted April 29, 2014 aloy, Please read the Code Posting Guidelines and edit your post to include the Code in Code Tags. Quote
ymg3 Posted April 29, 2014 Posted April 29, 2014 You could sort your points on X and Y then remove adjacent duplicates. ;;****************************************************************************; ;; remduppts by Joe Burke ; ;; remove duplicate adjacent points from point list with fuzz factor ; ;; Modified by ymg to operate on 2d points ; ;;****************************************************************************; (defun remduppts (pl fuz / res p) (repeat (1- (length pl)) (setq p (car pl)) (if (> (distance (list (car p) (cadr p)) (cadr pl)) fuz) (setq res (cons p res)) ) (setq pl (cdr pl)) ) (reverse (cons (car pl) res)) ) ;;****************************************************************************; ;; sortptlst by ymg ; ;; ; ;; Sort a point list on X and Y Coordinates. ; ;;****************************************************************************; (defun sortptlst (pl) (vl-sort pl (function (lambda (a b) (or (< (car a) (car b)) (and (= (car a) (car b)) (< (cadr a) (cadr b))))))) ) Quote
aloy Posted April 29, 2014 Author Posted April 29, 2014 SLW210, Please bear with me. Actually I did exactly as stated in the code posting guide lines. It came out without being wrapped. I tried several times to correct it, but to no avail. How can I correct it now when the dialog does not allow it?. Similar thing happened once before also when a smiley came from nowhere and it would not go away. Perhaps I am not doing it in the correct way. Quote
aloy Posted April 29, 2014 Author Posted April 29, 2014 ymg, I need the z coordinate, though the triangulation is only handling x and y. Quote
aloy Posted April 29, 2014 Author Posted April 29, 2014 Marko, The output should look like this: (2.0 3.0 1.2) (3.0 2.0 1.4) (10.0 12.0 1.5) ((2.0 3.0 1.2) (3.0 2.0 1.5) (10.0 12.0 1.5)) The first three points are not attached to the variable 'out'. Regards Quote
ymg3 Posted April 29, 2014 Posted April 29, 2014 aloy, I know you need the Z coordinates. Right now we are deleting one point if x and y are within the fuzz 2d distance. As you delete with Joe's routine the Z remains there. The reason I am doing it this way is that duplicate points in x y are not allowed in triangulation. As it is you are keeping the last repeated one. ymg Quote
marko_ribar Posted April 29, 2014 Posted April 29, 2014 (setq ptlst '((2.0 3.0 1.2) (3.0 2.0 1.5) (2.0 3.0 1.2) (3.0 2.0 1.4) (10.0 12.0 1.5) (10.0 12.0 1.5))) ;;; (2.0 3.0 1.2) (3.0 2.0 1.4) (10.0 12.0 1.5) ((2.0 3.0 1.2) (3.0 2.0 1.5) (10.0 12.0 1.5)) ;;; (defun princ+rem_dups ( lst / remove_dups prelst suflst diff rlst dlst ) (defun remove_dups ( lst / h dx ) (setq h 0.2 dx 0.5) (if lst (cons (car lst) (remove_dups (vl-remove-if '(lambda ( x ) (and (equal (caddr (car lst)) (caddr x) h) (< (distance x (car lst)) dx) ) ) (cdr lst) ) ) ) ) ) (defun prelst ( lst el / f ) (vl-remove-if '(lambda ( a ) (or f (setq f (equal a el 1e-))) lst) ) (defun suflst ( lst el ) (cdr (vl-member-if '(lambda ( a ) (equal a el 1e-) lst)) ) (defun diff ( l1 l2 / el ) (setq el (car l2)) (setq l2 (cdr l2)) (setq l1 (append (prelst l1 el) (suflst l1 el))) (if l2 (diff l1 l2) l1) ) (setq rlst (remove_dups lst)) (setq dlst (diff lst rlst)) (foreach el dlst (princ el) ) rlst ) (princ+rem_dups ptlst) HTH, M.R. Quote
aloy Posted April 30, 2014 Author Posted April 30, 2014 Thanks Marko. It is a substantial job, which is very useful for me. Best regards, Aloy Quote
SLW210 Posted April 30, 2014 Posted April 30, 2014 SLW210,Please bear with me. Actually I did exactly as stated in the code posting guide lines. It came out without being wrapped. I tried several times to correct it, but to no avail. How can I correct it now when the dialog does not allow it?. Similar thing happened once before also when a smiley came from nowhere and it would not go away. Perhaps I am not doing it in the correct way. Select "Go Advanced" after you select the "Edit Post" then the # will be available. You can also just manually insert . (no space between the E and ]) Quote
marko_ribar Posted April 30, 2014 Posted April 30, 2014 (no space between the E and ]) SLW210, [noparse][noparse] Your code ... [/noparse][/noparse] M.R. Quote
aloy Posted April 30, 2014 Author Posted April 30, 2014 (edited) ymg,Marko This will not do( at#8. Where is the fuzz for level difference for the nearby points?. I suppose we are trying to arrive at the solution of Civ3D which they have done with a dialog and it appears Marko has already done it at #13. I will try his solution for a large list later. Regards, Aloy Edited May 1, 2014 by aloy Quote
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.