--JaMConformal.mesa
--Written by J. Warnock
--Last changed by Maureen Stone January 31, 1984 4:51:22 pm PST
DIRECTORY
 JaM,
 CGSpline,
 CGOutlines,
 ParametricMap,
 TJaMGraphics USING [Painter],
 RealFns,
 Graphics,
 GraphicsBasic USING[Vec],
 Rope USING [ROPE],
 CGCubic USING[Bezier];

JaMConformal: CEDAR PROGRAM
IMPORTS JaM, RealFns, CGOutlines, Graphics, ParametricMap, TJaMGraphics =
BEGIN OPEN JaM,ParametricMap,RealFns,GraphicsBasic,CGCubic;

--AnulusMapper takes wu,wv,r,w,alpha,beta and sets up the conformal mapping proc.

AnulusMapper:PROC[state: State]= TRUSTED
{beta←PopReal[state];
alpha←PopReal[state];
w←PopReal[state];
r←PopReal[state];
wv←PopReal[state];
wu←PopReal[state];
a←w/wv;
b←r-w;
c←(beta-alpha)/wu;
SetMap[CirMapper];};

DAnulusMapper:PROC[state: State]= TRUSTED
{beta←PopReal[state];
alpha←PopReal[state];
w←PopReal[state];
r←PopReal[state];
wv←PopReal[state];
wu←PopReal[state];
SetMap[DMapper];};

EQuadrantMapper:PROC[state: State]= TRUSTED
{SetMap[EMapper]};

SetCubicScale:PROC[state: State]=
{ywidth←PopReal[state];
xwidth←PopReal[state];
};

BezierMapper:PROC[state: State]=TRUSTED
{bz.b3←GetPoint[state];
bz.b2←GetPoint[state];
bz.b1←GetPoint[state];
bz.b0←GetPoint[state];
SetMap[BMapper];};


CirMapper:PROC[u:Vec] RETURNS [t:Vec]=
{pr,pt:REAL;
pr𡤊*u.y+b;
pt𡤌*u.x+alpha;
t.x←pr*CosDeg[pt];
t.y←pr*SinDeg[pt];
RETURN;};

FromPolar: PROCEDURE [r: REAL, radians: REAL] RETURNS [Vec] = INLINE
 {RETURN[[r*RealFns.Cos[radians], r*RealFns.Sin[radians]]]};

Exp: PROCEDURE [a: Vec] RETURNS [Vec] = INLINE
 {RETURN[FromPolar[RealFns.Exp[a.x], a.y]]};

BMapper: PROC[u:Vec] RETURNS [v:Vec]=TRUSTED
{pos,dc:Vec;
sccs:BOOLEAN;
t:REAL;
[sccs,t]←GetTforArc[@bz,u.x*xwidth];
[pos,dc]←GetDirCos[t,@bz];
v.x←pos.x-dc.y*ywidth*u.y;
v.y←pos.y+dc.x*ywidth*u.y;
};

CMapper: PROC[u:Vec] RETURNS [v:Vec]=
{RETURN[CGOutlines.GetMappedVec[outref,Vec[u.x*xwidth,u.y*ywidth]]];
};


DMapper:PROC[u:Vec] RETURNS [t:Vec]=
{t ← Exp[[RealFns.Ln[r-w]+(u.y*(beta-alpha)/wv)*3.141593/180, (alpha+u.x*(beta-alpha)/wu)*3.141593/180]]};

EMapper: PROC[u:Vec] RETURNS [t:Vec]=
{x,y: REAL;
x←u.x/10*4-2;
y←u.y/10*4-2;
--[x,y] ← TenPoint.f[x, y];
t ← [x,y];};

path: Graphics.Path ← Graphics.NewPath[];
CMoveTo: PROC[state: State] = {
 t,r: Vec;
 move: SAFE PROC[dc: Graphics.Context] = TRUSTED{r←MapMoveTo[dc, t]};
 t←GetPoint[state];
 TJaMGraphics.Painter[move,state];
 Graphics.MoveTo[path,r.x,r.y,FALSE];
};

CCurveTo: PROC[state: State] = {
 t1,t2,t3: Vec;
 Point:PROC[v:Vec]={Graphics.LineTo[path,v.x,v.y];};
 t3←GetPoint[state];
 t2←GetPoint[state];
 t1←GetPoint[state];
 TRUSTED {MapCurveTo[t1,t2,t3,Point]};
 };

CLineTo: PROC[state: State] = {
 t: Vec;
 point:PROC[v:Vec]={Graphics.LineTo[path,v.x,v.y];};
 t←GetPoint[state];
 TRUSTED {MapLineTo[t,point]};
 };

CDrawStroke: PROC[state: State] = {
 width: REAL ← PopReal[state];
 drawstroke: PROC[dc: Graphics.Context] = {Graphics.DrawStroke[dc,path,width]};
 TJaMGraphics.Painter[drawstroke,state];
 Graphics.FlushPath[path];
 };

CDrawArea: PROC[state: State] = {
 drawarea: PROC[dc: Graphics.Context] = {Graphics.DrawArea[dc,path]};
 TJaMGraphics.Painter[drawarea,state];
 Graphics.FlushPath[path];
 };


CGetArc:PROC[state: State] =TRUSTED
 {PushReal[state,ArcLength[@bz]];};


CGetTfromArc:PROC[state: State] =TRUSTED
 {success:BOOLEAN;
 t,arclength:REAL;
 arclength←PopReal[state];
 [success,t]←GetTforArc[@bz,arclength];
 PushReal[state,t];
 PushBool[state,success];};

  
JGetDirCos:PROC[state: State] =TRUSTED
 {p,d:Vec;
 t:REAL←PopReal[state];
 [p,d]←GetDirCos[t,@bz];
 PushReal[state,p.x];
 PushReal[state,p.y];
 PushReal[state,d.x];
 PushReal[state,d.y];
 };
   
GetPoint: PROC[state: State] RETURNS[p: Vec] = {
 p.y ← PopReal[state];
 p.x ← PopReal[state];
 };

outref:CGOutlines.Ref;

OStartOutline:PROC[state: State]=TRUSTED
{outref𡤌GOutlines.New[16];
SetMap[CMapper];
};

OMoveTo:PROC[state: State]=
{p:Vec←GetPoint[state];
CGOutlines.MoveTo[outref,p];};

OLineTo:PROC[state: State]=
{p:Vec←GetPoint[state];
CGOutlines.LineTo[outref,p];};

OCurveTo:PROC[state: State]=
{v1,v2,v3:Vec;
v3←GetPoint[state];
v2←GetPoint[state];
v1←GetPoint[state];
CGOutlines.CurveTo[outref,v1,v2,v3];};

OClose:PROC[state: State]=
{CGOutlines.Close[outref];};

TestMap:PROC[state: State]=
{p,q:Vec;
p←GetPoint[state];
q𡤌GOutlines.GetMappedVec[outref,p];
PushReal[state, q.x];
PushReal[state, q.y];};

OutlineLength:PROC[state: State]=
{PushReal[state, outref.sum];};

OLinkLength:PROC[state: State]=
{i:NAT;
i�S[PopInt[state]];
PushReal[state, CGOutlines.GetLinkLength[outref,i]];
};

OLinkCnt:PROC[state: State]=
{PushInt[state, CGOutlines.GetLinkCount[outref]];
};

bz:Bezier;
wu,wv,r,w,alpha,beta,a,b,c:REAL;
xwidth:REAL𡤁
ywidth:REAL𡤁
Init: PROC [state: JaM.State] = {
Register[state,".cmoveto",CMoveTo];
Register[state,".clineto",CLineTo];
Register[state,".ccurveto",CCurveTo];
Register[state,".cdrawarea",CDrawArea];
Register[state,".cdrawstroke",CDrawStroke];
Register[state,".canulus",AnulusMapper];
Register[state,".danulus",DAnulusMapper];
Register[state,".equadrant",EQuadrantMapper];
Register[state,".cubicmapper",BezierMapper];
Register[state,".getdircos",JGetDirCos];
Register[state,".gettforarc",CGetTfromArc];
Register[state,".getarc",CGetArc];
Register[state,".cubicscale",SetCubicScale];
Register[state,".newoutline",OStartOutline];
Register[state,".omoveto",OMoveTo];
Register[state,".olineto",OLineTo];
Register[state,".ocurveto",OCurveTo];
Register[state,".oclose",OClose];
Register[state,".olength",OutlineLength];
Register[state,".osize",OLinkCnt];
Register[state,".olink",OLinkLength];
Register[state,".testmap",TestMap];
};

JaM.RegisterInit[name: "JaMConformal", init: Init];



END.