Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations GregLocock on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

An Autolisp Lesson part 3 2

Status
Not open for further replies.

shadow

Computer
Mar 1, 2001
321
Wow just relized how many posts was in An Autolisp Lesson part 2's thread

any way
a recap
(setq linelength (rtos linelength 4 8))
RTOS converts length into text string thats what it does

Then we learned about getting the drawing name and path using the following

setq MYPATH (getvar "dwgprefix"))

I do not recall if it comes with a slash or without.
If slash missing, add it thus:
(setq MYPATH (strcat MYPATH "/"))
try on command line till it works right - "/" or "\\" or else.
Then attach dwgname to this path.
(setq MYPATH (strcat MYPATH (getvar "dwgname")))

and how to use the prin(t)(c)(1) functions

(princ ", " f) ;puts a comma and a space on the same line
(princ "\n, " f) ;the same on a new line - never needed I suppose but to illustrate the use of \n

(print ", " f) ; the same on a new line but with quotations

(prin1 ", " f) ; used to do something - I forgot.


then we leearned about how to remove the extention from the drawing name to use as a name for a txt file using the following

(setq DWGNAME (getvar "DWGNAME"))
(setq NAME (substr DWGNAME 1 (- (strlen DWGNAME) 4)))

& we learned that possibly lisp cannot read the clipboard


now another ???

Conditional Rotation
back to the linelength.lsp
how do you go about telling the lisp to get the rotation angle of the line and if it is an angle between0-45 degrees then textangle should be at an angle opposit of that angle so inother words if the line comes out 45d then the text should be -45d or 315d
i would assume the latter would end up a variable that would be placed in the area where the followig is


(COMMAND "_.text" "_j" "mc"midpoint angledegree linelength)

with the variable txtang being the rotation angle for the text to be inserted right

So i guess the best place to start would be explaining what is being done on the following lines

;10 get the inclination
(setq angleradian (angle starting ending))
(setq angledegree (/ (* angleradian 180. 7. ) 22.))

i understand the first its getting the angle between the starting and ending poins collected in the selection set but what does the other do
if everyone helps everybody the world will be a better place
 
Replies continue below

Recommended for you

Now going back i want to make sure i have this right do i add the (princ "\n, " f) to the code so that it doesnt use " and is ,delimeted or do i edit one of the other prin functions shown below

(princ "\n, " f)
(prin1 hand_str f)
(print hand_str f) if everyone helps everybody the world will be a better place
 
also another ?
Does this line deal with the entity handle is that why whom ever called the var hand

(setq hand (cdr (assoc 5 entity))) if everyone helps everybody the world will be a better place
 
tigrek

what does the "W" mean in this portion of the lsp

(setq f (open file "w")) if everyone helps everybody the world will be a better place
 
tigrek here found this dealing with prin1

\e escape
\n New Line
\r return
\t tab
\007 beep
\nnn character whos octal code is nnn

so i need to prevent 2 things from appearing in my text file " and ()sets cause as it is now i get something like this

("5C17" . "72'-11 3/8\"-4'")
if everyone helps everybody the world will be a better place
 
Ok lets take a stab at the whole list of things here.

From the top......

To determine the angle of a line, you need to extract the beginning and ending points. Thus the later code you posted. The beginning point of a line is DXF group code 10 and the end of the line is DXF group code 11. Thus to determine the angel of a line you would do:

(setq angleradian (angle startpoint endpoint)

remembering that startpoint and endpoint are variables that are holding group 10 and group 11 respectively.

group code 5 is the handle of an entity. You can use the handle of an entity to retrieve the entity data list by using the HANDENT function. Check this out in the online help for AutoLisp.

The "w" in (open file "w") stands for "write" When a file is opened in this manner you can only write data to the file. Other ways to open a file are:

Append data to the file
(open file "a")

Read the data in the file
(open file "r")

remember that the "w" "a" and "r" must be lower case or the file will fail to open.

Also keep in mind that you must always assign the return value of a open command to a variable otherwise you will not be able to operate on the file or close it.

Lisp tutorial anyone?
 
in the previous lisp teh one that is called linelength.lsp how come if say a line is 26'0" that the 0" is not displayed how could i get around this if everyone helps everybody the world will be a better place
 
hmmm well i have come to this conclusion seeing as doing a list on a line displays me the way i want seen in the lable that its gotta have something to do with the point at which the lsp gets the linelength

(setq linelength (Distance starting ending))

cause in the line where it actually uses rtos to set the text useing the string info it drops the 0" if it has it but why does it do this if everyone helps everybody the world will be a better place
 
I cannot answer the last question unless the author of the program specifically wanted to show feet only with no inches. To show the entire string representation of a distance, you need to set the precision to 8 in the RTOS function. Example:

(rtos 312.375 4 0) will return
26'-0"
while
(rtos 312.375 4 8) will return
26'-0 3/8"

The problem could be in the program, I have not seen the entire lisp so I cannot
 
Yess ya have but here it is as i have edited it

; I wrote this code today for Shadow - would appreciate debug feedback from all interested

; extensively commented to serve as tutorial.
; sure all kinds of other things can be added - your homework
;all text is placed on the current layer - you may modify to put it on the layer of the line.

;To label lines with lengths


; TO WRITING YOUR OWN LISP CODE - OR MODIFY THIS
;1- open Acad2000, a new drawing, put some lines into it, save as linelength.dwg

;2- type VLIDE on command line
;3- in VLIDE window, type a title like this, save as linelength.lsp
; save where linelength.dwg is. Makes easy to load for now.
; later, after all tests are OK, save under Acad2000/support
;4- be clear about problem definition:
;to put a text along every selected line, giving the line length in ft-inch

;start the new command
(defun C:Linelength()
;5- select lines by any or all methods
(setq SUZY (ssget '((0 . "LINE"))))
;6- number of lines selected
(setq LENSUZY (sslength SUZY))
(setq COUNTER 0)
;7- loop through the set of selected lines
(while (setq EDNA (ssname SUZY COUNTER))
(setq ED (entget EDNA))
;8- get startpoint coordinates
(setq starting (dxf 10 ED))

;9- get endpoint coordinates
(setq ending (dxf 11 ED))

;10 get the inclination
(setq angleradian (angle starting ending))
(setq angledegree (/ (* angleradian 180. 7. ) 22.))
;11 calculate line length in drawing units
(setq linelength (Distance starting ending))
(setq textheight (getvar "TEXTSIZE"))
;12 estimate the midpoint coordinates
(setq midpoint (polar starting angleradian (/ linelength 2)))
;lets put text a textsize away from the line
;replace textheight in the following line with other distances, if you wish,
(setq distfromline textheight)
(setq midpoint (polar midpoint (+ angleradian (/ 22. 14)) distfromline))
;13 convert length into text string thats what RTOS does
(setq linelength (rtos linelength 4 4))

;14 insert linelength as text
;sure text is upside down for some lines
;this is the homework for you - get it top side up
;I personally prefer it as is, because reveals which way the start/end of line is.
(setq oldSnap (getvar "osmode"))
(setvar "osmode" 0)

(COMMAND "_.text" "_j" "mc"midpoint angledegree linelength)
(setvar "osmode" oldSnap)

;increase the counter - otherwise no way out of the Nexus
(setq COUNTER (+ 1 COUNTER))
;temp - this is just for debugging
(princ "\nLine ")(princ COUNTER)
(princ "\nstart ")(princ starting)(princ " end ")(princ ending)
(princ " radian ")(princ angleradian)
(princ " degree ")(princ angledegree)
(princ " length ")(princ linelength)


);end while

(princ)
);end defun

;----The only other function used above
;called like (dxf groupcode ED)
;ED being complete list of entity named EDNA
;returns the entity info corresponding to the group code
; (dxf 10 ED) returns list of startpoint coordinates
; (dxf 11 ED) returns list of endpoint coordinates
(defun dxf (n ed) (cdr (assoc n ed)))
;----------------- if everyone helps everybody the world will be a better place
 
I see a couple of minor flaws in the code posted. The problem is in the convertion of the radians to degrees. When you change through the method shown you get inaccurate values. You should use the following instead of:
(setq angledegree (/ (* angleradian 180. 7. ) 22.))
use
(setq angledegree (distof (angtos angleradian)))

angtos returns a string value representing degrees from a radian angle while distof converts a numeric string to a real number.

and
(setq midpoint (polar midpoint (+ angleradian (/ 22. 14)) distfromline))

should be

(setq midpoint (polar midpoint (+ angleradian (* pi(/ 90.0 180)))distfromline))


The system variable PI is equivalent to PI ie 3.14... and since the convertion of degrees to radians is angle/180 multiplied times PI , we get an accurate convertion from degrees to radians, hence

(* PI (/ angle 180))

in fact I have created a function to convert degree values to radians especially for use in the polar function called DTR using the syntax above, the function is:

(defun dtr ( a )
(* pi (/ a 180))
)

The function call is:
(DTR degrees_as_real)

so..
(dtr 90) will return
1.5708

The problem you are facing with the line length may be a problem with a units setting on your system, although the units are explicitly set in the RTOS function call. aside from the angles being slightly skewed the function worked flawlessly.

Cheers.....
 
striker
the following doesnt work because

(setq angledegree (distof (angtos angleradian)))

angtos converts angleradian into a text string which is not what the lsp is looking for its looking for an angle

if everyone helps everybody the world will be a better place
 
the following doesnt work because

(setq angledegree (distof (angtos angleradian)))

angtos converts angleradian into a text string which is not what the lsp is looking for its looking for an angle

Precicely the point... Remember I said that the angtos function converts the value to a string which represents degrees, then the distof function converts the string to a real number similar to what I will show here:

Suppose the value of angleradian is 90 degrees in radians which is roughly equal to 1.5708
(setq angleradian 1.5708)
Now we need to convert to a degree angle which should end up being 90.0 Lets do the following
(setq intermediate_value (angtos angleradian))

Now intermediate_value is set to "90.0" which is no good because we need a real for the polar function to add exactly 90 degrees so what we do is....
(setq degrees (distof intermediate_value))

now degrees is set to 90.0 a real number instead of a string, now when you need to say 90.0 degrees you can be exact with a degree to radian adjustment by using the actual value of radians instead of an approximation. Example:

(* pi (/ degrees 180.0))

This function returns 1.5708

What good you say since we actually started with 1.5708, well the text function uses degrees as a real and if we use the original function, you will end up with a value that is about 1/2 degree off from the actual angle of the line.
 
Folks you assumed 22/7 was not accurate enough for PI and got into deep forests.

Why not ask someone who knows, whether 22/7 is not the exact PI, more exact than the system variable or anything else!

Likewise 22/14 for PI/2, more accurate than 1.5708...
 
In fact 22/7 does not equal PI it is about .07 degrees off at 180 degrees. A more accurate value is 21.99114858.... / 7.0 This is only about 0.00000001 from 180 degrees.

So.....

To keep accurate angles, I suggested using PI to convert between radians and degrees.

(distof (angtos pi)) is 180.000000000......

while

(distof (angtos (/ 22.0 7.0))) is 180.075.......

Not a big difference, but it is not the same as 180.0

That is the difference.

I stand by my previous recommendation

Degrees to radians is:

(* PI ( / ang 180))

and

Radians to degrees is:

(distof (angtos ang))



Cheers.....
 
Striker you kinda lost me in that post whne you were talking about

(setq angledegree (distof (angtos angleradian)))

???
so what you are saying is i need the following lines in this general order

(setq angleradian 1.5708)
(setq intermediate_value (angtos angleradian))
(setq degrees (distof intermediate_value))
(setq angledegree (distof (angtos angleradian)))




if everyone helps everybody the world will be a better place
 
No, I suppose I should clarify a bit better. The original idea of the program was to take the angle of the line as represented by ANGLERADIANS and convert it to ANGLEDEGREES. What I made mention of, was that the program worked flawlessly save one small glitch. That glitch was that the angle of the line would be perhaps 90 degrees while the text would be 89.92.... degrees, so what I proposed was to use PI as the defacto accurate real for all convertions from radians to degrees and vice versa. Fortunately for us, LISP already has some functions to do this for us. To convert a radian to degrees use the angtos function. however the angtos function returns a string, but the program expects a number, so we convert the result from angtos with distof. Now the direct replacement for the identified line in my first post on this subject is:

(setq angledegree(distof (angtos angleradian)))

The other lines posted after that were merely to spell out in more detail exactly what is happening. Example:

(angtos angleradian) returns a string

and

(distof result_from_angtos) returns a real number

therefore

(distof (angtos angleradian)) returns a degree angle as a number which we assign to angledegree as such:

(setq angledegree (distof (angtos angleradian)))

The other lines can be ignored.

I suppose I could have just changed the program to expect a string, but why change several lines when only one will do the same thing.

I do regret the confusion on this issue. If I can be of any more assistance let me know.

Cheers to all.....
 
I tried it your way striker that is why i had asked you to clairfy cause i thought i had misinterpreted your info but apparently not but much to my suprize the cnp(copynpaste) i did dint work ??? so idont know whats wrong i did as you said replace

(setq angledegree (/ (* angleradian 180. 7. ) 22.))

& Use

(setq angledegree (distof (angtos angleradian)))

but at last then the lips fails to function properly

if everyone helps everybody the world will be a better place
 
Folks remember, the position of text was just about randomly picked. No need to be very precise there.
1% of a degree was no issue at all.

Now, this confusion beats the intent of the tutorial.

22/7 or 3.14 as radian of 180 degrees was good enough for this purpose. It still is.

hat degrees to radian or rtd / dtr is not very original - it is there in most lisp routines under directory sSupport of Acad.

22/7 was kind of cute and original because it is not used in any of lisp examples under Support.

Again - position of text, just a little away from the line - does not need overprecision.

As it is now, the length of this posting nullifies its tutorial value. Would be much simpler to read the reference to the few commands.

The art of the thing was to combine which commands were relevent to print linelengths into the drawing, how to select lines, filter, place the text somewhere etc.

Where exactly to place the text was left free to modify anyway.

Still, take care.



 
Status
Not open for further replies.

Part and Inventory Search

Sponsor