home *** CD-ROM | disk | FTP | other *** search
- REM @(#)CADKEY SOLIDS cylinder.cdl 2.2 10/31/88
- REM program to draw right circular cylinder entity
- array vmat[9]
-
- :length
- REM Positive length of the cylinder
-
- getflt "Length of the cylinder (%f) =>", 1.00, len
- if (@key <= -2)
- exit
- if (len > 0.00001)
- goto radius
- pause "Invalid length ... (Press RETURN)"
- goto length
-
- :radius
- REM Positive radius for the cylinder
-
- getflt "Radius of the cylinder (%f) =>", 0.5, rad
- if (@key == -3)
- exit
- if (@key == -2)
- goto length
- if (rad > 0.00001)
- goto sections
- pause "Invalid radius ... (Press RETURN)"
- goto radius
-
- :sections
- REM Number of parallel coaxial circles to be displayed
-
- getint "Enter no. of transverse sections (%d) =>", 5, sect
- if (@key == -3)
- exit
- if (@key == -2)
- goto radius
- if (sect >= 1)
- goto method
- pause "Invalid number ... (Press RETURN)"
- goto sections
-
- :method
- REM The axis of the cylinder can be defined by two methods. TWO PTS requires
- REM the user to indicate two points which determine a line. The axis of the
- REM cylinder is parallel to this line, but could be anywhere. This option is
- REM default. PLANE lets the user indicate a plane and the cylinder axis is
- REM parallel to the normal to that plane, but could be anywhere.
-
- getmenu "Choose method for defining cylinder axis direction",\
- "TWO PTS",\
- "PLANE"
-
- if (@key == -3)
- exit
- if (@key == -2)
- goto sections
- if (@key == 2)
- goto plane
-
- def = 3
- :first
- getpos "Indicate 1st pt. along the axis", def
- if (@key == -1)
- goto first
- x1 = @xworld
- y1 = @yworld
- z1 = @zworld
-
- if (@key == -3)
- exit
- if (@key == -2)
- goto method
- def = @key
-
- :second
- getpos "Indicate 2nd pt. along the axis", def
- if (@key == -1)
- goto second
- x2 = @xworld
- y2 = @yworld
- z2 = @zworld
-
- def = @key
- if (@key == -3)
- exit
- if (@key == -2)
- goto first
-
- REM direction vector for the cone axis has to be non-zero
- xn = x2 - x1
- yn = y2 - y1
- zn = z2 - z1
-
- if ((abs(xn) > 0.00001) || \
- (abs(yn) > 0.00001) || \
- (abs(zn) > 0.00001))
- goto unit
-
- pause "2nd pt. is coincident with 1st pt. (Press RETURN)"
- goto second
-
- :unit
- REM Take cross product of (0, 1, 0) with the direction vector to get x axis.
- REM If the result is a zero vector, the dirction vector is parallel to
- REM (0, 1, 0), so take direction vector cross (1, 0, 0) to get y axis. Once
- REM the x axis or y axis is determined, find the remaining axis by taking
- REM cross of the direction vector and the axis determined, thus completing
- REM the orthogonal basis
-
- call cross, xx, xy, xz, 0, 1, 0, xn, yn, zn
-
- if ((abs(xx) < 0.00001) && \
- (abs(xy) < 0.00001) && \
- (abs(xz) < 0.00001))
- goto use_x
-
- call cross, yx, yy, yz, xn, yn, zn, xx, xy, xz
- goto vmatrix
-
- :use_x
- call cross, yx, yy, yz, xn, yn, zn, 1, 0, 0
- call cross, xx, xy, xz, yx, yy, yz, xn, yn, zn
-
- :vmatrix
- REM Determine the vector magnitudes and convert the orthogonal basis to a
- REM orthnormal basis
-
- mn = sqrt(xn*xn + yn*yn + zn*zn)
- mx = sqrt(xx*xx + xy*xy + xz*xz)
- my = sqrt(yx*yx + yy*yy + yz*yz)
-
- REM Define the view matrix for the new view and go to defining the view
-
- vmat[0] = xx/mx
- vmat[1] = yx/my
- vmat[2] = xn/mn
- vmat[3] = xy/mx
- vmat[4] = yy/my
- vmat[5] = yn/mn
- vmat[6] = xz/mx
- vmat[7] = yz/my
- vmat[8] = zn/mn
- goto def_view
-
- :plane
- REM If the PLANE option is chosen, get the view matrix by GETPLANE command
-
- getplane "Define plane for 1st face", 1
-
- if (@key == -3)
- exit
- if (@key == -2)
- goto method
-
- getmenu "Accept plane (YES) ? ",\
- "NO",\
- "YES"
-
- on (@key+3) goto exit, plane, , , plane, plmat
-
- :plmat
- vmat[0] = @fltdat[1]
- vmat[1] = @fltdat[2]
- vmat[2] = @fltdat[3]
- vmat[3] = @fltdat[4]
- vmat[4] = @fltdat[5]
- vmat[5] = @fltdat[6]
- vmat[6] = @fltdat[7]
- vmat[7] = @fltdat[8]
- vmat[8] = @fltdat[9]
-
- :def_view
- REM define the view with ref. no. 10
-
- view 10, vmat[0], vmat[1], vmat[2],\
- vmat[3], vmat[4], vmat[5],\
- vmat[6], vmat[7], vmat[8]
-
- :directrix
- REM draw the directrix arrow to indicate the direction of the normal and
- REM determine which direction the cone should be extended.
-
- mode draw
- dx = vmat[2]/(2*@scale)
- dy = vmat[5]/(2*@scale)
- dz = vmat[8]/(2*@scale)
- line @xworld, @yworld, @zworld, @xworld+dx, @yworld+dy, @zworld+dz, 15
- call xfmwv, vmat, @xworld+dx, @yworld+dy, @zworld+dz, xc, yc, zc
- arr = 0.1/@scale
- circle xc, yc, zc, arr, 10, 15
- vline xc+arr, yc, zc, xc, yc, zc+2*arr, 10, 15
- vline xc-arr, yc, zc, xc, yc, zc+2*arr, 10, 15
- vline xc, yc+arr, zc, xc, yc, zc+2*arr, 10, 15
- vline xc, yc-arr, zc, xc, yc, zc+2*arr, 10, 15
- mode normal
-
- :dir
- getmenu "Draw cylinder in arrow direction or opposite direction ?",\
- "ARROW",\
- "OPPOSE"
-
- if (@key == -3)
- exit
- if (@key == -2)
- goto method
- if (@key == 2)
- len = -len
-
- def = 1
- :draw
- getpos "Indicate position for face center", def
- if (@key == -1)
- goto draw
- if (@key == -3)
- exit
- if (@key == -2)
- len = abs(len)
- if (@key == -2)
- goto dir
-
- def = @key
- x1 = @xworld
- y1 = @yworld
- z1 = @zworld
-
- call xfmwv, vmat, x1, y1, z1, xc, yc, zc
-
- REM Increment the total group number and check for overflow
-
- ptot = ptot + 1
- IF (ptot > 128)
- goto overflow
-
- REM Name and make the group.
-
- sprint $grp, "_cyl%d", ptot
- group $grp, ptot, 2
-
- inc = len/sect
-
- circle xc, yc, zc, rad, 10,,,, ptot, 2
- i = 1
- if (sect == 1)
- goto one
- :loop
- circle xc, yc, zc+i*inc, rad, 10,,,, ptot, 1
- i = i+1
- if (i < sect)
- goto loop
-
- :one
- circle xc, yc, zc+i*inc, rad, 10,,,, ptot, 2
-
- vline xc+rad, yc, zc, xc+rad, yc, zc+len, 10,,,, ptot, 2
- vline xc, yc+rad, zc, xc, yc+rad, zc+len, 10,,,, ptot, 1
- vline xc-rad, yc, zc, xc-rad, yc, zc+len, 10,,,, ptot, 1
- vline xc, yc-rad, zc, xc, yc-rad, zc+len, 10,,,, ptot, 1
- goto draw
-
- :overflow
- pause "Group overflow ... Abnormal termination"
- abort
-
- :exit
- exit
-