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.