Autocad Lisp Draw Line Distance and Angle
Chapter 6: Working With Geometry
Introduction
How to Find Angles and Distances
Understanding the Angle, Distance, and Polar Function
Using Trigonometry to Solve a Problem
Gathering Information
Finding Points Using Trigonometry
Conclusion
Introduction
It is inevitable that your work with AutoLISP will involve some geometric manipulations. With the box program in chapter 2, you have already created a program that derives new point locations based on user input. There, you learned how to take coordinate lists apart, then re-assemble them to produce a new coordinate. In this chapter, you will be introduced to other AutoLISP functions that will help you determine locations in your drawings coordinate system and in the process, you will review some basic trigonometry.
How to find Angles and Distances
In chapter 4, you learned how to prompt the user for angles and distances. At time, however, you will want to find angles and distances based on the location of existing point variables rather than relying on user input every time you need to find an angle.
Suppose you want to find a way to break two parallel lines between two points in a manner similar to the standard AutoCAD break command. In addition, you would like this function to join the ends of the two broken portions of each line to form an opening. Figure 6.1 shows a drawing of the process along with a description of what must occur. This drawing can be developed into pseudocode for your program. A function similar to this is commonly used in architectural drawings to place an opening in a wall.
Figure 6.1: Sketch of the parallel line break program
In Chapter 3, we discussed the importance of designing your program to be simple to use. This program is designed to obtain the information needed to perform its task using the minimum of user input. Since it is similar to the break command, it also tries to mimic the break program to some degree so the user feels comfortable with it. As you read through this section, pay special attention to the way information is gathered and used to accomplish the final result.
Open an AutoLISP file called Break2.lsp and copy the program in figure 6.2. Open a new AutoCAD file called Chapt6. Draw a line from point 2,4 to 12,4 then offset that line a distance of 0.25 units. Your screen should look like figure 6.3.
;Program to break 2 parallel lines -- Break2.lsp (defun c:break2 (/ pt1 pt2 pt3 pt4 pt0 ang1 dst1) (setvar "osmode" 512) ;near osnap mode (setq pt1 (getpoint "\nSelect object: ")) ;get first break point (setq pt2 (getpoint pt1 "\nEnter second point: ")) ;get second break point (setvar "osmode" 128) ;perpend osnap mode (Setq pt3 (getpoint pt1 "\nSelect parallel line: "));get 2nd line (Setvar "osmode" 0) ;no osnap mode (setq ang1 (angle pt1 pt3)) ;find angle btwn lines (setq dst1 (distance pt1 pt3)) ;find dist. btwn lines (setq pt4 (polar pt2 ang1 dst1)) ;derive pt4 on 2nd line (command "break" pt1 pt2 ;break 1st line "break" pt3 pt4 ;break 2nd line "line" pt1 pt3 "" ;close ends of lines "line" pt2 pt4 "" ) )
Figure 6.3: Two parallel lines drawn
1. Load the Break2.lsp file and enter break2 at the Command prompt.
2. At the prompt:
The osnap cursor appears. Pick the lowermost line near coordinate 5,4.
3. At the next prompt:
Pick the lowermost line again near coordinate 10,4.
4. Finally, at the prompt:
pick the upper line near its midpoint. The two line break and are joined at their break points to form an opening (see figure 6.4)
Figure 6.4: The lines after using Break2
Now draw several parallel lines at different orientations and try the Break2 program on each pair of lines. Break2 places an opening in a pair of parallel lines regardless of their orientation. Let's look at how break2 accomplishes this.
Understanding the Angle, Distance, and Polar Functions
The first line after defun function uses the setvar function to set the osnap system variable to the nearest mode.
(defun C:BREAK2 (/ pt1 pt2 pt3 pt4 pt0 ang1 dst1)
(setvar "osmode" 512)
This ensures that the point the user picks at the next prompt is exactly on the line. It also give the user a visual cue to pick something since the osnap cursor appears.
When setvar is used with the osmode system variable, a numeric code must also be supplied. This code determines the osnap mode to be used. Table 6.1 shows a list of the codes and their meaning.
Table 6.1: Osmode codes and their meaning
Code
Equivalent Osnap mode
1
Endpoint
2
Midpoint
4
Center
8
Node
16
Quadrant
32
Intersection
64
Insertion
128
Perpendicular
256
Tangent
512
Nearest
1024
Quick
The next line prompts the user to select an object using the getpoint function:
(setq pt1 (getpoint "\nSelect object: "))
Here, the variable pt1 is used to store the first point location for the break. Since the nearest osnap mode is used, the osnap cursor appears and the point picked falls exactly on the line (see Figure 6.5).
Figure 6.5: Getting a point using the "nearest" osnap mode.
Next, another prompt asks the user to pick another point:
(setq pt2 (getpoint pt1 "\nEnter second point: "))
The variable pt2 is assigned a point location for the other end of the break. The next line:
(setvar "osmode" 128)
sets the osnap mode to perpendicular in preparation for the next prompt:
(Setq pt3 (getpoint pt1 "\nSelect parallel line: "))
Here, the user is asked to select the line parallel to the first line. The user can pick any point along the parallel line and the perpendicular osnap mode ensures that the point picked on the parallel line is "perpendicular" to the first point stored by the variable pt1. The perpendicular osnap mode will only work, however, if a point argument is supplied to the Getpoint function. In this case, the point pt1 is supplied as a reference from which the perpendicular location is to be found (see figure 6.6). This new point variable pt3 will be important in calculating the location of the two break points on the parallel line.
Figure 6.6: Picking the point perpendicular to the first point.
The next line sets the osnap mode back to "none":
(Setvar "osmode" 0)
The next two lines find the angle and distance described by the two point variables pt1 and pt3.
(setq ang1 (angle pt1 pt3))
(setq dst1 (distance pt1 pt3))
You can obtain the angle described by two points using the Angle function. Angles syntax is:
( angle [ coordinate list ][ coordinate list ] )
The arguments to angle are always coordinate lists. The lists can either be variables or quoted lists.
Angle returns a value in radians. You looked at radians briefly in chapter 4. A radian is system to measure angles based on a circle of 1 unit radius. In such a circle, an angle can be described as a distance along the circle's circumference. You may recall from high school geometry that a circle's circumference is equal to 2 times pi times its radius. since the hypothetical circle has a radius of 1, we drop the one from the equation.
circumference = 2pi
90 degrees is equal to one quarter the circumference of the circle or pi/2 radians or 1.5708 (see figure 6.7). 180 degrees is equal to half the circumference of a circle or 1 pi radians or 3.14159. 360 degrees is equal the full circumference of the circle or to 2 pi radians or 6.28319.
A simple formula to convert degrees to radians is:
radians * 57.2958
To convert degrees to radians the formula is:
degrees * 0.0174533
Angle uses the current UCS orientation as its basis for determining angles. Though you can supply 3 dimensional point values to angle, the angle returned is based on a 2 dimensional projection of those points on the current UCS (see figure 6.7). Finally, radians are always measured with a counterclockwise directions being positive.
Figure 6.7: Degrees and radians
The distance function is similar to angle in that it requires two point lists for arguments:
(distance [ coordinate list ][ coordinate list ])
The value returned by distance is in drawing units regardless of the current unit style setting. This means that if you have the units set to Architectural, distance will return distances in one inch units.
By storing the angle and distance values between pt1 and pt3, the program can now determine the location of the second break point on the parallel line. This is done by applying this angle and distance information to the second break point of the first line using the following expression:
(setq pt4 (polar pt2 ang1 dst1))
Here the angle variable ang1 and the distance variable dst1 are used as arguments to the polar function to find a point pt4. Polar returns a point value (see figure 6.8).
Figure 6.8: Using the polar function to find a new point.
The syntax for polar is:
(polar [ point value ][ angle in radians ][ distance ])
Polar is used to find relative point locations. It requires a point value as its first argument followed by an angle and distance value. The new point value is calculated by applying the angle and distance to the point value supplied. This is similar to describing a relative location in AutoCAD using the at sign. For example, to describe a relative location of .25 units at 90 degrees from the last point entered you would enter the following in AutoCAD:
@.25<90
The same relative location would look like the following using the polar function:
(setq pt1 (getvar "lastpoint"))
(polar pt1 1.5708 .25)
The first expression in this example uses the getvar function to obtain the last point selected. Setq then assigns that point to the variable pt1. Polar is used in the next line to find a point that is 1.5708 radians (45 degrees) and 2 units away from the lastpoint.
The last several lines of the Break2 program use all the point variables to first break the two lines then draw the joining lines between them.
(command
"break" pt1 pt2
"break" pt3 pt4
"line" pt1 pt3 ""
"line" pt2 pt4 ""
)
)
In the Break2 program, you could have used the getdist and getangle functions but to do so would mean including an additional prompt. By using the combination of the perpend osnap mode along with the getpoint function, you establishes a point value from which both the angle and distance value is derived. In general, if you know that you will need to gather both distance and angle information, it is better to establish coordinate variables first then derive angles and distances from those coordinates using the distance and angle functions.
Using Trigonometry to Solve a Problem
The Break2 function is relatively simple as far as its manipulation of data is concerned. But at times, you will need to enlist the aid of some basic trigonometric functions to solve problems. Suppose you want a function that will cut a circle along an axis defined by the user. Figure 6.9 shows a sketch along with a written description of a program that does this.
Figure 6.9: Sketch of circle cutting program.
This program makes use of the Pythagorean Theorem as well as the Sine trigonometric function as you will see in the next section.
Gathering Information
Before a problem can be solved, you must first gather all the known factors affecting the problem. The program you will explore next will give an example of how you might go about your information gathering.
Exit AutoCAD and open an AutoLISP file called Cutcr.lsp. Carefully copy the program in figure 6.10 into this file. Save and exit the Cutcr.lsp file then start AutoCAD and open the Chapt6 file again. Load the Ctcr.lsp fine then do the following:
1. Erase everything on the screen then draw a circle with its center at point 8,6 and a with a radius of 3 units (see figure 6.11).
2. Enter cutcr at the command prompt to start the C:CUTCR program.
3 At the prompt:
Pick circle to cut:
pick the circle you just drew.
4. At the next prompt:
Pick first point of cut line:
pick a point at coordinate 5,9.
5. At the prompt:
Pick second point:
pick a point at coordinate 8,2.
The circle is cut into two arcs along the axis represented by the two points you picked (see figure6.12).
6. Use the erase command to erase the left half of the circle. You can now see that the circle has been cut (see figure 6.13).
;Program to cut a circle into two arcs -- Cutcr.lsp (defun C:CUTCR (/ cpt1 lpt1 lpt2 cent rad1 ang1 dst1 dst2 cord ang2 wkpt cpt2 cpt3) (setvar "osmode" 512) ;osnap to nearest (setq cpt1 (getpoint "\nPick circle to cut: ")) ;find point on circle (setvar "osmode" 0) ;osnap to none (setq lpt1 (getpoint "\nPick first point of cut line: ")) ;1st point of cut (setq lpt2 (getpoint lpt1 "\nPick second point: ")) ;2nd point of cut (setq cent (osnap cpt1 "center")) ;find center pt (setq rad1 (distance cpt1 cent)) ;find radius of circle (setq ang1 (- (angle lpt1 cent)(angle lpt1 lpt2))) ;find difference of angles (setq dst1 (distance lpt1 cent)) ;find dist.lpt1 to cent (setq dst2 (* dst1 (sin ang1))) ;find side of triangle (setq cord (sqrt(-(* rad1 rad1)(* dst2 dst2)))) ;find half cord (setq ang2 (- (angle lpt1 lpt2) 1.57)) ;find perpend angle (setq wkpt (polar cent ang2 dst2)) ;find workpoint (setq cpt2 (polar wkpt (angle lpt1 lpt2) cord)) ;find first intersect (setq cpt3 (polar wkpt (angle lpt2 lpt1) cord)) ;find second intersect (command "erase" cpt1 "" ;erase circle "arc" "c" cent cpt2 cpt3 ;draw first circle seg. "arc" "c" cent cpt3 cpt2 ;draw second circle seg. ) ;close command funct. ) ;close defun
Figure 6.12: Drawing the cut axis.
Figure 6.13: Erasing one part of the circle after it has been cut.
The first three expressions in the program after the defun functions and its arguments obtain a point on the circle:
(setvar "osmode" 512)
(setq cpt1 (getpoint "\nPick circle to cut: "))
(setvar "osmode" 0)
The setvar function sets osnap to the nearest mode then the user is prompted to pick the circle to cut. This point is stored as cpt1. The osnap mode ensures that the point picked is exactly on the circle. Later, this point will be used to both erase the circle and to find the circles center. The next function sets osnap back to none.
The next two lines prompt the user to select the points that define the axis along which the circle is to be cut:
(setq lpt1 (getpoint "\npick first point of cut line: "))
(setq lpt2 (getpoint lpt1 "\nPick second point: "))
The getpoint function is used in both these expressions to obtain the endpoints of the cut axis. These endpoints are stored as lpt1 and lpt2.
The next expression uses a new function called osnap:
(setq cent (osnap cpt1 "center"))
Here the point picked previously as the point on the circle cpt1 is used in conjunction with the osnap function to obtain the center point of the circle. The syntax for osnap is:
(osnap [ point value ][ osnap mode ])
The osnap function acts in the same way as the osnap overrides. If you use the center osnap override and pick a point on the circle, you get the center of the circle. Likewise, the osnap function takes a point value and applies an osnap mode to it to obtain a point. In this case, osnap applies the center override to the point cpt1 which is located on the circle. This gives us the center of the circle which is assigned to the symbol cent.
The next expression obtains the circle's radius
(setq rad1 (distance cpt1 cent))
The distance function is used to get the distance from cpt1, the point located on the circle, to cent, the center of the circle. This value is assigned to the symbol rad1.
Finding Points Using Trigonometry
At this point, we have all the known points we can obtain without utilizing some math. ultimately, we want to find the intersection point between the circle and the cut axis. By using the basic trigonometric functions, we can derive the relationship between the sides of triangle. In particular, we want to look for triangles that contain right angles. If we analyze the known elements to our problem, we can see that two triangles can be used to find one intersection on the circle (See figure 6.14)
Figure 6.14: Triangles used to find the intersection
In our analysis, we see that we can find a point along the cut axis that describes the corner of a right triangle. To find this point, we only need an angle and the length of the hypotenuse of the triangle. We can then apply one of the basic trigonometric functions shown in figure 6.15 to our problem.
Figure 6.15: Basic trigonometric functions
The sine function is the best match to information we have.
sine(angle) = opposite side / hypotenuse
This formula has to be modified using some basic algebra to suite our needs:
opposite side = hypotenuse * sine (angle)
Before we can use the sine function, we need to find the angle formed by points lpt1, lpt2 and cent (see figure 6.16).
Figure 6.16: Angle needed to before the sine function can be used.
The following function does this for us:
(setq ang1 (- (angle lpt1 cent) (angle lpt1 lpt2)))
The first of these three functions finds the angle described by points lpt1 and lpt1. The second expression finds the angle from lpt1 to the center of the circle. The third line finds the difference between these two angles to give us the angle of the triangle we need (see figure 6.17).
Figure 6.17: The sine expression written to accommodate the known elements.
We also need the length of the hypotenuse of the triangle. this can be gotten by finding the distance between lpt1 and the center of the triangle:
(setq dst1 (distance lpt1 cent))
The length of the hypotenuse is saved as the variable dst1. We can now apply our angle and hypotenuse to the formula:
opposite side = hypotenuse * sine (angle) becomes
(setq dst2 (* dst1 (sin ang1)))
Now we have the length of the side of the triangle but we need to know the direction of that side in order to find the corner point of the triangle. We already know that the direction is at a right angle to the cut axis. therefore, we can determine the right angle to the cut axis by adding the cut axis angle to 1.57 radians (90 degrees)(see figure 6.18). The following expression does this for us:
(setq ang2 (- (angle lpt1 lpt2) 1.57))
Figure 6.18: Finding the angle of the opposite side of the triangle.
We are now able to place the missing corner of the triangle using the polar function (see figure 6.19).
(setq wkpt (polar cent ang2 dst2))
Figure 6.19: Finding the workpoint wkpt.
We assign the corner point location to the variable wkpt. We're still not finished with our little math exercise, however. We still need to find the intersection of the cut axis to the circle. Looking at our problem solving sketch, we can see that yet another triangle can be used to solve our problem. We know that the intersection lies along the cut axis. We can describe a triangle whose corner is defined by the intersection of the circle and the cut axis (see figure 6.20).
Figure 6.20: The triangle describing one intersection point.
We also already know two of the sides of this new triangle. One is the radius of the circle stored as the variable rad1. The other is the side of the triangle we used earlier stored as the variable dst2. The most direct way to find the intersection is to apply the Pythagorean Theorem shown in figure 6.21.
Figure 6.21: The Pythagorean Theorem
Again we must apply algebra to derive a formula to suite our needs. The formula:
c 2 = a 2 - b 2
becomes the expression:
(setq cord (sqrt(-(* rad1 rad1)(* dst2 dst2))))
We assign the distance value gotten from the Pythagorean Theorem to the variable cord. Using the Polar function, we can now find one intersection point between the circle and the cut axis:
(setq cpt2 (polar wkpt (angle lpt2 lpt1) cord))
In this expression, we find one intersection by applying the angle described by lpt1 and lpt2 and the distance described by cord to the polar functions (see figure 6.22).
Figure 6.22: Finding the location of an intersection point.
Since the two intersection points are symmetric about point wkpt, the second intersection point is found by reversing the direction of the angle in previous expression:
(setq cpt3 (polar wkpt (angle lpt1 lpt2) cord))
Finally, we can get AutoCAD to do the actual work of cutting the circle:
(command "erase" cpt1 ""
"arc" "c" cent cpt2 cpt3
"arc" "c" cent cpt3 cpt2
)
)
Actually, we don't really cut the circle. Instead, the circle is erased entirely and replaced with two arcs (see figure 6.23).
Figure 6.23: Drawing the new circle.
Functions Useful in Geometric Transformations
The majority of your graphic problems can be solved with the basic trigonometric functons used in the Cutcr program. But AutoLISP provides the tools to solve even th emost arcane trigonometric problems. This section shows the functions you are most likely to use in situations that require geometric manipulations.
Trans
Trans translates a coordinate or displacement from one user coordinate system to another. The first argument is a point of reference. The second argument is a code indicating which coordinate system the point is expressed in. The third argument is a code indicating which coordinate system the point is to be translated to. An optional fourth True/nil argument can be included. If this fourth argument evaluates to True or non-nil, then the first argument will be treated as a displacement rather than a point value. The following are the codes for the second and third arguments.
Code | Coordinate System |
0 | World Coordinate System |
1 | Current User Coordinate System |
2 | Coordinate system of the current view plane |
The syntax for Trans is
(trans [coordinage_list] [UCS_code] [optionalT/nil] )
Atan
Atan returns the arctangent in radians of its first argument. If the argument is negative, then the value returned will be negative. If two arguments are supplied, then Atan returns a the arctangent of the first argument divided by the second argument.
The syntax for Atan is
(atan [number] [optional_2nd_number])
Inters
Inters returns a coordinate list of the intersection of two vectors. The first two arguments to inters are the endpoints of one vector while the third and fourth arguments define the other vector. If an optional fifth agrument is present and evaluates to nil, then Inters will attempt to locate an intersection point of the two vectors regardless of whether the intersection falls between the specified points or not.
The syntax for Inters is
(inters [point point point point] [optional_T/nil])
Sin
Sine returns the sine of an angle as a real number. The angle must be expressed in radians.
The syntax for Sine is
(sin [angle])
Cos
Cos returns the Cosine of an angle as a real number. The angle must be expressed in radians.
The syntax for Cos is
(cos [angle])
Conclusion
The majority of your graphic problems can be solved using the basic trigonometric functions shown in this sample program. But AutoLISP provides the tools to solve even the most arcane Trigonometric problems. If you find you need to use these math trig functions, consider making liberal use of a sketch pad or for that matter, AutoCAD itself to document your program. You may want to re-use or modify programs such as the previous example and if you don't have some graphic documentation recording how it works, you can have a difficult time understanding why you wrote your program as you did.
Source: http://people.fsv.cvut.cz/www/chourpav/Lisp/Chapter%206.htm
0 Response to "Autocad Lisp Draw Line Distance and Angle"
إرسال تعليق