Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Looking for a lisp that measures the vertical distance between a vertice and a horizontal (x axis) line.

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
david_norrisHJ9DY
381 Views, 12 Replies

Looking for a lisp that measures the vertical distance between a vertice and a horizontal (x axis) line.

I have a graph. And, at the moment, I need to measure the vertical distance between each polyline vertice and the x axis and then put the result above this vertice. I have attached a picture with an example. Note that this graph has a scale 1/50 so whatever the distance is, I need to divide by 50

I already made a lisp where I can input two points and then it will generate the distance. But I need to do this for each vertice and I have hundreds to do. Here is the lisp that I have cobbled together:

(defun c:railmeasurement (/ p1 p2 p3 distance resultText sign)
(setq p1 (getpoint "\nSpecify first point: "))

; Check if the user canceled the first point selection
(if (null p1)
(progn
(prompt "\nCommand canceled.")
(exit)
)
)

(setq p2 (getpoint p1 "\nSpecify next point: "))

(if (and p2)
(progn
; Calculate the distance, multiply by 2, and divide by 100
(setq distance (/ (* 2 (distance p1 p2)) 100))

; Format the result text to two decimal places
(setq resultText (rtos distance 2))

; Determine the sign based on Y-coordinates
(if (< (cadr p1) (cadr p2))
(setq sign "-") ; Negative sign
(setq sign "+") ; Positive sign
)

; Combine the sign and result text
(setq resultText (strcat sign resultText))

; Get the location for the text
(setq p3 (getpoint "\nSpecify text location: "))

; Create an MTEXT entity with the result and set rotation to 90 degrees
(entmakex
(list
'(0 . "MTEXT")
'(100 . "AcDbEntity")
'(100 . "AcDbMText")
(cons 10 p3)
(cons 1 resultText)
(cons 50 77) ; Set rotation to 90 degrees (along Y-axis)
)
)
)
)
(princ)
)


Ideally, what I would like is something where I simply select the data line and then select the x axis and then the vertical distance between each vertice and the x axis is measured and each measurement is inputted into the the drawing a text above the respective vertice. I have put an image as well to show what I mean. Thanks in advance!

Labels (2)
12 REPLIES 12
Message 2 of 13

Post a dwg with the graph and a few examples of output.

Message 3 of 13

I have posted a dwg with a sample graph. The LISP that I have made (railmeasurement), I just have endpoint and perpendicular snap on. So then for each vertice I select first the vertice on the graph. Followed by the perpendicular distance to the x axis. 

This then prompts me to place text somewhere and I usually turn off my snaps and place the result above the vertice. If you need anything else let me know.

Message 4 of 13

How is this working for you? 

 

(setq distance (/ (* 2 (distance p1 p2)) 100))

 

Variable and function of the same name? That cannot be....

 

Message 5 of 13

I wouldn't call myself an expert, I have just tried to put different things online together to make something. So in short, I don't know but it seems to work for me. 

I have changed the variable name to "dist" and also changed it here:

 

; Format the result text to two decimal places
(setq resultText (rtos dist 2))

 

Still working fine.

Message 6 of 13

That's only because the distance function is used BEFORE the variable. When some value is stored in that variable, that moment is the function definition replaced with this value and the function can't be used anymore.

 

(vl-load-com)

(defun c:RailMea ( / e p o s v x y)

  (if (and (setq e (car (entsel "\nSelect polyline: ")))
	   (setq p (getpoint "\nBaselevel: "))
	   (setq o (getdist "\nText offset: "))
	   (setq s (getdist "\nScale: "))
	   )
    (foreach v (mapcar 'cdr (vl-remove-if '(lambda (x) (/= (car x) 10)) (entget e)))
      (setq x (* s (- (cadr v) (cadr p)))
	    y (strcat (if (< x 0) "" "+") (rtos x 2 2)))
      (entmakex (list '(0 . "TEXT") '(40 . 1.5) '(73 . 2) (cons 50 (/ pi 2))
		      (cons 10 (polar v (/ pi 2) o))
		      (cons 11 (polar v (/ pi 2) o))
		      (cons 1 y)))))
  (princ)
  )
 

 

Message 7 of 13

yet another one

(defun c:add_deviations (/ a_graph zero_x_line zero_level deviation deviation_string alignment_point alignment)
	(setq a_graph (car (entsel "\nPick a graph: "))
		  zero_x_line (car (entsel "\nPick a zero level X line: "))
	)
	(mapcar '(lambda (vertex)
				(progn
					(if (member (cdr (assoc 0 (entget zero_x_line))) '("LINE" "LWPOLYLINE"))								
						(setq zero_level (caddr (assoc 10 (entget zero_x_line)))
						) 
					)
					(setq deviation (/ (- (cadr vertex) zero_level) 50.0))
					(cond
						(
							(or
								(zerop deviation)
								(not (minusp deviation))
							)
								(setq deviation_string (strcat "+" (rtos deviation 2 2))
									  alignment_point (vlax-3d-point (list (car vertex) (+ (cadr vertex) (getvar 'textsize))))
									  alignment 9 

								) 
						)
						(
							t
								(setq deviation_string (rtos deviation 2 2)
									  alignment_point (vlax-3d-point (list (car vertex) (- (cadr vertex) (getvar 'textsize))))
									  alignment 11
								) 

						)
					)
					(setq deviation_text (vla-addtext (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
										 			  deviation_string
										 			  alignment_point
										 			  (getvar 'textsize)
								 		 )
					)
					(vla-put-rotation deviation_text (* 0.5 pi)) 
					(vla-put-color deviation_text 7)
					(vla-put-alignment deviation_text alignment)
					(vla-put-textalignmentpoint deviation_text alignment_point)
				)
			)
			(mapcar 'cdr (vl-remove-if-not '(lambda (group) (= 10 (car group))) (entget a_graph)))
	)
	(princ)
)
Message 8 of 13

That can certainly be done for a single path Polyline.  The above-vs.-below positioning may not be something a routine can figure out, so you may need to Move some of the results when you have multiple paths.

 

Usage would presumably be to select the horizontal zero-level reference Line and the "CHASSIS"-Layer Polyline.  Is there more to it than that?  Would the Text height and Style and Layer always be the same?  Etc.

 

Why Mtext?  [There's no reason I can think of that they shouldn't just be plain Text, like all the "coord"-Layer labels.]

 

[The singular is vertex.]

Kent Cooper, AIA
Message 9 of 13

Thanks for the advice and thanks for your lisp!

I am trying it out and at the moment, not quite getting it.. I am getting a stack overflow error

; ----- Error around expression -----
; (CONS 1 X)
;
; error : Unknown Error in Lisp or CAD system or 'Stack Overflow'

To be clear what I am doing is selcting the polyline of the graph, selecting the basepoint I suppose this can be any point on the x axis.

Text offset, I just measure 4mm above the vertice and then scale, I am just inputting 50. I am not sure what's going wrong, sorry to be a pain

Message 10 of 13

It's not necessary for it to be mtext. It's just a personal habit for me to use that. Text height and style would always be the same. There's nothing more to it than that.

Message 11 of 13

Ok, try the updated code..., close are reopen dwg. But frankly don't really know why it works for me but not for you.

 

The scale factor should be 0.02 (as 1/50)

Message 12 of 13


@david_norrisHJ9DY wrote:

.... Text height and style would always be the same. There's nothing more to it than that.


Here's another way:

(defun C:Elev50 (/ ref refY path n ver)
  (setvar 'textstyle "ARIAL") (setvar 'textsize 1.5)
  (if
    (and
      (setq ref (car (entsel "\nZero Reference Line: ")))
      (setq
        refY (caddr (assoc 10 (entget ref)))
        path (car (entsel "\nPath Polyline to mark: "))
      )
    )
    (repeat (setq n (1+ (fix (vlax-curve-getEndParam path))))
      (setq
        ver (vlax-curve-getPointAtParam path (setq n (1- n)))
        offs (- (cadr ver) refY)
      )
      (command "_.text" "_ml" "_non" (polar ver (/ pi 2) 2) "" "300"
        (strcat (if (> offs 0) "+" "") (rtos (/ offs 50) 2 2))
      )
    )
  ) 
  (prin1)
)

It is based on the sample drawing's having the non-default settings of angles increasing in the clockwise direction, and in gradians.

It puts the Text always above the path [see my previous Reply], and on the current Layer.

It could be made to check whether you picked the right kinds of things, that the Polyline is open, set a Layer, save current values for Text size and Style and Layer to reset afterwards, wrap Undo begin/end around it all, etc.

Kent Cooper, AIA
Message 13 of 13

This is exactly what I needed! Thank you so much!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Customer Advisory Groups


Autodesk Design & Make Report