Jump to content

need help to write mapcar to solve a problem


samifox

Recommended Posts

hi

the idea of the code is the detect 90 degrees corners in a polyline selection set. so after detecting paier of vertices thae form a corner i want to store tham in a database

 

since every pair of vertices is stored as a list inside a database list, i need to access nasted lists and prevent duplicates.

 

how can i translate the red lines to efficient mapcar function?

;;;--------------------------------------------------------------------;
;;;  Function: createCornerVertexList                                  ;
;;;--------------------------------------------------------------------;
;;;  Description: analyzes a given 2d vertices list by comparing every ;
;;;               pair of vertices for all possible distances and      ;
;;;               angles, and create a new list of 2d vertices only if ;
;;;               they form 90 degrees corner.
;;;               NOTE : every pair of vertices compose an entry
;;;  Argument   : lst - 2d vertices list                               ;
;;;--------------------------------------------------------------------;
;;;                             anglein radianc but for comprance      ;
;;;                             porpuses,there is a need for the       ;
;;;                             (<) and (>)functionsthe get 0 or       ;
;;;                             (* pi 2) as arguments                  ;
;;;               MAXDISTANCE - the maximum distance allowed between 2 ;
;;;                             pointsto be listed as a corner pair    ;
;;;                             vertices.                              ;
;;;               MINDISTANCE - the minimum distance allowed between 2 ;
;;;                             vertecis  to be listed as a corner     ;
;;;                             vertices.                              ;
;;;                             notice that this constant prevent      ;
;;;                             vertex to be compared to it self and   ;
;;;                             other verticesin a door or a window    ;
;;;                             posts.                                 ;
       
(defun MMDPOLY1:createCornerVertexList(lst / ma fe col corners )
(setq	fe 0 ma 0)
(while (< ma (length lst))
	(while (< fe (length lst))
		(if(MMDPOLY.isCornerForm (nth ma lst)(nth fe lst) MINDISTANCE MAXDISTANCE)
		  (progn

		   [color="red"][b] ;_if [corners] is empty
		    ;_if (nth ma lst) or (nth fe lst) are not member of any of [/b][/color]the sublists
		      (setq database (cons (list (nth ma lst)(nth fe lst))corners))	   
	       );_if
       );_if

		  
  
	(setq fe (1+ fe))	  
               );_while (fe	
 (setq ma (1+ ma))(setq fe 0)
) ;_while (ma

)

 

Thanks

Shay

Link to comment
Share on other sites

Perhaps consider the following function:

(defun getcornervertices ( lst )
   (apply 'append
       (mapcar
           (function
               (lambda ( a b c )
                   (if (perp-p (mapcar '- a b) (mapcar '- c b)) (list b))
               )
           )
           (cons (last lst) lst) lst (append (cdr lst) (list (car lst)))
       )
   )
)

(defun perp-p ( u v )
   (equal 0.0 (apply '+ (mapcar '* u v)) 1e-
)

The above function will accept a list of ordered coplanar vertices and, for each vertex, will test the perpendicularity of the vectors joining the previous and next vertex, and will return the corner vertex if the dot product of these vectors is zero (i.e. the vectors are perpendicular).

 

Assumes a closed vertex set, but could easily be modified to process open sets.

Link to comment
Share on other sites

interesthing...LEE

i've write this, do you think i need to replace this code with yours?

 

(defun MMDPOLY1:createCornerVertexList(lst / ma fe col corners )
(setq	fe 0 ma 0)
(while (< ma (length lst))
	(while (< fe (length lst))
		(if(MMDPOLY.isCornerForm (nth ma lst)(nth fe lst) MINDISTANCE MAXDISTANCE)
		  

		    (if (eq database nil)
		      (setq database(cons (list (nth ma lst)(nth fe lst))database))
		        (progn
		            (foreach e database 
			       (if (not (or  (member (nth fe lst)e)(member (nth ma lst)e)))
		                   (setq database(cons (list (nth ma lst)(nth fe lst))database))
				 );_if
			      );_foreach
			  );_progn
	       );_if
			  
       );_if

		  
  
	(setq fe (1+ fe))	  
               );_while (fe	
 (setq ma (1+ ma))(setq fe 0)
) ;_while (ma

)

Link to comment
Share on other sites

Perhaps consider the following function:

(defun getcornervertices ( lst )
   (apply 'append
       (mapcar
           (function
               (lambda ( a b c )
                   (if (perp-p (mapcar '- a b) (mapcar '- c b)) (list b))
               )
           )
           (cons (last lst) lst) lst (append (cdr lst) (list (car lst)))
       )
   )
)

(defun perp-p ( u v )
   (equal 0.0 (apply '+ (mapcar '* u v)) 1e-
)

The above function will accept a list of ordered coplanar vertices and, for each vertex, will test the perpendicularity of the vectors joining the previous and next vertex, and will return the corner vertex if the dot product of these vectors is zero (i.e. the vectors are perpendicular).

 

Assumes a closed vertex set, but could easily be modified to process open sets.

 

Sorry LEE

 

i was reading your reply from my mobile on the go..and didnt notice you gave me a "rea"l solution to find complaner vertices.

 

i really need to learn it

 

but as the same

milion of thankses!

Link to comment
Share on other sites

  • 2 weeks later...
Perhaps consider the following function:

(defun getcornervertices ( lst )
   (apply 'append
       (mapcar
           (function
               (lambda ( a b c )
                   (if (perp-p (mapcar '- a b) (mapcar '- c b)) (list b))
               )
           )
           (cons (last lst) lst) lst (append (cdr lst) (list (car lst)))
       )
   )
)

(defun perp-p ( u v )
   (equal 0.0 (apply '+ (mapcar '* u v)) 1e-
)

The above function will accept a list of ordered coplanar vertices and, for each vertex, will test the perpendicularity of the vectors joining the previous and next vertex, and will return the corner vertex if the dot product of these vectors is zero (i.e. the vectors are perpendicular).

 

Assumes a closed vertex set, but could easily be modified to process open sets.

 

i couldn't understand what the "function" function does?

Link to comment
Share on other sites

  • 11 months later...
Perhaps consider the following function:

(defun getcornervertices ( lst )
   (apply 'append
       (mapcar
           (function
               (lambda ( a b c )
                   (if (perp-p (mapcar '- a b) (mapcar '- c b)) (list b))
               )
           )
           (cons (last lst) lst) lst (append (cdr lst) (list (car lst)))
       )
   )
)

(defun perp-p ( u v )
   (equal 0.0 (apply '+ (mapcar '* u v)) 1e-
)

The above function will accept a list of ordered coplanar vertices and, for each vertex, will test the perpendicularity of the vectors joining the previous and next vertex, and will return the corner vertex if the dot product of these vectors is zero (i.e. the vectors are perpendicular).

 

Assumes a closed vertex set, but could easily be modified to process open sets.

 

Lee,

only now, one year later, i realize how smart was your solution to find perpendicularity points

Thanks LEE

Link to comment
Share on other sites

Lee why dot product of prep perpendicular always sums to 0?

 

Because the dot product of two vectors a & b is equivalent to:

 

png.latex?\dpi{150}&space;\large&space;a&space;\cdot&space;b&space;=&space;|a|&space;|b|&space;cos&space;\theta

 

Where θ is the angle between the two vectors.

 

Hence the dot product of perpendicular vectors is zero because cos(π/2) & cos (3π/2) are both equal to zero.

 

Therefore, it remains to show that the above equivalence is true - a proof of which may be found here.

Link to comment
Share on other sites

Perhaps consider the following function:

(defun getcornervertices ( lst )
   (apply 'append
       (mapcar
           (function
               (lambda ( a b c )
                   (if (perp-p (mapcar '- a b) (mapcar '- c b)) (list b))
               )
           )
           (cons (last lst) lst) lst (append (cdr lst) (list (car lst)))
       )
   )
)

(defun perp-p ( u v )
   (equal 0.0 (apply '+ (mapcar '* u v)) 1e-
)

The above function will accept a list of ordered coplanar vertices and, for each vertex, will test the perpendicularity of the vectors joining the previous and next vertex, and will return the corner vertex if the dot product of these vectors is zero (i.e. the vectors are perpendicular).

 

Assumes a closed vertex set, but could easily be modified to process open sets.

 

Hi LEE

 

i made some researches about your function, let me know if i got it

 

the argument list is being divided by 3 in order to set different initial place for variables a,b,c.

 

than in each iteration 2 vectors from different origin point are sent to be tested for perpendicularity, only those that sum dot product equal to 0 are being registered in the returned list.

 

what need to be modified for open sets?

 

Shay

Link to comment
Share on other sites

Because the dot product of two vectors a & b is equivalent to:

 

png.latex?\dpi{150}&space;\large&space;a&space;\cdot&space;b&space;=&space;|a|&space;|b|&space;cos&space;\theta

 

Where θ is the angle between the two vectors.

 

Hence the dot product of perpendicular vectors is zero because cos(π/2) & cos (3π/2) are both equal to zero.

 

Therefore, it remains to show that the above equivalence is true - a proof of which may be found here.

Thanks Lee

 

i use this code to find 2 perpendicular points . but it will only work with 90 degrees angles. if the ucs is rotated it wont work,

is there any math megic i can do?

 

(defun isOrtho(pt1 pt2)
 (or
    (equal (car pt1)(car pt2) 1e-
    (equal (cdr pt1)(cdr pt2) 1e-
 )
)

 

Thanks

Shay

Link to comment
Share on other sites

If you are working with WCS points, translate such points to the UCS, e.g.:

(defun ortho-p ( p q )
   (setq p (trans p 0 1)
         q (trans q 0 1)
   )
   (or (equal (car  p) (car  q) 1e-
       (equal (cadr p) (cadr q) 1e-
   )
)

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...