Jump to content

Function to find the dimensions of the flat figure through the points of the vertices


Jéferson Gustavo

Recommended Posts

Hello everyone, I would like your help to create a function. I have a list with 4 points (referring to the vertices of a flat figure), this figure can be a rectangle, parallelogram or trapezoid, I need to check if this figure has two horizontal lines (with the same y), if it does, the function will return me the dimension of the upper line, the lower line, the two diagonals and the height of the figure.
For example:
'((0 0 0) (7 0 0) (5 3 0) (1 3 0))
The function will return:
(4 7 6,7082 58310 3)
Thank you in advance.

Link to comment
Share on other sites

(defun fnc (lst / dw tol unq up)
    (setq tol 1e-7)
    (if
	(and
	    (= (length lst) 4)
	    (= (length (setq unq (LM:UniqueFuzz (mapcar 'cadr lst) tol))) 2)
	    (=
		(length
		    (setq up
			     (vl-remove-if-not
				 '(lambda (x)
				      (equal
					  (cadr x)
					  (apply 'max unq)
					  tol
				      )
				  )
				 lst
			     )
		    )
		)
		2
	    )
	    (=
		(length
		    (setq dw
			     (vl-remove-if-not
				 '(lambda (x)
				      (equal
					  (cadr x)
					  (apply 'min unq)
					  tol
				      )
				  )
				 lst
			     )
		    )
		)
		2
	    )
	)
	(append
	    (list
		(apply 'distance up)
		(apply 'distance dw)
	    )
	    (mapcar 'distance up (if (equal (apply 'angle up) (apply 'angle dw)) (reverse dw) dw))
	    (list (abs (apply '- unq)))
	)
    )
)

;; Unique with Fuzz  -  Lee Mac
;; Returns a list with all elements considered duplicate to
;; a given tolerance removed.

(defun LM:UniqueFuzz ( l f / x r )
    (while l
        (setq x (car l)
              l (vl-remove-if (function (lambda ( y ) (equal x y f))) (cdr l))
              r (cons x r)
        )
    )
    (reverse r)
)

 

Edited by Jonathan Handojo
  • Thanks 1
Link to comment
Share on other sites

12 hours ago, Jonathan Handojo said:

(defun fnc (lst / dw tol unq up)
    (setq tol 1e-7)
    (if
	(and
	    (= (length lst) 4)
	    (= (length (setq unq (LM:UniqueFuzz (mapcar 'cadr lst) tol))) 2)
	    (=
		(length
		    (setq up
			     (vl-remove-if-not
				 '(lambda (x)
				      (equal
					  (cadr x)
					  (apply 'max unq)
					  tol
				      )
				  )
				 lst
			     )
		    )
		)
		2
	    )
	    (=
		(length
		    (setq dw
			     (vl-remove-if-not
				 '(lambda (x)
				      (equal
					  (cadr x)
					  (apply 'min unq)
					  tol
				      )
				  )
				 lst
			     )
		    )
		)
		2
	    )
	)
	(append
	    (list
		(apply 'distance up)
		(apply 'distance dw)
	    )
	    (mapcar 'distance up (if (equal (apply 'angle up) (apply 'angle dw)) (reverse dw) dw))
	    (list (abs (apply '- unq)))
	)
    )
)

;; Unique with Fuzz  -  Lee Mac
;; Returns a list with all elements considered duplicate to
;; a given tolerance removed.

(defun LM:UniqueFuzz ( l f / x r )
    (while l
        (setq x (car l)
              l (vl-remove-if (function (lambda ( y ) (equal x y f))) (cdr l))
              r (cons x r)
        )
    )
    (reverse r)
)

 

Very good, it worked perfectly. thank you so much.

Out of curiosity, could you explain to me what is happening on the line?

(mapcar 'distance up (if (equal (apply' angle up) (apply 'angle dw)) (reverse dw) dw))

I only know how to use mapcar in conjunction with lambda function  and this is new to me.

Link to comment
Share on other sites

'up' is a list of the two points entailing the upper horizontal line: ((5 3 0) (1 3 0))

'dw' is a list of the two points entailing the lower horizontal line: ((0 0 0) (7 0 0))

 

mapcar works as such:

 

(mapcar <function_accepting_n_arguments> <list1> <list2> ... <listn>)

 

And it will return a list resulting from the evaluation of the function as a result of passing its elements into the function... meaning:

 

The first result of mapcar in the list will be by passing:

The first item of list1 denoting the first argument of the function,

The first item of list2 denoting the second argument of the function,

The first item of listn denoting the nth argument of the function.

 

Then the second result of mapcar in the list will be by passing:

The second item of list1 denoting the first argument of the function,

The second item of list2 denoting the second argument of the function,

The second item of listn denoting the nth argument of the function.

 

This process continues until whichever's lists run out first, and evaluation stops. Ultimately, the length of the returned mapcar list will be the length of the shortest list from list1 to listn, so if any one of the lists supplied is nilmapcar returns nil

 

That said... the function distance accepts two points, so that means following the "(mapcar 'distance" should accept two lists... which is up and dw. Writing

(mapcar
    'distance 
    '((5 3 0) (1 3 0)) 
    '((0 0 0) (7 0 0))
)

is the equivalent to:

(list
    (distance '(5 3 0) '(0 0 0))
    (distance '(1 3 0) '(7 0 0))
)

 

Lambda is basically a user defined function. You write it in the form of '(lambda (a b c ...) <expressions>) and then following a few more lists equaling the number of arguments in the lambda function. The above and below mean exactly the same thing:

 

(mapcar
    '(lambda (a b)
	 (distance a b)
     )
    '((0 0 0) (7 0 0))
    '((5 3 0) (1 3 0))
)

 

Now, depending on whether the direction of the upper and lower lines are in the same direction or not (by using the (angle) function), that's the purpose of the reverse function to make sure that the correct diagonal is returned instead.

 

In the end, the above returns '(5.83095 6.7082)

  • Thanks 2
Link to comment
Share on other sites

On 12/14/2020 at 9:06 PM, Jonathan Handojo said:

'up' is a list of the two points entailing the upper horizontal line: ((5 3 0) (1 3 0))

'dw' is a list of the two points entailing the lower horizontal line: ((0 0 0) (7 0 0))

 

mapcar works as such:

 

(mapcar <function_accepting_n_arguments> <list1> <list2> ... <listn>)

 

And it will return a list resulting from the evaluation of the function as a result of passing its elements into the function... meaning:

 

The first result of mapcar in the list will be by passing:

The first item of list1 denoting the first argument of the function,

The first item of list2 denoting the second argument of the function,

The first item of listn denoting the nth argument of the function.

 

Then the second result of mapcar in the list will be by passing:

The second item of list1 denoting the first argument of the function,

The second item of list2 denoting the second argument of the function,

The second item of listn denoting the nth argument of the function.

 

This process continues until whichever's lists run out first, and evaluation stops. Ultimately, the length of the returned mapcar list will be the length of the shortest list from list1 to listn, so if any one of the lists supplied is nilmapcar returns nil

 

That said... the function distance accepts two points, so that means following the "(mapcar 'distance" should accept two lists... which is up and dw. Writing


(mapcar
    'distance 
    '((5 3 0) (1 3 0)) 
    '((0 0 0) (7 0 0))
)

is the equivalent to:


(list
    (distance '(5 3 0) '(0 0 0))
    (distance '(1 3 0) '(7 0 0))
)

 

Lambda is basically a user defined function. You write it in the form of '(lambda (a b c ...) <expressions>) and then following a few more lists equaling the number of arguments in the lambda function. The above and below mean exactly the same thing:

 


(mapcar
    '(lambda (a b)
	 (distance a b)
     )
    '((0 0 0) (7 0 0))
    '((5 3 0) (1 3 0))
)

 

Now, depending on whether the direction of the upper and lower lines are in the same direction or not (by using the (angle) function), that's the purpose of the reverse function to make sure that the correct diagonal is returned instead.

 

In the end, the above returns '(5.83095 6.7082)

With that explanation it was very clear now, thank you very much!

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...