samifox Posted July 27, 2013 Share Posted July 27, 2013 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 Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 27, 2013 Share Posted July 27, 2013 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. Quote Link to comment Share on other sites More sharing options...
samifox Posted July 27, 2013 Author Share Posted July 27, 2013 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 ) Quote Link to comment Share on other sites More sharing options...
samifox Posted July 30, 2013 Author Share Posted July 30, 2013 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! Quote Link to comment Share on other sites More sharing options...
samifox Posted August 8, 2013 Author Share Posted August 8, 2013 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? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted August 9, 2013 Share Posted August 9, 2013 i couldn't understand what the "function" function does? Read this explanation. Quote Link to comment Share on other sites More sharing options...
samifox Posted July 12, 2014 Author Share Posted July 12, 2014 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 Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 12, 2014 Share Posted July 12, 2014 ........ Quote Link to comment Share on other sites More sharing options...
samifox Posted July 12, 2014 Author Share Posted July 12, 2014 Lee why dot product of prep always sums to 0? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 12, 2014 Share Posted July 12, 2014 Lee why dot product of prep always sums to 0? What is prep? Quote Link to comment Share on other sites More sharing options...
samifox Posted July 13, 2014 Author Share Posted July 13, 2014 Perpendicular Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 13, 2014 Share Posted July 13, 2014 Lee why dot product of prep perpendicular always sums to 0? Because the dot product of two vectors a & b is equivalent to: 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. Quote Link to comment Share on other sites More sharing options...
samifox Posted July 13, 2014 Author Share Posted July 13, 2014 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 Quote Link to comment Share on other sites More sharing options...
samifox Posted July 16, 2014 Author Share Posted July 16, 2014 Because the dot product of two vectors a & b is equivalent to: 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 Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 16, 2014 Share Posted July 16, 2014 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- ) ) 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.