G2dEllipseCmdImpl.mesa
Copyright Ó 1985, 1992 by Xerox Corporation. All rights reserved.
Bloomenthal, July 20, 1992 1:10 pm PDT
DIRECTORY Args, Buttons, Commander, Controls, Draw2d, G2dBasic, G2dTool, RealFns, Rope, Vector2, ViewerClasses, ViewerOps;
G2dEllipseCmdImpl: CEDAR PROGRAM
IMPORTS Args, Buttons, Controls, Draw2d, G2dTool, RealFns, Rope, Vector2, ViewerOps
~ BEGIN
Types
Pair:    TYPE ~ G2dBasic.Pair;
EllipseData:  TYPE ~ REF EllipseDataRep;
EllipseDataRep: TYPE ~ RECORD [
viewer:     ViewerClasses.Viewer Ź NIL,
graphics:     ViewerClasses.Viewer Ź NIL,
a, b, scale:    Controls.Control Ź NIL,
show:      RECORD [ellipse, focci, derivs, accels: BOOL Ź TRUE],
focus1, focus2:   Pair Ź [0.0, 0.0],
points:     G2dBasic.PairSequence Ź NIL,
derivs:     G2dBasic.PairSequence Ź NIL,
accels:     G2dBasic.PairSequence Ź NIL
];
Display
G2dEllipse: Commander.CommandProc ~ {
incline, ecc, nPoints: Args.Arg;
[incline, ecc, nPoints] Ź Args.ArgsGet[cmd, "-incline%r-ecc%r-nPoints%i"
! Args.Error => {msg Ź reason; CONTINUE}];
IF msg # NIL
THEN RETURN[$Failure, usage]
ELSE {
B: PROC [name: Rope.ROPE] RETURNS [Controls.Button] ~ {
RETURN[Controls.ClickButton[Rope.Concat[name, ": On"], Button, e]];
};
e: EllipseData Ź NEW[EllipseDataRep];
nPts: INTEGER Ź IF nPoints.ok THEN nPoints.int ELSE 40;
e.points Ź NEW[G2dBasic.PairSequenceRep[nPts]];
e.derivs Ź NEW[G2dBasic.PairSequenceRep[nPts]];
e.accels Ź NEW[G2dBasic.PairSequenceRep[nPts]];
e.points.length Ź e.derivs.length Ź e.accels.length Ź nPts;
e.a Ź Controls.NewControl["a", vSlider, e, 0.0, 1.0, 0.5, EllipseControl];
e.b Ź Controls.NewControl["b", vSlider, e, 0.0, 1.0, 0.25, EllipseControl];
e.scale Ź Controls.NewControl["scale", vSlider, e, 0.0, 3.0, 1.0, EllipseControl];
ComputeEllipse[e];
e.viewer Ź Controls.OuterViewer[
name: "G2d Ellipse",
graphicsHeight: 200,
drawProc: DrawEllipse,
controls: LIST[e.a, e.b, e.scale],
buttons: LIST[B["Ellipse"], B["Focci"], B["Derivs"], B["Accels"]],
clientData: e].parent;
e.graphics Ź NARROW[e.viewer.data, Controls.OuterData].graphics;
};
};
Button: ViewerClasses.ClickProc ~ {
e: EllipseData Ź NARROW[clientData];
on: BOOL Ź SELECT TRUE FROM
Rope.Find[parent.name, "Ellipse"] # -1 => e.show.ellipse Ź NOT e.show.ellipse,
Rope.Find[parent.name, "Focci"] # -1 => e.show.focci Ź NOT e.show.focci,
Rope.Find[parent.name, "Derivs"] # -1 => e.show.derivs Ź NOT e.show.derivs,
ENDCASE          => e.show.accels Ź NOT e.show.accels;
Buttons.ReLabel[parent, Rope.Concat[Rope.Substr[parent.name, 0, Rope.Find[parent.name, ":"]+2], IF on THEN "On" ELSE "Off"]];
ViewerOps.PaintViewer[e.graphics, client, FALSE];
};
ComputeEllipse: PROC [e: EllipseData] ~ {
a: REAL Ź e.a.value*e.scale.value;
b: REAL Ź e.b.value*e.scale.value;
f: REAL Ź RealFns.SqRt[ABS[a*a-b*b]];
e.focus1 Ź IF a > b THEN [f, 0.0] ELSE [0.0, f];
e.focus2 Ź [-e.focus1.x, -e.focus1.y];
FOR n: NAT IN [0..e.points.length) DO
angle: REAL Ź REAL[n]*2.0*3.1415926535/REAL[e.points.length];
cos: REAL Ź RealFns.Cos[angle];
sin: REAL Ź RealFns.Sin[angle];
e.points[n] Ź [a*cos, b*sin];
e.derivs[n] Ź [-a*sin, b*cos];
e.accels[n] Ź [e.derivs[n].y, -e.derivs[n].x];
ENDLOOP;
};
EllipseControl: Controls.ControlProc ~ {
e: EllipseData Ź NARROW[control.clientData];
ComputeEllipse[e];
ViewerOps.PaintViewer[e.graphics, client, FALSE];
};
DrawEllipse: Draw2d.DrawProc ~ {
Action: PROC ~ {
TransformPoint: PROC [p: Pair] RETURNS [pp: Pair] ~ INLINE {
pp Ź [translate.x+scale*p.x, translate.y+scale*p.y];
};
TransformVector: PROC [p: Pair] RETURNS [pp: Pair] ~ INLINE {
pp Ź [scale*p.x, scale*p.y];
};
scale: REAL Ź 0.5*MIN[viewer.cw, viewer.ch];
translate: Pair Ź [0.5*viewer.cw, 0.5*viewer.ch];
e: EllipseData Ź NARROW[clientData];
p0: Pair Ź TransformPoint[e.points[e.points.length-1]];
FOR n: NAT IN [0..e.points.length) DO
p1: Pair Ź TransformPoint[e.points[n]];
deriv: Pair Ź TransformVector[e.derivs[n]];
IF e.show.ellipse
THEN Draw2d.Line[context, p0, p1];
IF e.show.derivs
THEN Draw2d.Arrow[context, p1, Vector2.Add[p1, TransformVector[e.derivs[n]]]];
IF e.show.accels
THEN Draw2d.Arrow[context, p1, Vector2.Add[p1, TransformVector[e.accels[n]]]];
p0 Ź p1;
ENDLOOP;
IF e.show.focci THEN {
Draw2d.Mark[context, TransformPoint[e.focus1], asterisk];
Draw2d.Mark[context, TransformPoint[e.focus2], asterisk];
};
};
Draw2d.DoWithBuffer[context, Action];
};
Start Code
usage: Rope.ROPE Ź "Test parametric representation of ellipse.";
G2dTool.Register["Ellipse", G2dEllipse, usage];
END.