5
This program draws Bezier curves using the degree elevation
6
method. For large numbers of points (more than 10, for
7
example) this is faster than the recursive way.
12
Changed the source to use 2.0+.
14
Added CloseWindowSafely.
15
Made the window dynamic, it will
16
adjust the size after the screen size.
19
Translated the source to fpc.
22
Changed to use TAGS and pas2c.
25
Removed Opening of graphics.library,
26
handled by graphics.pas.
29
Uses systemvartags and
35
nils.sjoholm@mailbox.swipnet.se
38
uses exec, intuition, graphics, utility,pastoc, systemvartags;
41
PointRec = packed Record
50
This will make the new look for screen.
51
SA_Pens, Integer(pens)
53
pens : array [0..0] of integer = (not 0);
59
Points : Array [1..200] of PointRec;
63
Procedure CleanUpAndDie;
65
if assigned(w) then CloseWindow(w);
66
if assigned(s) then CloseScreen(s);
72
Move(rp, Trunc(Points[PointCount].X), Trunc(Points[PointCount].Y));
73
Draw(rp, LastX, LastY);
81
StoreMsg : tIntuiMessage;
83
OutOfBounds : Boolean;
84
BorderLeft, BorderRight,
85
BorderTop, BorderBottom : Word;
91
with Points[PointCount] do begin
92
X := Real(StoreMsg.MouseX);
93
Y := Real(StoreMsg.MouseY);
95
with StoreMsg do begin
98
LastSeconds := Seconds;
103
DrawEllipse(rp, LastX, LastY, 5, 3);
105
SetDrMd(rp, COMPLEMENT);
109
Function CheckForExit : Boolean;
110
{ This function determines whether the user wanted to stop
111
entering points. I added the position tests because my
112
doubleclick time is too long, and I was too lazy to dig
113
out Preferences to change it. }
116
CheckForExit := DoubleClick(LastSeconds, LastMicros,
118
(Abs(MouseX - Trunc(Points[PointCount].X)) < 5) and
119
(Abs(MouseY - TRunc(Points[PointCount].Y)) < 3);
123
{ This just clears the screen when you enter your first point }
127
RectFill(rp, BorderLeft, BorderTop,
128
BorderRight, BorderBottom);
129
SetDrMd(rp, COMPLEMENT);
134
dummy := ModifyIDCMP(w, IDCMP_CLOSEWINDOW or IDCMP_MOUSEBUTTONS or
136
SetDrMd(rp, COMPLEMENT);
139
OutOfBounds := False;
140
BorderLeft := w^.BorderLeft;
141
BorderRight := (w^.Width - w^.BorderRight) -1;
142
BorderTop := w^.BorderTop;
143
BorderBottom := (w^.Height - w^.BorderBottom) -1;
145
IM := pIntuiMessage(WaitPort(w^.UserPort));
146
IM := pIntuiMessage(GetMsg(w^.UserPort));
148
ReplyMsg(pMessage(IM));
149
case StoreMsg.IClass of
150
IDCMP_MOUSEMOVE : if PointCount > 0 then begin
151
if not OutOfBounds then
153
LastX := StoreMsg.MouseX;
154
LastY := StoreMsg.MouseY;
155
if (LastX > BorderLeft) and
156
(LastX < BorderRight) and
157
(LastY > BorderTop) and
158
(LastY < BorderBottom) then begin
160
OutOfBounds := False;
164
IDCMP_MOUSEBUTTONS : if StoreMsg.Code = SELECTUP then begin
165
if PointCount > 0 then
166
Leave := CheckForExit
169
if (not Leave) and (not OutOfBounds) then
172
IDCMP_CLOSEWINDOW : CleanUpAndDie;
174
until Leave or (PointCount > 50);
177
dummy := ModifyIDCMP(w, IDCMP_CLOSEWINDOW);
189
RealPoints := Real(PointCount);
190
Points[PointCount] := Points[Pred(PointCount)];
191
for i := Pred(PointCount) downto 2 do
192
with Points[i] do begin
193
t := Real(i) / RealPoints;
195
X := t * Points[Pred(i)].X + tprime * X;
196
Y := t * Points[Pred(i)].Y + tprime * Y;
204
Move(rp, Trunc(Points[1].X), Trunc(Points[1].Y));
205
for i := 2 to PointCount do
206
Draw(rp, Round(Points[i].X), Round(Points[i].Y));
209
Procedure DrawBezier;
212
while PointCount < 100 do begin
215
if GetMsg(w^.UserPort) <> Nil then
224
s := OpenScreenTags(nil,[SA_Pens,@pens,
226
SA_DisplayID, HIRES_KEY,
227
SA_Title, 'Simple Bezier Curves',
230
if s = NIL then CleanUpAndDie;
232
w := OpenWindowTags(nil,[
233
WA_IDCMP, IDCMP_CLOSEWINDOW,
235
WA_Top, s^.BarHeight +1,
237
WA_Height, s^.Height - (s^.BarHeight + 1),
238
WA_DepthGadget, ltrue,
240
WA_CloseGadget, ltrue,
241
WA_ReportMouse, ltrue,
242
WA_SmartRefresh, ltrue,
244
WA_Title, 'Close the Window to Quit',
248
IF w=NIL THEN CleanUpAndDie;
252
GText(rp, pas2c('Enter points by pressing the left mouse button'), 46);
254
GText(rp, pas2c('Double click on the last point to begin drawing'), 47);
256
GetPoints; { Both these routines will quit if }
257
DrawBezier; { the window is closed. }