DIRECTORY Buttons, Commander, Draw2d, FS, G2dTool, Imager, MessageWindow, Random, Real, RealFns, Rope, TIPUser, ViewerClasses, ViewerOps, ViewerTools; G2dPrettyCurvesCmdImpl: CEDAR PROGRAM IMPORTS Buttons, Draw2d, FS, G2dTool, Imager, MessageWindow, Random, RealFns, Rope, TIPUser, ViewerOps, ViewerTools ~ BEGIN PaintData: TYPE ~ REF PaintDataRec; PaintDataRec: TYPE ~ RECORD [ viewer: ViewerClasses.Viewer ¬ NIL, x, y: REAL ¬ 10, cn: INT ¬ 0, random: Random.RandomStream ¬ Random.Create[range:21, seed:4] ]; VEC: TYPE ~ Imager.VEC; Abs: PUBLIC PROC [ival: REAL] RETURNS [REAL] = { IF ival > 0.0 THEN RETURN[ival] ELSE RETURN[-ival]; }; PrettyCurvesCmd: Commander.CommandProc ~ { pd: PaintData ¬ NEW[PaintDataRec]; pd.viewer ¬ ViewerOps.CreateViewer[ flavor: $Paint, info: [name: "2dPrettyCurves", data: pd]]; [] ¬ Buttons.Create[[parent: pd.viewer, name: "IP-Out ", wx: 3, wy: 20], IPOut, pd]; ViewerOps.OpenIcon[pd.viewer]; }; Complain: PROC [rope: Rope.ROPE] ~ { MessageWindow.Append[rope, TRUE]; MessageWindow.Blink[]; }; IPOut: ViewerClasses.ClickProc ~ { fileName: Rope.ROPE ¬ ViewerTools.GetSelectionContents[]; IF Rope.IsEmpty[fileName] THEN Complain["\t\tPlease select a filename first."] ELSE Draw2d.IPOut[fileName, DoDraw, clientData ! FS.Error => {Complain[Rope.Concat["Bad name: ", fileName]]; CONTINUE}]; }; PaintPaint: ViewerClasses.PaintProc ~ { DoDraw[context, self.data, whatChanged, self]; }; DoDraw: Draw2d.DrawProc ~ { paintData: PaintData ¬ NARROW[clientData]; pi: REAL ¬ 3.1415926535; theta, r: REAL; steps: INT ¬ 250; v1, v2: VEC ¬ [0, 0]; choice: INT ¬ 1; polar: BOOL ¬ FALSE; Imager.MaskRectangle[context, [paintData.x-10.0, paintData.y-10.0, 0.0, 0.0]]; Draw2d.Circle[context, [paintData.x, paintData.y], 0.0, FALSE]; choice ¬ paintData.cn; choice ¬ Random.NextInt[paintData.random]; FOR step: INT¬0, step+1 WHILE step <= steps DO theta¬(step*2.0*pi)/steps; SELECT choice FROM 0 => { -- circle v2.x¬RealFns.Cos[theta]; v2.y¬RealFns.Sin[theta]; }; 1 => { v2.x¬(.8 * RealFns.Sin[theta] + .2 * RealFns.Sin[7.0 * theta]); v2.y¬(.5 * RealFns.Cos[theta] + .5 * RealFns.Cos[9.0 * theta]); }; 2 => { v2.x¬(.6 * RealFns.Sin[theta] + .4 * RealFns.Sin[7.0 * theta]); v2.y¬(.3 * RealFns.Cos[theta] + .4 * RealFns.Cos[4.0 * theta]); }; 3 => { v2.x¬(.4 * RealFns.Sin[theta] + .6 * RealFns.Sin[9.0 * theta]); v2.y¬(.3 * RealFns.Cos[theta] + .4 * RealFns.Cos[6.0 * theta]); }; 4 => { v2.x¬(.8 * RealFns.Sin[theta] + (.2 * RealFns.Sin[7.0 * theta]) * .5 * (1.0 + Abs[RealFns.Cos[11.0 * theta]])); v2.y¬(.8 * RealFns.Cos[theta] + (.2 * RealFns.Cos[7.0 * theta]) * .5 * (1.0 + Abs[RealFns.Cos[11.0 * theta]])); }; 5 => { v2.x¬(RealFns.Sin[theta] * RealFns.Sin[3.0 * theta] * RealFns.Sin[5.0 * theta]); v2.y¬(RealFns.Sin[4.0 * theta] * RealFns.Cos[2.0 * theta] * RealFns.Cos[6.0 * theta]); }; 6 => { v2.x¬(RealFns.Sin[theta] * RealFns.Cos[3.0 * theta] * RealFns.Sin[5.0 * theta]); v2.y¬(RealFns.Sin[2.0 * theta] * RealFns.Cos[4.0 * theta] * RealFns.Sin[6.0 * theta]); }; 7 => { v2.x¬.5 * (RealFns.Sin[3.0 * theta] + RealFns.Sin[4.0 * theta]); v2.y¬.5 * (RealFns.Sin[theta] + RealFns.Sin[2.0 * theta]); }; 8 => { v2.x¬.5 * (RealFns.Sin[3.0 * theta] + RealFns.Sin[5.0 * theta]); v2.y¬.5 * (RealFns.Sin[2.0 * theta] + RealFns.Sin[4.0 * theta]); }; 9 => { v2.x¬.5 * (RealFns.Sin[3.0 * theta] + RealFns.Cos[5.0 * theta]); v2.y¬.5 * (RealFns.Sin[2.0 * theta] + RealFns.Sin[4.0 * theta]); }; 10 => { v2.x¬0.25 * (RealFns.Sin[theta] + RealFns.Sin[3.0 * theta] + RealFns.Cos[5.0 * theta] + RealFns.Cos[7.0 * theta]); v2.y¬0.25 * (RealFns.Sin[2.0 * theta] + RealFns.Sin[4.0 * theta] + RealFns.Cos[6.0 * theta] + RealFns.Cos[8.0 * theta]); }; 11 => { v2.x¬(.8 * RealFns.Cos[theta] + .2 * RealFns.Sin[9.0 * theta]); v2.y¬(.8 * RealFns.Sin[theta] + .2 * RealFns.Sin[3.0 * theta]); }; 12 => { v2.x¬0.5 * (RealFns.Sin[4.0 * theta] + RealFns.Sin[7.0 * theta]); v2.y¬0.5 * (RealFns.Sin[3.0 * theta] + RealFns.Sin[2.0 * theta]); }; 13 => { v2.x¬ 0.5 * (RealFns.Sin[3.0 * theta] + RealFns.Sin[4.0 * theta]); v2.y¬0.5 * (RealFns.Sin[3.0 * theta] + RealFns.Sin[2.0 * theta]); }; 14 => { r ¬ RealFns.Sin[RealFns.Exp[RealFns.Cos[2.0*theta]]] + RealFns.Cos[RealFns.Exp[RealFns.Sin[5.0*theta]]]; polar ¬ TRUE; v2.x ¬ RealFns.Sin[r]; v2.y ¬ RealFns.Cos[r]; }; 15 => { r ¬ Abs[RealFns.Sin[2.0*theta]] + Abs[RealFns.Sin[3.0*theta]]; polar ¬ TRUE; }; 16 => { r ¬ RealFns.Cos[Abs[RealFns.Sin[5.0*theta]]] + RealFns.Sin[Abs[RealFns.Cos[2.0*theta]]] ; polar ¬ TRUE; }; 17 => { r ¬ Abs[RealFns.Sin[6.0*theta]] + Abs[RealFns.Sin[3.0*theta]]; polar ¬ TRUE; }; 18 => { r ¬ RealFns.Sin[6.0*theta] + RealFns.Sin[3.0*theta]; polar ¬ TRUE; }; 19 => { r ¬ RealFns.Sin[2.0*theta] * RealFns.SqRt[Abs[RealFns.Cos[2.0*theta]]] * RealFns.SqRt[Abs[RealFns.Sin[5.0*theta]]]; polar ¬ TRUE; }; 20 => { r ¬ RealFns.SqRt[Abs[RealFns.Cos[2.0*theta]]] + RealFns.SqRt[Abs[RealFns.Sin[5.0*theta]]]; polar ¬ TRUE; }; 21 => { r ¬ RealFns.Sin[RealFns.SqRt[Abs[RealFns.Cos[theta]]]] * RealFns.Sin[6.0*theta]; polar ¬ TRUE; paintData.cn ¬ 0; }; ENDCASE => NULL; IF polar = TRUE THEN { v2.x ¬ 0.8*r*RealFns.Sin[theta]; v2.y ¬ 0.8*r*RealFns.Cos[theta]; }; v2.x ¬ (v2.x * 200.0) + paintData.x; v2.y ¬ (v2.y * 200.0) + paintData.y; IF step > 0 THEN Imager.MaskVector[context, v1, v2]; v1 ¬ v2; ENDLOOP; }; NotifyPaint: ViewerClasses.NotifyProc = { paintData: PaintData ¬ NARROW[self.data]; mouse: TIPUser.TIPScreenCoords ¬ NARROW[input.first]; SELECT input.rest.first FROM $move => { paintData.x ¬ mouse.mouseX; paintData.y ¬ mouse.mouseY; paintData.cn ¬ paintData.cn + 1; ViewerOps.PaintViewer[self, client] }; ENDCASE => NULL; }; ViewerOps.RegisterViewerClass[ $Paint, NEW[ViewerClasses.ViewerClassRec ¬ [ paint: PaintPaint, notify: NotifyPaint, tipTable: TIPUser.InstantiateNewTIPTable["G2dPlot.tip"] ]] ]; G2dTool.Register["PrettyCurves", PrettyCurvesCmd, "Draw some pretty parametric curves"]; END. * G2dPrettyCurvesCmdImpl.mesa Copyright Σ 1985, 1992 by Xerox Corporation. All rights reserved. Bloomenthal, July 20, 1992 1:09 pm PDT Glassner, September 26, 1988 12:40:53 pm PDT Type Declarations Procedures Start Code paintIcon: Icons.IconFlavor _ Icons.NewIconFromFile["Paint.icon", 0]; ΚΤ–"cedarcode" style•NewlineDelimiter ™™Jšœ Οeœ6™BJ™&J™,J™—JšΟk œ˜–J˜šΟnœžœž˜%Jšžœl˜sJ˜—Jšœž˜headšΟl™Jšœ žœžœ˜$šœ žœžœ˜Jšœ#žœ˜'Jšœž œ˜Jšœ žœ˜J˜BJ˜—Jšžœžœ žœ˜—š  ™ š Ÿœžœžœžœžœžœ˜0Jš žœ žœžœžœžœ˜3J˜J˜—šŸœ˜*Jšœžœ˜"•StartOfExpansionΏ[flavor: ViewerClasses.ViewerFlavor, info: ViewerClasses.ViewerRec _ [class: NIL, wx: 0, wy: 0, ww: 0, wh: 0, cx: 0, cy: 0, cw: 0, ch: 0, lock: [process: PROCESS#0B, count: 0B (0)], tipTable: NIL, name: NIL, file: NIL, label: NIL, menu: NIL, icon: 177777B?, column: left, caption: FALSE, scrollable: TRUE, hscrollable: FALSE, iconic: TRUE, border: TRUE, newVersion: FALSE, newFile: FALSE, visible: TRUE, offDeskTop: FALSE, destroyed: FALSE, init: FALSE, saveInProgress: FALSE, inhibitDestroy: FALSE, guardDestroy: FALSE, paintingWedged: FALSE, ...], paint: BOOL _ TRUE]˜#Jšœ˜Jšœ*˜*—J˜UJšœ˜J˜J˜—–y -- [self: ViewerClasses.Viewer, context: Imager.Context, whatChanged: REF ANY, clear: BOOL] RETURNS [quit: BOOL _ FALSE]šŸœžœ žœ˜$Jšœžœ˜!J˜J˜J˜—šŸœ˜"Jšœžœ&˜9šžœ˜Jšžœ0˜4šžœ*˜.Jšœžœ:žœ˜I——J˜J˜—šŸ œ˜'Jšœ.˜.J˜J˜—šŸœ˜Jšœžœ ˜*Jšœžœ˜Jšœ žœ˜Jšœžœ˜Jšœžœ ˜Jšœžœ˜Jšœžœžœ˜J˜NJ˜?J˜J˜*šžœžœ žœž˜.J˜šžœž˜šœ Οc ˜J˜J˜J˜—˜ J˜?J˜?J˜—˜ J˜?J˜?J˜—˜ J˜?J˜?J˜—˜ ˜ JšœO˜O—˜ JšœO˜O—J˜—˜ J˜PJ˜VJ˜—˜ J˜PJ˜VJ˜—˜ J˜@J˜:J˜—˜ J˜@J˜@J˜—˜ J˜@J˜@J˜—˜ J˜rJ˜xJ˜—˜ J˜?J˜?J˜—˜ J˜AJ˜AJ˜—˜ J˜BJ˜AJ˜—˜J˜hJšœžœ˜ J˜.J˜—˜J˜>Jšœžœ˜J˜—˜J˜YJšœžœ˜J˜—˜J˜>Jšœžœ˜ J˜—˜J˜4Jšœžœ˜ J˜—˜J˜sJšœžœ˜ J˜—˜J˜ZJšœžœ˜ J˜—˜J˜PJšœžœ˜ J˜˜J˜——Jšžœžœ˜—J˜šžœ žœžœ˜J˜BJšœ˜—J˜&J˜$Jšžœ žœ$˜4J˜Jšžœ˜—J˜J˜—šŸ œ˜)Jšœžœ ˜)Jšœ!žœ˜5šžœž˜šœ ˜ J˜J˜J˜ Jšœ#˜#J˜—Jšžœžœ˜—J˜——š  ™ JšœE™EJ˜šœ˜Jšœ˜šžœ!˜$Jšœ˜Jšœ˜Jšœ7˜7Jšœ˜—Jšœ˜J˜—J˜X—J˜Jšžœ˜—…—0 .