home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 March
/
Chip_1998-03_cd.bin
/
tema
/
MINICAD
/
MC7DEMO
/
MINICAD.1
/
ELBO_REC.MPC
< prev
next >
Wrap
Text File
|
1997-04-30
|
12KB
|
469 lines
Procedure DrawElbow;
{
⌐1996, Diehl Graphsoft, Inc.
Developed by Frank Brault
Last modified: 4/3/97
}
CONST
MaxPoints = 10;
kLineSize = 12;
kFilledPat = 5;
kPlainPat = 1;
kDashedLine = -2;
kLinedOffset = 1.0;
VAR
han1, han2 : HANDLE;
tempx,tempy : REAL;
a,b,c,d,e,f,g,h,i,j,m,n,L,r1,Alpha,theta : REAL;
x0,y0,x1,y1,x2,y2,L1x0,L1y0,L2x0,L2y0 : REAL;
clickX1,clickY1,clickX2,clickY2,qx1,qy1,qx2,qy2 : REAL;
verX1,verY1,verX2,verY2 : REAL;
x,y,xp,yp,R : ARRAY[1..MaxPoints] OF REAL;
xL1,yL1,xL2,yL2,RL1,RL2: ARRAY[1..3] OF REAL;
k,nPoints,dlogX1,dlogX2,item,quadrant,whichKey : INTEGER;
finished,cancel,aboveHor,leftOfVer : BOOLEAN;
lined,filled,insulated,labeled : BOOLEAN;
px1,py1,px2,py2,px3,py3,px4,py4 : INTEGER;
PROCEDURE switch(VAR first,second:REAL);
VAR
temporary:REAL;
BEGIN
{** Exchanges value in first with value in second}
temporary:=first;
first := second;
second := temporary;
END;
Procedure DrawPolyPoint(x,y,R : REAL);
{** This procedure draws a polyline point based on the value of R:
R = 0 ==> Corner point
R > 0 ==> Arc point of radius, R
R = -1 ==> Cubic spline point
R = any value less than 0 except -1
==> Bezier control point }
BEGIN
IF R = 0 THEN
LineTo(x,y)
ELSE IF R > 0 THEN
ArcTo(x,y,R)
ELSE IF R = -1 THEN
CurveThrough(x,y)
ELSE
CurveTo(x,y);
END; {of DrawPolyPoint}
Function xt(x,y,x0,y0,Alpha:REAL) : REAL;
{** This function transforms the x-coordinate of a point
relative to the x,y axis to an axis passing through
x0,y0 at an angle, Alpha. }
VAR
A : REAL;
BEGIN
A:=Deg2Rad(Alpha);
xt:=x0 + x*Cos(A) - y*Sin(A);
END; {of Function xt}
Function yt(x,y,x0,y0,Alpha:REAL) : REAL;
{** This function transforms the y-coordinate of a point
relative to the x,y axis to an axis passing through
x0,y0 at an angle, Alpha. }
VAR
A : REAL;
BEGIN
A:=Deg2Rad(Alpha);
yt:=y0 + y*Cos(A) + x*Sin(A);
END; {of Function yt}
FUNCTION clickOnWhatSide(x1,y1,x2,y2,clickX,clickY:REAL):BOOLEAN;
{** This function determines the side of the line
that point clickX,clickY is on. It will return
an unpredictable result if x1,y1 and x2,y2
are the same. }
VAR
M,B : REAL;
whichSide : BOOLEAN;
BEGIN
IF (x1 <> x2) AND (y1 <> y2) THEN
BEGIN
M := (y1-y2) / (x1-x2);
B := y1 - (M * x1);
IF clickY > (M * clickX) + B THEN whichSide := true
ELSE whichSide := false;
IF x1 < X2 THEN whichSide := NOT(whichSide);
END;
IF x1 = x2 THEN
BEGIN
IF (y1 > y2) AND (clickX > x1) THEN whichSide := false;
IF (y1 > y2) AND (clickX < x1) THEN whichSide := true;
IF (y1 < y2) AND (clickX > x1) THEN whichSide := true;
IF (y1 < y2) AND (clickX < x1) THEN whichSide := false;
END;
IF y1 = y2 THEN
BEGIN
IF (x1 > x2) AND (clickY > y1) THEN whichSide := true;
IF (x1 > x2) AND (clickY < y1) THEN whichSide := false;
IF (x1 < x2) AND (clickY > y1) THEN whichSide := false;
IF (x1 < x2) AND (clickY < y1) THEN whichSide := true;
END;
clickOnWhatSide := whichSide;
END;
PROCEDURE CenterDialog(dX1,dX2 : INTEGER; VAR x1,x2 : INTEGER);
{** This procedure calculates the horizontal center of the user screen
and returns the start and stop X values in screen coordinates. }
VAR
scrX1,scrY1,scrX2,scrY2,w : INTEGER;
BEGIN
GetScreen(scrX1,scrY1,scrX2,scrY2);
w := dX2 - dX1;
x1 := ((scrX1 + scrX2) DIV 2) - (w DIV 2);
x2 := x1 + w;
END;
Procedure LocateButtons2(scnh,scnw : INTEGER);
{
This procedure locates the 'OK' and 'Cancel' buttons centered at the bottom of the dialog box.
}
VAR
v1,v2,v3,v4 : INTEGER;
Procedure Swap(VAR m1,m2,m3,m4 : INTEGER);
VAR
Temp : INTEGER;
BEGIN
Temp:=m1;
m1:=m3;
m3:=Temp;
Temp:=m2;
m2:=m4;
m4:=Temp;
END; {of Swap}
BEGIN
px1:=scnw - 180;
px2:=scnw - 110;
px3:=scnw - 90;
px4:=scnw - 20;
py1:=scnh-40;
py2:=scnh-20;
py3:=py1;
py4:=py2;
GetVersion(v1,v2,v3,v4);
IF v4 = 1 THEN Swap(px1,px2,px3,px4);
END; {of Locate Buttons2}
{** Main program **}
BEGIN
pushAttrs;
ANGLEVAR;
FillFore(0,0,0);
PenSize(kLineSize);
{** Get angle with respect to x-axis and inside radius dimension of object.}
CENTERDIALOG(0,384,dlogX1,dlogX2);
LocateButtons2(152,384);
BEGINDIALOG(1,1,dlogX1,192,dlogX2,344);
ADDBUTTON('OK',1,1,px1,py1,px2,py2);
ADDBUTTON('Cancel',2,1,px3,py3,px4,py4);
ADDFIELD('Enter the elbow angle and the inside radius:',3,1,13,9,325,27);
ADDFIELD('Angle:',4,1,48,47,93,65);
ADDFIELD('Radius:',5,1,41,76,93,94);
ADDFIELD('90í',6,2,105,46,145,61);
ADDFIELD('12"',7,2,105,75,145,91);
ADDBUTTON('Lined',8,2,180,46,240,61);
ADDBUTTON('Filled',9,2,275,46,335,61);
ADDBUTTON('Insulated',10,2,180,75,260,91);
ADDBUTTON('Labeled',11,2,275,75,345,91);
ENDDIALOG;
GetDialog(1);
finished := FALSE;
cancel:= FALSE;
SetTitle('Create Elbow');
REPEAT DialogEvent(item);
IF item = 2 THEN
BEGIN
finished := TRUE;
cancel := TRUE;
END;
IF item = 1 THEN finished := TRUE;
IF item > 7 THEN SetItem(item, not(ItemSel(item)));
UNTIL finished;
theta := Deg2Rad(Str2Num(GetField(6)));
r1:=Str2Num(GetField(7));
lined := ItemSel(8);
filled := ItemSel(9);
insulated := ItemSel(10);
labeled := ItemSel(11);
CLRDIALOG;
IF NOT(cancel) THEN
BEGIN
{** Get angle and baseline of object. }
MESSAGE('Draw the baseline of the elbow...');
GetLine(x1,y1,x2,y2);
IF NOT((x1 = x2) AND (y1 = y2)) THEN
BEGIN
{IF (y1 < y2) THEN
BEGIN
Switch(y1,y2);
Switch(x1,x2);
END;}
IF (x1 > x2) THEN
BEGIN
Switch(y1,y2);
Switch(x1,x2);
END;
L:=Distance(x1,y1,x2,y2);
Alpha:=Rad2Deg(ArcCos((x2-x1)/L));
IF y2 < y1 THEN Alpha:=360 - Alpha;
{** Draw a cross and get direction of object with respect to x-axis.}
pushAttrs;
PenSize(1);
PenFore(65535,0,0);
MoveTo(x1,y1);
LineTo(x2,y2);
han1:=LObject;
qx1 := xt(L/2,-L/2,x1,y1,Alpha);
qy1 := yt(L/2,-L/2,x1,y1,Alpha);
MOVETO(qx1,qy1);
qx2 := xt(L/2,L/2,x1,y1,Alpha);
qy2 := yt(L/2,L/2,x1,y1,Alpha);
LineTo(qx2,qy2);
han2:=LObject;
Redraw;
popAttrs;
MESSAGE('Click in the quadrant of the desired elbow bend.');
GetPt(clickX1,clickY1);
leftOfVer := clickOnWhatSide(x1,y1,x2,y2,clickX1,clickY1);
aboveHor := clickOnWhatSide(qX1,qY1,qX2,qY2,clickX1,clickY1);
IF aboveHor AND NOT(leftOfVer) THEN quadrant := 1;
IF aboveHor AND leftOfVer THEN quadrant := 2;
IF NOT(aboveHor) AND leftOfVer THEN quadrant := 3;
IF NOT(aboveHor) AND NOT(leftOfVer) THEN quadrant := 4;
{** Determine the insertion point of object.}
IF (quadrant = 1) | (quadrant = 2) THEN
BEGIN
x0:=x2;
y0:=y2;
IF lined THEN
BEGIN
L1x0:= x2 - kLinedOffset*Cos(Deg2Rad(Alpha));
L1y0:= y2 - kLinedOffset*Sin(Deg2Rad(Alpha));
L2x0:= x2 - (L - kLinedOffset)*Cos(Deg2Rad(Alpha));
L2y0:= y2 - (L - kLinedOffset)*Sin(Deg2Rad(Alpha));
END;
END;
IF (quadrant = 3) | (quadrant = 4) THEN
BEGIN
x0:=x1;
y0:=y1;
IF lined THEN
BEGIN
L1x0:= x1 + kLinedOffset*Cos(Deg2Rad(Alpha));
L1y0:= y1 + kLinedOffset*Sin(Deg2Rad(Alpha));
L2x0:= x1 + (L - kLinedOffset)*Cos(Deg2Rad(Alpha));
L2y0:= y1 + (L - kLinedOffset)*Sin(Deg2Rad(Alpha));
END;
END;
Alpha := Alpha + 180;
DSelectAll;
{** Initialize variables with parmetric formulas of the object.}
a := r1*tan(theta/2);
b := r1*sin(theta);
c := (r1 + L)*tan(theta/2);
d := (r1 + L)*sin(theta);
e := r1-(r1*cos(theta));
f := r1-((r1 + L)*cos(theta));
IF lined THEN
BEGIN
g:= (r1 + kLinedOffset)*tan(theta/2);
h:= (r1 + kLinedOffset)*sin(theta);
i:= ((r1 + L) - kLinedOffset)*tan(theta/2);
j:= ((r1 + L) - kLinedOffset)*sin(theta);
m:= ((r1 + L) - kLinedOffset)-(((r1 + L) - kLinedOffset)*cos(theta));
n:= (r1 + kLinedOffset)-((r1 + kLinedOffset)*cos(theta));
END;
{** Calculate the coordinates of the poly points relative to the insertion point
of the object (x0,y0) at an angle of Alpha = 0.}
IF quadrant = 1 THEN
BEGIN
x[1]:=0; y[1]:=0; R[1]:=0;
x[2]:=0; y[2]:=-a; R[2]:=r1;
x[3]:=-e; y[3]:=-b; R[3]:=0;
x[4]:=-f; y[4]:=-d; R[4]:=0;
x[5]:=L; y[5]:=-c; R[5]:=r1 + L;
x[6]:=L; y[6]:=0; R[6]:=0;
IF lined THEN
BEGIN
xL1[1]:=0; yL1[1]:=0; RL1[1]:=0;
xL1[2]:=0; yL1[2]:=-g; RL1[2]:=r1 + kLinedOffset;
xL1[3]:=-n; yL1[3]:=-h; RL1[3]:=0;
xL2[1]:=0; yL2[1]:=0; RL2[1]:=0;
xL2[2]:=0; yL2[2]:=-i; RL2[2]:=(r1 + L) - kLinedOffset;
xL2[3]:=-m; yL2[3]:=-j; RL2[3]:=0;
END;
END;
IF quadrant = 2 THEN
BEGIN
x[1]:=0; y[1]:=0; R[1]:=0;
x[2]:=0; y[2]:=a; R[2]:=r1;
x[3]:=-e; y[3]:=b; R[3]:=0;
x[4]:=-f; y[4]:=d; R[4]:=0;
x[5]:=L; y[5]:=c; R[5]:=r1 + L;
x[6]:=L; y[6]:=0; R[6]:=0;
IF lined THEN
BEGIN
xL1[1]:=0; yL1[1]:=0; RL1[1]:=0;
xL1[2]:=0; yL1[2]:=g; RL1[2]:=r1 + kLinedOffset;
xL1[3]:=-n; yL1[3]:=h; RL1[3]:=0;
xL2[1]:=0; yL2[1]:=0; RL2[1]:=0;
xL2[2]:=0; yL2[2]:=i; RL2[2]:=(r1 + L) - kLinedOffset;
xL2[3]:=-m; yL2[3]:=j; RL2[3]:=0;
END;
END;
IF quadrant = 3 THEN
BEGIN
x[1]:=0; y[1]:=0; R[1]:=0;
x[2]:=0; y[2]:=a; R[2]:=r1;
x[3]:=e; y[3]:=b; R[3]:=0;
x[4]:=f; y[4]:=d; R[4]:=0;
x[5]:=-L; y[5]:=c; R[5]:=r1 + L;
x[6]:=-L; y[6]:=0; R[6]:=0;
IF lined THEN
BEGIN
xL1[1]:=0; yL1[1]:=0; RL1[1]:=0;
xL1[2]:=0; yL1[2]:=g; RL1[2]:=r1 + kLinedOffset;
xL1[3]:=n; yL1[3]:=h; RL1[3]:=0;
xL2[1]:=0; yL2[1]:=0; RL2[1]:=0;
xL2[2]:=0; yL2[2]:=i; RL2[2]:=(r1 + L) - kLinedOffset;
xL2[3]:=m; yL2[3]:=j; RL2[3]:=0;
END;
END;
IF quadrant = 4 THEN
BEGIN
x[1]:=0; y[1]:=0; R[1]:=0;
x[2]:=0; y[2]:=-a; R[2]:=r1;
x[3]:=e; y[3]:=-b; R[3]:=0;
x[4]:=f; y[4]:=-d; R[4]:=0;
x[5]:=-L; y[5]:=-c; R[5]:=r1 + L;
x[6]:=-L; y[6]:=0; R[6]:=0;
IF lined THEN
BEGIN
xL1[1]:=0; yL1[1]:=0; RL1[1]:=0;
xL1[2]:=0; yL1[2]:=-g; RL1[2]:=r1 + kLinedOffset;
xL1[3]:=n; yL1[3]:=-h; RL1[3]:=0;
xL2[1]:=0; yL2[1]:=0; RL2[1]:=0;
xL2[2]:=0; yL2[2]:=-i; RL2[2]:=(r1 + L) - kLinedOffset;
xL2[3]:=m; yL2[3]:=-j; RL2[3]:=0;
END;
END;
;
{** Calculate the points relative to the x and y axis of the drawing (0,0)
and, if appropiate, adjust for any rotation (Alpha).}
BEGINGROUP;
IF filled THEN FillPat(kFilledPat) ELSE FillPat(kPlainPat);
nPoints := 6;
FOR k:=1 TO nPoints DO
BEGIN
xp[k]:=xt(x[k],y[k],x0,y0,Alpha);
yp[k]:=yt(x[k],y[k],x0,y0,Alpha);
END;
{** Move to the absolute coordinates of the first point and draw the polyline.}
Absolute;
MoveTo(x0,y0);
ClosePoly;
BeginPoly;
FOR k:=1 TO nPoints DO
DrawPolyPoint(xp[k],yp[k],R[k]);
EndPoly;
{** If user has asked for lined duct then draw the dashed curves.}
IF lined THEN
BEGIN
FillPat(0);
PenPat(kDashedLine);
nPoints := 3;
FOR k:=1 TO nPoints DO
BEGIN
xp[k]:=xt(xL1[k],yL1[k],L1x0,L1y0,Alpha);
yp[k]:=yt(xL1[k],yL1[k],L1x0,L1y0,Alpha);
END;
{** Move to the absolute coordinates of the first point of the lining and draw the polyline.}
MoveTo(L1x0,L1y0);
OpenPoly;
BeginPoly;
FOR k:=1 TO nPoints DO
DrawPolyPoint(xp[k],yp[k],RL1[k]);
EndPoly;
FOR k:=1 TO nPoints DO
BEGIN
xp[k]:=xt(xL2[k],yL2[k],L2x0,L2y0,Alpha);
yp[k]:=yt(xL2[k],yL2[k],L2x0,L2y0,Alpha);
END;
MoveTo(L2x0,L2y0);
BeginPoly;
FOR k:=1 TO nPoints DO
DrawPolyPoint(xp[k],yp[k],RL2[k]);
EndPoly;
END;
ENDGROUP;
DelObject(han1);
DelObject(han2);
END;
END;
PopAttrs;
CLRMESSAGE;
END; {of Main program}
RUN(DrawElbow);