Posts Tagged ‘LISP’

Making Isometric Drawings Using AutoLISP – Part 5

Posted on: January 28th, 2014 by amhsmc

Irregular Angles

I know I planned on only having a circle, rectangle and hexagon as options in my autolisp function for isometric drawing, but just after I finished with my code I realized I needed one more thing: a way to create irregular angles on the face of an axis. This makes it much easier to build complex geometry in isometric views, and it wasn’t actually too difficult to implement once I figured out some of the mechanisms.

Building Geometry


The angle to be produced shown against an isometric cube, with reference points and angles shown.
Figure 1: The angle shown against isometric axes, with the 30 degree offset and x and y distances shown.

The first thing to do is determine the angle transformation from regular to isometric. The relative position of the angle remains constant in the transformation (a 45 degree angle still goes to the opposite corner of a cube). This means that:
theta/90 = phi/60,
Where theta is the angle at 90 degrees and phi is the angle at 60 degrees. Thereby theta * 60/90 is equal to the transformation angle. We then add that angle to the additional 30 degrees created by the isometric view (figure 1). The line can then be divided into x and y coordinates using trig functions, as seen from the code below:

(setq m1(getdist "\n Length(inches):")) ;query magnitude
(setq r2(getangle "\n Angle:")) ;query angle
(setq f1(getstring "\n Face(Top/Left/Right):"))
((or (= f1 "L") (= f1 "l") (= f1 "Left") (= f1 "left") (= f1 "LEFT")) (progn
(setq i -1.0)
(setq r3 (* r2 (/ 60.0 90.0))) ) )
((or (= f1 "R") (= f1 "r") (= f1 "Right") (= f1 "right") (= f1 "RIGHT"))
(setq i 1.0)
(setq r3 (* r2 (/ 60.0 90.0))) ) )
((or (= f1 "T") (= f1 "t") (= f1 "Top") (= f1 "top") (= f1 "TOP"))
(setq i 1.0)
(setq r3 (* r2 (/ 120.0 90.0))) ) )
(setq pta1 (list (+ x1 (* i (* m1 (cos (+ a1 r3))))) (+ y1 (* m1 (sin (+ a1 r3)))) 0)) (command "._line" pt1 pta1 "")

And there you have it! I hope you enjoyed this bonus post about AutoLISP. I may create a data or geographic information systems (GIS) themed script in the future, depending on how much I can get out of the built-in features in AutoCAD and how useful Autocad would be for those purposes.

Making Isometric Drawings Using AutoLISP – Part 4

Posted on: January 21st, 2014 by amhsmc

The Circle

Circles are among the hardest simple geometric shapes to draw in isometric view. When transformed into an isometric view, circles become ellipses. In order to draw the ellipse, we need to determine the x and y radii using the provided radius as a reference. By transforming the x and y coordinates of the radius at a 45 degree angle, we can get the coordinates for the isometric radii and create our ellipse (figure 1).

A circle, in x-y plane and isometric x-y plane views, with geometry showing how to build the isometric view (ellipse)
Figure 1: Here we show the circle and radius right triangle, which is transformed into a 120 degree inner angle triangle in isometric view.

Then it becomes fairly easy to build out the ellipse. Here we also show the method for putting it on different axes of the isometric x-y-z view:

(setq axis1(getstring "\n Horizontal/Vertical axis:"))
(setq rd2(getdist "\n Radius:"))
(setq rd2 (* rd2 (sqrt 2)))
(if (or (= axis1 "H") (= axis1 "Horizontal") (= axis1 "horizontal") (= axis1 "h"))(progn
(setq pte1 (list (+ x1 (* (cos a1) rd2)) y1 0))
(setq pte2 (list x1 (+ y1 (* (sin a1) rd2)) 0))
(setq pte1 (list (+ x1 (* (* (cos a1) rd2) (sin a1))) (+ y1 (* (* (cos a1) rd2) (cos a1))) 0))
(setq pte2 (list (+ x1 (* (* (sin a1) rd2) (sin a5))) (+ y1 (* (* (sin a1) rd2) (cos a5))) 0))
(command "._ellipse" "c" pt1 pte1 pte2) ;draws ellipse

Where a1=30 degrees, a5=60 degrees. Note we also show the Horizontal/Vertical Axis selection to cut down on steps.
We’re solving for the sides of the 45 degree triangle formed by the radius, and then converting that right triangle into an obtuse 120 degree triangle in isometric view in order to solve for the lengths of the ellipse radii. Once we know where those two radii are located, it becomes a simple matter of drawing the ellipse.
And that’s it! Thank you for sticking through it, or if you haven’t seen the previous posts, check them out!

Making Isometric Drawings Using AutoLISP – Part 3

Posted on: January 20th, 2014 by amhsmc

The Hexagon

The hexagon is a little more complicated of a shape than a rectangle. Since it has geometry directly perpendicular to one axis, it becomes trivial to use more trigonometry to solve for the points.

Developing the Geometry

Like placing any other geometry, you need a reference point, which we’ll set as the center of the hexagon to be drawn. We then have to find out what size of hexagon to draw, using the radius of the circle inscribed inside the hexagon (figure 1).

A hexagon with inscribed circle, in x-y plane and isometric x-y plane views
Figure 1: Here we show the reference point, inscribed circle, and some of the geometry to be modeled

We then use the radius provided to build the geometry directly on the isometric x-y axes, and then build the geometry between those points:

(setq t1(getdist "\n Trade Size Width(inches):"))
(setq r1 (/ t1 (sin (* a1 2))))
(setq s1 (* r1 (cos (* a1 2))))
(setq pthx1 (list (+ x1 (+ (* (/ t1 2) (cos a3)) (* (/ s1 2) (cos a4)))) (+ y1 (+ (* (/ t1 2) (sin a3)) (* (/ s1 2) (sin a4)))) 0))
(setq pthx2 (list (+ x1 (+ (* (/ t1 2) (cos a3)) (* (/ s1 2) (cos a2)))) (+ y1 (+ (* (/ t1 2) (sin a3)) (* (/ s1 2) (sin a2)))) 0))
(setq pthx3 (list (+ x1 (* (/ r1 2) (cos a2))) (+ y1 (* (/ r1 2) (sin a2))) 0))
(setq pthx4 (list (+ x1 (+ (* (/ t1 2) (cos a1)) (* (/ s1 2) (cos a2)))) (+ y1 (+ (* (/ t1 2) (sin a1)) (* (/ s1 2) (sin a2)))) 0))
(setq pthx5 (list (+ x1 (+ (* (/ t1 2) (cos a1)) (* (/ s1 2) (cos a4)))) (+ y1 (+ (* (/ t1 2) (sin a1)) (* (/ s1 2) (sin a4)))) 0))
(setq pthx6 (list (+ x1 (* (/ r1 2) (cos a4))) (+ y1 (* (/ r1 2) (sin a4))) 0))
(command "._pline" pthx1 pthx2 pthx3 pthx4 pthx5 pthx6 "C")

Now that that’s taken care of, on to the hard one, the circle!

Making Isometric Drawings Using AutoLISP – Part 2

Posted on: August 8th, 2013 by amhsmc

The Rectangle

The rectangle is the easiest, since each axis of drawing follows the isometric axis. Isometric drawings use 30° parallel projection, meaning that unlike perspective drawing, objects along the same axis don’t convene at a point, but rather are parallel to one another. This preserves the dimensions of most of the shape, however there is no visible depth to the objects (see figure 1).

(a) An isometric rectangle with parallel edges, and (b) a perspective rectangle with converging edges.


Developing the Geometry

In order to start building the rectangle, we need to establish a reference point, which we’ll then use to also be where the geometry is placed. We’ll call this point “p0” for convenience sake. We also need to know the length, width and height, which we’ll call “lx”, “wx” and “hx” respectively. It’s then just a matter of expressing the coordinates of the cube in two dimensions.
Since the lengths all stay the same, and the x and y axes are offset 120°, we can express each of the points of the prismatic rectangle on the regular x and y axis using trigonometry.

Using a reference point to express all the other points in x and y
Using the reference point, extend the length, width and height along their respective axes and use trigonometry to express the points along an x and y coordinate system.

We then have to turn this into LISP code, which looks like this:

(setq l1(getdist "\n Length(inches):"))
(setq w1(getdist "\n Width(inches):"))
(setq h1(getdist "\n Height(inches):"))
(setq ptl1 (list (+ x1 (* (cos a1) l1)) (+ y1 (* (sin a1) l1)) 0))
(setq ptw1 (list (+ x1 (* (cos a2) w1)) (+ y1 (* (sin a2) w1)) 0))
(setq pth1 (list x1 (+ y1 h1) 0))
(setq pthw1 (list (car ptw1) (+ h1 (car(cdr ptw1))) 0))
(setq pthl1 (list (car ptl1) (+ h1 (car(cdr ptl1))) 0))
(setq ptlwh1 (list (+ (car ptl1) (* (cos a2) w1)) (+ (car(cdr pthl1)) (* (sin a2) w1)) 0))
(command "._line" pt1 pth1 "")
(command "._line" pt1 ptl1 "")
(command "._line" pt1 ptw1 "")
(command "._line" pth1 pthw1 "")
(command "._line" pth1 pthl1 "")
(command "._line" pthw1 ptlwh1 "")
(command "._line" pthl1 ptlwh1 "")
(command "._line" ptl1 pthl1 "")
(command "._line" ptw1 pthw1 "")

There! All done with that, on to the the next!

Making Isometric Drawings Using AutoLISP – Part 1

Posted on: August 4th, 2013 by amhsmc

I started creating isometric details in AutoCAD a while ago, and realized something I thought I already knew: AutoCAD sucks at 3D modeling. Isometric drawings are an effective way of representing 3D objects in 2D, and preserves dimensionality of the object. Unfortunately it turns out that while AutoCAD is perfectly capable of handling isometric drawings, it does so with a lot less thoughtfullness as I’d hope.
Creating isometric drawings means breaking up a workflow, which most people would say isn’t that big of a deal, but for anyone trying to work quickly and effectively, that’s a problem. It’s fine sticking to regular drawing when creating boxes, they’re simple enough. But circles and hexagons aren’t as easy. That’s why I decided to create an AutoLISP macro to do it for me.
Since I’m also fairly new to AutoCAD and AutoLISP, I decided to practice further by generating my own geometry and functions, rather than just switching between the two drawing methods with LISP. This allows me to get my own input and output options, which also speeds up the drawing process.
The following is the step by step process by which I made the macro and solved for the geometry mathematically.

Develop Input and Output Goals

Choosing your input how it’s asked for is key to a good function. Not only does it force you to start thinking about what variables you need, it also gets you thinking about the algorithm’s process and how it performs the calculations. First off I decided I wanted either a circle, rectangle, or hexagon, so I needed a snippet for that prompt. Next I wanted to put that object somewhere, so I needed to query for that as well. Then what do I want? For it to draw the shape of course! So here is the first iteration of what I want.
(defun C:myProg () ;defines the function in LISP
;query shape to build
;query starting point
;draw shape

The “draw shape” segment then expands into:
;if circle
;draw circle
;else if rectangle
;draw rectangle
;else if hexagon
;draw hexagon

And since each shape has different ways of measuring it, those need to be included to get the desired size. For circles I use the radius, rectangles the edge lengths, and hexagons the trade size (since they will be nuts and bolts). It’s very important to get an input that has meaningful bearing on your output, otherwise the program gets overly complicated.

;if circle
;query radius
;draw circle
;if rectangle
;query length, width, height
;draw rectangle
;if hexagon
;query trade size (diameter)
;draw hexagon

Now let’s solve for those shapes!