pr-main.red 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. % %
  3. % PictureRLISP : A Lisp-Based Graphics Language System with %
  4. % Flexible Syntax and Hierarchical %
  5. % Data Structure %
  6. % %
  7. % Author: Fuh-Meei Chen, Paul Stay and Martin L. Griss %
  8. % Symbolic Computation Group %
  9. % Computer Science Dept. %
  10. % University of Utah %
  11. % %
  12. % <PSL.UTIL>PRLISP.RED.21, 9-Jan-82 22:47:43, Edit by GRISS %
  13. % <STAY.PICT>PRLISP.B 12-april-82 8:00:00 by Paul Stay %
  14. % changed bezier circle and bspline drivers and hp terminal %
  15. % on 10-april-82 by Paul Stay %
  16. % Added MPS support software for use on the graphics vax %
  17. % Added ST.INIT %
  18. % Copyright (c) 1981 University of Utah %
  19. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  20. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  21. % Part of the parser to accomplish the Pratt parser written %
  22. % in New-Rlisp runs at DEC-20. %
  23. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  24. RemFlag('(MKVECT),'TWOREG); %/ Seems in Error
  25. RemProp('!{,'NEWNAM!-OP); %. left and right brackets
  26. RemProp('!},'NEWNAM!-OP); %. handling.
  27. RemProp('!{,'NEWNAM); % left and right brackets are
  28. RemProp('!},'NEWNAM); % used to Define points.
  29. Put('!{, 'NEWNAM,'!*LBRAC!*);
  30. Put('!}, 'NEWNAM,'!*RBRAC!*); % Put on to the property list.
  31. DefineROP('!*LBRAC!*,NIL,LBC); % Define the precedence.
  32. DefineBOP('!*RBRAC!*,1,0);
  33. FLUID '(OP);
  34. Procedure LBC X;
  35. Begin scalar RES;
  36. If X EQ '!*RBRAC!* then
  37. <<OP := X; RES := '!*EMPTY!*>>
  38. else RES:= RDRIGHT(2,X);
  39. If OP EQ '!*RBRAC!* then
  40. OP := SCAN()
  41. else PARERR("Missing } after argument list",NIL);
  42. Return REPCOM('OnePoint,RES)
  43. end;
  44. Procedure REPCOM(TYPE,X); %. Create ARGLIST
  45. IF EQCAR(X,'!*COMMA!*) THEN (TYPE . CDR X)
  46. ELSE IF X EQ '!*EMPTY!* THEN LIST(TYPE)
  47. ELSE LIST(TYPE,X);
  48. RemProp('!_,'NEWNAM); %. underscore handling.
  49. Put('!_,'NEWNAM,'POINTSET); % "_" is used for Pointset.
  50. DefineBOP('POINTSET,17,18,NARY('POINTSET,X,Y));
  51. Put('!&,'NEWNAM,'GROUP); %. and sign handling.
  52. DefineBOP('GROUP,13,14,NARY('GROUP,X,Y)); % "&" is used for Group.
  53. Put('!|,'NEWNAM,'TRANSFORM); %. back slash handling.
  54. DefineROP('TRANSFORM,20, % "|" is used for transform.
  55. If EQCAR(X,'!*COMMA!*) then
  56. REPCOM('TRANSFORM,X));
  57. DefineBOP('TRANSFORM,15,16);
  58. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  59. % conversion of external Procedures to %
  60. % internal form. %
  61. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  62. % **************************************
  63. % conversion on structures of models. *
  64. % **************************************
  65. NExpr Procedure POINTSET L$
  66. 'POINTSET . L$
  67. NExpr Procedure GROUP L$
  68. 'GROUP . L$
  69. NExpr Procedure TRANSFORM L$
  70. 'TRANSFORM . L$
  71. % ***********************************
  72. % conversion on interpreter level *
  73. % Procedures. *
  74. % ***********************************
  75. Procedure BSPLINE;
  76. LIST 'BSPLINE;
  77. Procedure BEZIER;
  78. LIST 'BEZIER;
  79. Procedure LINE;
  80. LIST 'LINE;
  81. Procedure CIRCLE(R);
  82. LIST('CIRCLE,R);
  83. Procedure COLOR N;
  84. List('Color,N);
  85. Procedure REPEATED(COUNT,TRANS);
  86. LIST('REPEATED,COUNT,TRANS);
  87. BothTimes <<Procedure MKLIST L$
  88. 'LIST . L; >>;
  89. MACRO Procedure OnePoint L$
  90. LIST('MKPOINT, MKLIST CDR L)$
  91. MACRO Procedure MAT16 L;
  92. LIST('LIST2VECTOR, MKLIST (NIL. CDR L))$
  93. Procedure PNT4(X1,X2,X3,X4); % create a vector of a point
  94. Begin scalar V;
  95. V:=MKVECT 4;
  96. V[1]:=X1;
  97. V[2]:=X2;
  98. V[3]:=X3;
  99. V[4]:=X4;
  100. Return V;
  101. end;
  102. % %%%%%%%%%%%%%%%%%%%%%%%%%
  103. % PAIR KLUDGES %
  104. % %%%%%%%%%%%%%%%%%%%%%%%%%
  105. Procedure PRLISPCDR L$ %. PRLISPCDR of a list.
  106. If PAIRP L then CDR L else 'NIL$
  107. Procedure CAR1 L$ %. the Car1 element of
  108. If PAIRP L then CAR L else 'NIL$ %. a list.
  109. Procedure CAR2 L$ %. the CAR2 element of
  110. If LENGTH L > 1 then CADR L else 'NIL$ %. a list.
  111. Procedure CAR3 L$ %. the CAR3 element of
  112. If LENGTH L > 2 then CADDR L else 'NIL$ %. a list.
  113. Procedure CAR4 L$ %. the CAR4 element of
  114. If LENGTH L > 3 then CADDDR L else 'NIL$ %. a list.
  115. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  116. % interpreter supporting Procedures %
  117. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  118. Procedure V!.COPY V1$ %. Copy a vector
  119. Begin scalar N, V2$
  120. V2 := MKVECT(N := SIZE V1)$
  121. FOR I := 0 : N DO
  122. V2[I] := V1[I]$
  123. Return V2$
  124. end$
  125. % *********************
  126. % point primitive *
  127. % *********************
  128. Procedure MKPOINT (POINTLIST)$ %. make a vector form for
  129. Begin scalar P,I;
  130. P:=Pnt4(0,0,0,1);
  131. I:=1;
  132. While PairP PointList and I<=4 do
  133. <<P[I]:=Car PointList;
  134. I:=I+1;
  135. PointList:=Cdr PointList>>;
  136. Return P
  137. End;
  138. % **************************
  139. % initialize globals and *
  140. % and fluids *
  141. % set up for compiled *
  142. % version *
  143. % **************************
  144. FLUID '(
  145. DISPLAY!.LIST %. Used for object definition for MPS
  146. MAT!*0 %. 4 x 4 Zero Matrix
  147. MAT!*1 %. 4 x 4 Unit Matrix
  148. FirstPoint!* % FirstPoint of PointSet is MOVED to
  149. GLOBAL!.TRANSFORM %. Accumulation Transform
  150. CURRENT!.TRANSFORM
  151. CURRENT!.LINE %. Line Style
  152. CURRENT!.COLOR %. Default Color
  153. X1CLIP % Set by VWPORT for Clipping
  154. X2CLIP
  155. Y1CLIP
  156. Y2CLIP
  157. FourClip % Vector to return New Clipped point
  158. Xprevious
  159. Yprevious
  160. DEV!. % Device Name, set by xxx!.Init()
  161. )$
  162. Procedure SetUpVariables; % Intialize Globals and Fluids
  163. Begin
  164. MAT!*0 := MAT16 ( 0,0,0,0,
  165. 0,0,0,0,
  166. 0,0,0,0,
  167. 0,0,0,0)$
  168. MAT!*1 := MAT16 (1,0,0,0,
  169. 0,1,0,0,
  170. 0,0,1,0,
  171. 0,0,0,1)$ % unit matrix.
  172. GLOBAL!.TRANSFORM := MAT!*1$
  173. CURRENT!.TRANSFORM := MAT!*1$ % current transformation matrix
  174. % initialized as mat!*1.
  175. CURRENT!.LINE := 'LINE$
  176. CURRENT!.COLOR := 'BLACK$
  177. Xprevious := 0; Yprevious:=0;
  178. FourClip := PNT4(0,0,0,0);
  179. FirstPoint!* := NIL$
  180. End;
  181. % ---------------- BASIC Moving and Drawing -------------------
  182. % Project from Normalized 4 Vector to X,Y plane
  183. Procedure MoveToXY(X,Y)$ %. Move current cursor to x,y of P
  184. <<MoveS(X,Y);
  185. Xprevious := X;
  186. Yprevious := Y>>$
  187. Procedure DrawToXY(X,Y)$ %. Move cursor to "P" and draw from Previous
  188. <<DrawS(X,Y);
  189. Xprevious := X;
  190. Yprevious := Y>>$
  191. % **************************************
  192. % clipping-- on 2-D display screen *
  193. % **************************************
  194. Smacro procedure MakeFourClip(X1,Y1,X2,Y2);
  195. <<FourClip[1]:=x1; FourClip[2]:=y1;
  196. FourClip[3]:=x2; FourClip[4]:=y2;
  197. FourClip>>;
  198. Procedure InView (L);
  199. NULL(Car L) and NULL(cadr L) and NULL(caddr L) and NULL (cadddr L);
  200. Procedure CLIP2D (x1,y1,x2,y2); % Iterative Clipper
  201. Begin scalar P1,P2,TMP;
  202. % Newmann and Sproull
  203. P1 := TESTPOINT(x1,y1); % Classify EndPoints, get 4 List
  204. P2 := TESTPOINT(x2,y2);
  205. If InView(P1) and InView(P2) then Return MakeFourClip(x1,y1,X2,Y2);
  206. WHILE NOT(InView(P1) AND InView(P2) OR LOGICAND(P1,P2)) DO
  207. << If InView(P1) then % SWAP to get Other END
  208. <<TMP := P1$ P1 := P2$ P2 := TMP$
  209. TMP := X1$ X1 := X2$ X2 := TMP$
  210. TMP := Y1$ Y1 := Y2$ Y2 := TMP>>$
  211. If CADDDR P1 then
  212. <<Y1 := Y1 + ((Y2-Y1)*(X1CLIP-X1)) / (X2-X1)$
  213. X1 := X1CLIP>>
  214. else If CADDR P1 then
  215. <<Y1 := Y1 + ((Y2-Y1)*(X2CLIP-X1)) / (X2-X1)$
  216. X1 := X2CLIP>>
  217. else If CADR P1 then
  218. <<X1 := X1 + ((X2-X1)*(Y1CLIP-Y1)) / (Y2-Y1)$
  219. Y1 := Y1CLIP>>
  220. else If CAR P1 then
  221. <<X1 := X1 + ((X2-X1)*(Y2CLIP-Y1)) / (Y2-Y1)$
  222. Y1 := Y2CLIP>>$
  223. P1 := TESTPOINT(X1,Y1)>>; % reTest P1 after clipping
  224. If Not LOGICAND(P1,P2) then Return MakeFourClip(X1,Y1,X2,Y2);
  225. Return NIL
  226. end$
  227. Procedure LOGICAND (P1, P2)$ %. logical "and".
  228. (CAR P1 AND CAR P2) OR %. use in clipping
  229. (CADR P1 AND CADR P2) OR
  230. (CADDR P1 AND CADDR P2) OR
  231. (CADDDR P1 AND CADDDR P2) $
  232. Procedure TESTPOINT(x,y)$ %. test If "P"
  233. LIST (If y > Y2CLIP then T else NIL, %. inside the viewport.
  234. If y < Y1CLIP then T else NIL, %.used in clipping
  235. If x > X2CLIP then T else NIL,
  236. If x < X1CLIP then T else NIL)$
  237. % All NIL if Inside
  238. % **********************************
  239. % tranformation matrices *
  240. % matrices internal are stored as *
  241. % OnePoint = [x y z w] *
  242. % matrix = [v1 v5 v9 v13 *
  243. % v2 v6 v10 v14 *
  244. % v3 v7 v11 v15 *
  245. % v4 v8 v12 v16 ] *
  246. % **********************************
  247. %*******************************************************
  248. % Matrix Multiplication given two 4 by 4 matricies *
  249. %*******************************************************
  250. Procedure MAT!*MAT (V1,V2)$ %. multiplication of matrices.
  251. MAT16 ( % V1 and V2 are 4 by 4 matrices.
  252. V1[ 1] * V2[ 1] + V1[ 5] * V2[ 2] + V1[ 9] * V2[ 3] + V1[ 13] * V2[ 4],
  253. V1[ 2] * V2[ 1] + V1[ 6] * V2[ 2] + V1[ 10] * V2[ 3] + V1[ 14] * V2[ 4],
  254. V1[ 3] * V2[ 1] + V1[ 7] * V2[ 2] + V1[ 11] * V2[ 3] + V1[ 15] * V2[ 4],
  255. V1[ 4] * V2[ 1] + V1[ 8] * V2[ 2] + V1[ 12] * V2[ 3] + V1[ 16] * V2[ 4],
  256. V1[ 1] * V2[ 5] + V1[ 5] * V2[ 6] + V1[ 9] * V2[ 7] + V1[ 13] * V2[ 8],
  257. V1[ 2] * V2[ 5] + V1[ 6] * V2[ 6] + V1[ 10] * V2[ 7] + V1[ 14] * V2[ 8],
  258. V1[ 3] * V2[ 5] + V1[ 7] * V2[ 6] + V1[ 11] * V2[ 7] + V1[ 15] * V2[ 8],
  259. V1[ 4] * V2[ 5] + V1[ 8] * V2[ 6] + V1[ 12] * V2[ 7] + V1[ 16] * V2[ 8],
  260. V1[ 1] * V2[ 9] + V1[ 5] * V2[ 10] + V1[ 9] * V2[ 11] + V1[ 13] * V2[ 12],
  261. V1[ 2] * V2[ 9] + V1[ 6] * V2[ 10] + V1[ 10] * V2[ 11] + V1[ 14] * V2[ 12],
  262. V1[ 3] * V2[ 9] + V1[ 7] * V2[ 10] + V1[ 11] * V2[ 11] + V1[ 15] * V2[ 12],
  263. V1[ 4] * V2[ 9] + V1[ 8] * V2[ 10] + V1[ 12] * V2[ 11] + V1[ 16] * V2[ 12],
  264. V1[ 1] * V2[ 13] + V1[ 5] * V2[ 14] + V1[ 9] * V2[ 15] + V1[ 13] * V2[ 16],
  265. V1[ 2] * V2[ 13] + V1[ 6] * V2[ 14] + V1[ 10] * V2[ 15] + V1[ 14] * V2[ 16],
  266. V1[ 3] * V2[ 13] + V1[ 7] * V2[ 14] + V1[ 11] * V2[ 15] + V1[ 15] * V2[ 16],
  267. V1[ 4] * V2[ 13] + V1[ 8] * V2[ 14] + V1[ 12] * V2[ 15] + V1[ 16] * V2[ 16])$
  268. Procedure PNT!*PNT(U,V)$ %. multiplication of matrices
  269. U[1] * V[1] + %. 1 by 4 and 4 by 1.
  270. U[2] * V[2] + % Returning a value.
  271. U[3] * V[3] +
  272. U[4] * V[4] $
  273. Procedure PNT!*MAT(U,V)$ %. multiplication of matrices
  274. Begin scalar U1,U2,U3,U4$ %. 1 by 4 with 4 by 4.
  275. U1 := U[1]$ % Returning a 1 by 4 vector.
  276. U2 := U[2]$
  277. U3 := U[3]$
  278. U4 := U[4]$
  279. U:=Mkvect 4;
  280. u[1]:= U1 * V[1] + U2 * V[2] + U3 * V[3] + U4 * V[4];
  281. u[2]:= U1 * V[5] + U2 * V[6] + U3 * V[7] + U4 * V[8];
  282. u[3]:= U1 * V[9] + U2 * V[10] + U3 * V[11] + U4 * V[12];
  283. u[4]:= U1 * V[13] + U2 * V[14] + U3 * V[15] + U4 * V[16];
  284. Return U;
  285. end$
  286. % ************************************
  287. % set up perspective transformtion *
  288. % given eye and screen distances *
  289. % ************************************
  290. Procedure WINDOW(EYE,SCREEN)$ %. perspective transformation.
  291. Begin scalar SE$
  292. SE := SCREEN - EYE$ % EYE and SCREEN are distances
  293. Return MAT16(SE,0.0,0.0,0.0, % from eye and screen to
  294. 0.0,SE,0.0,0.0, % origin respectively.
  295. 0.0,0.0,SE,0.0,
  296. 0.0,0.0,1.0, -EYE)
  297. end$
  298. % **********************
  299. % translation *
  300. % **********************
  301. Procedure XMove (TX)$ %. x translation only
  302. Move (TX,0,0) $
  303. Procedure YMove (TY)$ %. y translation only
  304. Move (0,TY,0) $
  305. Procedure ZMove (TZ)$ %. z translation only
  306. Move (0,0,TZ) $
  307. Procedure Move (TX,TY,TZ)$ %. Move origin / object$
  308. MAT16 (1, 0, 0, TX, %. make a translation
  309. 0, 1, 0, TY, %. transformation matrix
  310. 0, 0, 1, TZ, %. [ 1 O O O
  311. 0, 0, 0, 1)$ %. 0 1 0 0
  312. %. 0 0 1 0
  313. %. Tx Ty Tz 1 ]
  314. % *******************
  315. % rotation *
  316. % *******************
  317. Procedure XROT (X)$ %. rotation about x
  318. FROTATE (X,2,3) $
  319. Procedure YROT (X)$ %. rotation about y
  320. FROTATE (X,3,1) $
  321. Procedure ZROT (X)$ %. rotation about z
  322. FROTATE (X,1,2) $
  323. Procedure FROTATE (THETA,I,J)$ %. scale factor
  324. Begin scalar S,C,W,TEMP$ %. i and j are the index
  325. %. values to set up matrix
  326. S := SIND (THETA)$ %. sin in degrees uses mathlib
  327. C := COSD (THETA)$ %. cos in degrees uses mathlib
  328. TEMP := V!.COPY MAT!*1;
  329. PutV (TEMP, 5 * I-4, C)$
  330. PutV(TEMP, 5 * J-4, C)$
  331. PutV (TEMP, I+4 * J-4,-S)$
  332. PutV (TEMP, J+4 * I-4, S)$
  333. Return TEMP
  334. end $
  335. %/ Need to add rotate about an AXIS
  336. % ******************
  337. % scaling *
  338. % ******************
  339. Procedure XSCALE (SX)$ %. scaling along X axis only.
  340. SCALE1 (SX,1,1) $
  341. Procedure YSCALE (SY)$ %. scaling along Y axis only.
  342. SCALE1 (1,SY,1) $
  343. Procedure ZSCALE (SZ)$ %. scaling along Z axis only.
  344. SCALE1 (1,1,SZ) $
  345. Procedure SCALE1(XT,YT,ZT)$ %. scaling transformation
  346. MAT16 ( XT, 0, 0, 0, %. matrix.
  347. 0 ,YT, 0, 0,
  348. 0 , 0,ZT, 0,
  349. 0 , 0, 0, 1)$
  350. Procedure SCALE SFACT; %. scaling along 3 axes.
  351. SCALE1(SFACT,SFACT,SFACT);
  352. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  353. % Procedure definitions %
  354. % in the interpreter %
  355. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  356. Put('OnePoint,'PBINTRP,'DrawPOINT)$
  357. Put('POINTSET,'PBINTRP,'DrawPOINTSET)$
  358. Put('GROUP,'PBINTRP,'DrawGROUP)$
  359. Put('TRANSFORM,'PBINTRP,'PERFORMTRANSFORM)$
  360. Put('PICTURE,'PBINTRP,'DrawModel)$
  361. Put('CIRCLE,'PBINTRP,'DrawCIRCLE)$
  362. Put('BEZIER,'PBINTRP,'DOBEZIER)$
  363. Put('LINE,'PBINTRP,'DOLINE)$
  364. Put('BSPLINE,'PBINTRP,'DOBSPLINE)$
  365. Put('REPEATED, 'PBINTRP,'DOREPEATED)$
  366. Put('Color,'pbintrp,'Docolor);
  367. %******************************************
  368. % SETUP Procedure FOR BEZIER AND BSPLINE *
  369. % LINE and COLOR
  370. %******************************************
  371. procedure DoColor(Object,N);
  372. Begin scalar SaveColor;
  373. SaveColor:=Current!.color;
  374. N:=Car1 N; % See CIRCLE example, huh?
  375. If IDP N then N:=EVAL N;
  376. ChangeColor N;
  377. Draw1(Object,CURRENT!.TRANSFORM);
  378. ChangeColor SaveColor;
  379. Return NIL;
  380. End;
  381. Procedure DOBEZIER OBJECT$
  382. Begin scalar CURRENT!.LINE$
  383. CURRENT!.LINE := 'BEZIER$
  384. Draw1(Object,CURRENT!.TRANSFORM);
  385. end$
  386. Procedure DOBSPLINE OBJECT$
  387. Begin scalar CURRENT!.LINE$
  388. CURRENT!.LINE := 'BSPLINE$
  389. Draw1(Object,CURRENT!.TRANSFORM);
  390. end$
  391. Procedure DOLINE OBJECT$
  392. Begin scalar CURRENT!.LINE$
  393. CURRENT!.LINE := 'LINE$
  394. Draw1(Object,CURRENT!.TRANSFORM);
  395. end$
  396. %*************************************
  397. % interpreted function calls *
  398. %*************************************
  399. Procedure DOREPEATED(MODEL,REPTFUN)$ %. repeat applying
  400. Begin scalar TEMP,I,TRANS,COUNT,TS,TA,GRP$ %. transformations.
  401. TRANS := PRLISPCDR REPTFUN$
  402. If LENGTH TRANS = 1 then
  403. TRANS := EVAL CAR1 TRANS
  404. else % "TRANS": transformation
  405. << TS :=CAR1 TRANS$ % matrix.
  406. TA := PRLISPCDR TRANS $ % "MODEL": the model.
  407. TRANS := APPLY(TS,TA) >> $ % "COUNT": the times "MODEL"
  408. COUNT := CAR1 REPTFUN$ % is going to be
  409. GRP := LIST('GROUP)$ % repeated.
  410. TEMP := V!.COPY TRANS$
  411. FOR I := 1 : COUNT DO
  412. << GRP := LIST('TRANSFORM,MODEL,TEMP) . GRP$
  413. TEMP := MAT!*MAT(TEMP,TRANS) >>$
  414. GRP := REVERSE GRP$
  415. Return GRP
  416. end$
  417. %***********************************
  418. % Define SHOW ESHOW Draw AND EDraw *
  419. % ESHOW AND EDraw ERASE THE SCREEN *
  420. %***********************************
  421. Procedure SHOW X; %. ALIAS FOR Draw
  422. <<
  423. If DEV!. = 'MPS then %. MPS driver don't call
  424. << %. echo functions for diplay
  425. %. device
  426. DISPLAY!.LIST := LIST (X, DISPLAY!.LIST);
  427. FOR EACH Z IN DISPLAY!.LIST DO
  428. If Z neq NIL then
  429. Draw1(Z,GLOBAL!.TRANSFORM); % Draw object list
  430. % to frame
  431. PSnewframe(); % display frame
  432. >>
  433. else
  434. << GraphOn(); % call echo off If not emode
  435. % If neccessary turn low level
  436. Draw1(X,GLOBAL!.TRANSFORM); % Draw model tekronix style
  437. GraphOff(); % call echoon
  438. >>;
  439. >>;
  440. Procedure ESHOW ZZ$ %. erases the screen and
  441. << Erase();
  442. GraphOn();
  443. DELAY();
  444. Draw1(ZZ,GLOBAL!.TRANSFORM); % Draw model tekronix style
  445. If DEV!. = 'MPS then << % Mps display frame
  446. PSnewframe();
  447. DISPLAY!.LIST := ZZ; >>;
  448. GraphOff();
  449. 0 >>;
  450. DefineROP('SHOW,10); %. set up precedence
  451. DefineROP('ESHOW,10);
  452. Procedure Draw X; %. ALIAS FOR SHOW
  453. SHOW X$
  454. Procedure EDraw ZZ$ %. erases the screen and
  455. ESHOW ZZ$
  456. DefineROP('Draw,10);
  457. DefineROP('EDraw,10);
  458. Procedure Col N; % User top-level color
  459. <<GraphOn(); ChangeColor N; GraphOff()>>;
  460. %*************************************
  461. % Define Draw FUNCTIONS FOR VARIOUS *
  462. % TYPES OF DISPLAYABLE OBJECTS *
  463. %*************************************
  464. Procedure DrawModel PICT$ %. given picture "PICT" will
  465. Draw1(PICT,CURRENT!.TRANSFORM)$ %. be applyied with global
  466. Procedure DERROR(MSG,OBJECT);
  467. <<PRIN2 " Draw Error `"; PRIN2T MSG;
  468. PRIN2 OBJECT; ERROR(700,MSG)>>;
  469. Procedure Draw1 (PICT,CURRENT!.TRANSFORM)$ % Draw PICT with TRANSFORMATION
  470. Begin scalar ITM,ITSARGS$
  471. If NULL Pict then Return NIL;
  472. If IDP PICT then PICT:=EVAL PICT;
  473. If VECTORP PICT AND SIZE(PICT)=4 then Return DrawPOINT PICT$
  474. If NOT PAIRP PICT then DERROR("Non Pair in Draw1: ",PICT);
  475. ITM := CAR1 PICT$
  476. ITSARGS := PRLISPCDR PICT$
  477. If NOT (ITM = 'TRANSFORM) then
  478. ITSARGS := LIST ITSARGS$ % gets LIST of args
  479. ITM := GET (ITM,'PBINTRP)$
  480. If NULL ITM then DERROR("Unknown Operator in Draw1:",PICT);
  481. APPLY(ITM,ITSARGS)$
  482. Return PICT$
  483. end$
  484. Procedure DrawGROUP(GRP)$ % Draw a group object
  485. Begin scalar ITM,ITSARGS,LMNT$
  486. If PAIRP GRP then
  487. FOR EACH LMNT IN GRP DO
  488. If PAIRP LMNT then Draw1 (LMNT,CURRENT!.TRANSFORM)
  489. else Draw1 (EVAL LMNT,CURRENT!.TRANSFORM)
  490. else Draw1 (EVAL GRP,CURRENT!.TRANSFORM)$
  491. Return GRP$
  492. end$
  493. Procedure DrawPOINTSET (PNTSET)$
  494. Begin scalar ITM,ITSARGS,PT$
  495. FirstPoint!* := 'T$
  496. If PAIRP PNTSET then
  497. << If CURRENT!.LINE = 'BEZIER then
  498. PNTSET := DrawBEZIER PNTSET
  499. else If CURRENT!.LINE = 'BSPLINE then
  500. PNTSET := DrawBSPLINE PNTSET$
  501. FOR EACH PT IN PNTSET DO
  502. <<If PAIRP PT then Draw1 (PT,CURRENT!.TRANSFORM)
  503. else Draw1 (EVAL PT,CURRENT!.TRANSFORM)$
  504. FirstPoint!* := 'NIL>> >>
  505. else Draw1 (EVAL PNTSET,CURRENT!.TRANSFORM)$
  506. Return PNTSET$
  507. end$
  508. Procedure DrawPOINT (PNT)$
  509. Begin scalar CLP,X1,Y1,W1,V,U1,U2,U3,U4;
  510. If IDP PNT then PNT := EVAL PNT$
  511. If PAIRP PNT then PNT := MKPOINT PNT;
  512. V:=CURRENT!.TRANSFORM;
  513. % Transform Only x,y and W
  514. U1:=PNT[1]; U2:=PNT[2]; U3:= PNT[3]; U4:=PNT[4];
  515. X1:=U1 * V[1] + U2 * V[2] + U3 * V[3] + U4 * V[4];
  516. Y1:=U1 * V[5] + U2 * V[6] + U3 * V[7] + U4 * V[8];
  517. W1:=U1 * V[13] + U2 * V[14] + U3 * V[15] + U4 * V[16];
  518. IF NOT (W1 = 1.0) then <<x1:=x1/w1; y1:=y1/w1>>;
  519. If FirstPoint!* then Return MoveToXY(X1,Y1);
  520. % back to w=1 plane If needed.
  521. CLP := CLIP2D(Xprevious,Yprevious, X1,Y1)$
  522. If CLP then <<MoveToXY(CLP[1],CLP[2])$
  523. DrawToXY(CLP[3],CLP[4])>>$
  524. end$
  525. Procedure PERFORMTRANSFORM(PCTSTF,TRNSFRM)$
  526. Begin scalar PROC,OLDTRNS,TRNSFMD,TRANSFOP,
  527. TRANSARG,ITM,ITSARGS$
  528. If IDP TRNSFRM then
  529. TRNSFRM := EVAL TRNSFRM$
  530. If VECTORP TRNSFRM AND SIZE(TRNSFRM) = 16 then
  531. Draw1 (PCTSTF,MAT!*MAT(TRNSFRM,CURRENT!.TRANSFORM))
  532. else If PAIRP TRNSFRM then
  533. <<TRANSFOP := CAR1 TRNSFRM$
  534. If (TRANSARG := PRLISPCDR TRNSFRM)
  535. then TRANSARG := LIST (PCTSTF,TRANSARG)
  536. else TRANSARG := LIST PCTSTF$
  537. If (TRANSFOP = 'BEZIER OR TRANSFOP = 'BSPLINE) then
  538. APPLY(GET(TRANSFOP,'PBINTRP),TRANSARG)
  539. else
  540. Draw1 (APPLY(GET(TRANSFOP,'PBINTRP),TRANSARG),
  541. CURRENT!.TRANSFORM) >>
  542. end$
  543. %***************************************
  544. % circle bezier and bspline functions *
  545. %***************************************
  546. Procedure DrawCIRCLE(CCNTR,RADIUS); %. Draw a circle with radius
  547. Begin scalar APNT,POLY,APNTX, APNTY$ %. "RADIUS".
  548. POLY := LIST('POINTSET)$
  549. If IDP CCNTR then CCNTR := EVAL CCNTR$
  550. RADIUS := CAR1 RADIUS$
  551. If IDP RADIUS then
  552. RADIUS := EVAL RADIUS$
  553. FOR ANGL := 180 STEP -15 UNTIL -180 DO % each line segment
  554. << APNTX := CCNTR[1] + RADIUS * COSD ANGL$ % represents an arc of 15 dgrs
  555. APNTY := CCNTR[2] + RADIUS * SIND ANGL$
  556. POLY := LIST('Onepoint,APNTX,APNTY) . POLY>>$
  557. Return REVERSE POLY
  558. end$
  559. Procedure DrawBSPLINE CONPTS$ %. a closed bspline curve
  560. Begin scalar N,TWOLIST,PX,PY,CURPTS, %. will be Drawn when given
  561. BSMAT,II,TFAC,CPX,CPY$ %. a polygon "CONPTS".
  562. BSMAT := MAT16 % " CONPTS" is a pointset.
  563. ( -0.166666, 0.5, -0.5, 0.166666,
  564. 0.5 , -1.0, 0.0, 0.666666,
  565. -0.5 , 0.5, 0.5, 0.166666,
  566. 0.166666, 0.0, 0.0, 0.0 )$
  567. CURPTS := NIL$
  568. N := LENGTH CONPTS$
  569. TWOLIST := APPend (CONPTS,CONPTS)$
  570. WHILE N > 0 DO
  571. << PX :=PNT4
  572. (GETV(CAR1 TWOLIST,1), GETV(CAR2 TWOLIST,1),
  573. GETV(CAR3 TWOLIST,1),GETV(CAR4 TWOLIST,1))$
  574. PY := PNT4
  575. (GETV(CAR1 TWOLIST,2), GETV(CAR2 TWOLIST,2),
  576. GETV(CAR3 TWOLIST,2), GETV(CAR4 TWOLIST,2))$
  577. FOR I := 0.0 STEP 1.0 UNTIL 4.0 DO
  578. << II := I/4.$
  579. TFAC := PNT4 (II*II*II, II*II, II, 1.)$
  580. TFAC := PNT!*MAT(TFAC,BSMAT)$
  581. CPX := PNT!*PNT(TFAC,PX)$
  582. CPY := PNT!*PNT(TFAC,PY)$
  583. CURPTS := LIST ('Onepoint, CPX, CPY) . CURPTS >>$
  584. N := N - 1$
  585. TWOLIST := PRLISPCDR TWOLIST >>$
  586. Return REVERSE CURPTS
  587. end$
  588. LISP Procedure DrawBEZIER CNTS;
  589. Begin
  590. scalar LEN, NALL, SAVEX, SAVEY, CPX, CPY,
  591. CURPTS, I, T0, TEMP, FACTL;
  592. CURPTS := NIL;
  593. SAVEX := NIL;
  594. SAVEY := NIL;
  595. LEN := LENGTH CNTS;
  596. FOR I := 1 STEP 1 UNTIL LEN DO
  597. <<
  598. SAVEX := GETV(CAR1 CNTS, 1) . SAVEX;
  599. SAVEY := GETV(CAR1 CNTS, 2) . SAVEY;
  600. CNTS := PRLISPCDR CNTS
  601. >>;
  602. SAVEX := LIST2VECTOR SAVEX;
  603. SAVEY := LIST2VECTOR SAVEY;
  604. NALL := 8.0 * (LEN - 1);
  605. FACTL := FACT (LEN - 1);
  606. T0 := 0.0;
  607. FOR T0 := 0.0 STEP 1.0 / NALL UNTIL 1.0 DO
  608. <<
  609. CPX := 0.0;
  610. CPY := 0.0;
  611. TEMP := 0.0;
  612. FOR I := 0 STEP 1 UNTIL LEN - 1 DO
  613. <<
  614. TEMP := FACTL / ((FACT I) * (FACT (LEN -1 - I))) *
  615. (T0 ** I) * (1.0 - T0)**(LEN -1 - I);
  616. CPX := TEMP * SAVEX[I] + CPX;
  617. CPY := TEMP * SAVEY[I] + CPY
  618. >>;
  619. CURPTS := LIST ('ONEPOINT, CPX, CPY, 0.0) . CURPTS
  620. >>;
  621. Return REVERSE CURPTS;
  622. end;
  623. procedure FACT N; % Simple factorial
  624. Begin scalar M;
  625. M:=1;
  626. for i:=1:N do M:=M*I;
  627. Return M;
  628. end;
  629. LoadTime SetUpVariables();