home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_progs
/
educ
/
splines.lzh
/
SPLINES
/
CMDS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-16
|
7KB
|
245 lines
/* The routines in this file are copyright (c) 1987 by Helene (Lee) Taran.
* Permission is granted for use and free distribution as long as the
* original author's name is included with the code.
*/
#include "spline.h"
extern DLIST_ELEMENT Control_Points;
extern struct PopUp_Menu PointMenu, CurveMenu;
extern struct Image control_image;
int DrawAFrame = TRUE;
int CurveType = OPENB_NATURAL;
/* InRange : returns TRUE iff the mouse position is in the selection
* range of the given control point position
*/
int InRange(mouse, control)
REAL_POINT *mouse, *control;
{
return ((mouse->x >= control->x - CONTROL_RADIUS) &&
(mouse->x <= control->x + CONTROL_RADIUS) &&
(mouse->y >= control->y - CONTROL_RADIUS) &&
(mouse->y <= control->y + CONTROL_RADIUS));
}
/* Select_ControlPoint : returns the member of Control_Points that is
* is selected at <x,y>. Returns FALSE if no point is selected.
*/
DLISTPTR Select_ControlPoint(x,y)
SHORT x,y;
{
REAL_POINT tmp; int InRange();
DLISTPTR Find_Element();
tmp.x = (float) x;
tmp.y = (float) y;
return(Find_Element(&tmp,&Control_Points,InRange));
}
/* Print Instruction: prints a string in the upper left hand corner
* of the window. Assumes that the current pen color is the the
* color you want the string to appear in.
*/
PrintInstruction(w,instr)
struct Window *w;
char *instr;
{
Move(w->RPort,w->LeftEdge + w->BorderLeft + 1,
w->TopEdge + w->BorderTop + 1);
Text(w->RPort,instr,strlen(instr));
}
/* GetPoint : Waits for the user to select a point in window <w> and returns its
* x,y coordinates in terms of a REAL_POINT structure.
*/
DLISTPTR GetPoint(w)
struct Window *w;
{
REAL_POINT *tmp; void *calloc(); DLISTPTR p;
struct IntuiMessage mcopy, *msg, *GetMsg();
struct RastPort *rp = w->RPort;
BYTE old_mode = rp->DrawMode;
if (!((tmp = (REAL_POINT *)calloc(1,sizeof(REAL_POINT))) &&
(p = (DLISTPTR)calloc(1,sizeof(DLIST_ELEMENT))))) {
fprintf(stderr,"splines : trouble in paradise : can't allocate point\n");
panic(0);
}
SetDrMd(rp,COMPLEMENT);
PrintInstruction(w,"Select A Point");
while (1) {
Wait(1 << w->UserPort->mp_SigBit);
while (msg = GetMsg(w->UserPort)) {
mcopy = *msg;
ReplyMsg(msg);
if ((msg->Class == MOUSEBUTTONS) && (msg->Code == SELECTDOWN) &&
Inside_Window(msg->MouseX,msg->MouseY,w)) {
tmp->x = (float)msg->MouseX;
tmp->y = (float)msg->MouseY;
PrintInstruction(w,"Select A Point");
SetDrMd(rp,old_mode);
PlopDot(w,tmp);
p->contents = tmp;
return(p);
}
}
}
}
/* PrintError: prints a error string to the window's upper left hand
* corner for approx. 1.6 seconds. The string is drawn in the complement
* of the background so that it doesn't destroy what's already drawn in the
* window. After the delay, the string is complemented out again so it
* disappears.
*/
PrintError(w,str)
struct Window *w;
char *str;
{ struct RastPort *rp = w->RPort;
BYTE old_mode = rp->DrawMode;
SetDrMd(rp,COMPLEMENT);
PrintInstruction(w,str);
Delay(80l);
PrintInstruction(w,str);
SetDrMd(rp,old_mode);
}
DrawConstructionLine(w,p0,p1) /* draws a dotted line from p0 to p1 */
struct Window *w;
REAL_POINT *p0,*p1;
{ struct RastPort *rp = w->RPort;
BYTE old_pen = rp->FgPen; /* save the old pen color */
USHORT old_pat = rp->LinePtrn; /* save the old line pattern */
SetAPen(rp,AFRAME_COLOR);
SetDrPt(rp,0xcccc); /* use a dotted line */
Move(rp,(SHORT)p0->x,(SHORT)p0->y);
Draw(rp,(SHORT)p1->x,(SHORT)p1->y);
SetDrPt(rp,old_pat);
SetAPen(rp,old_pen);
}
/* Edit_Curve : pops up the curve style editing menu in <w> and allows
* the user to alter the current curve style
*/
Edit_CurveStyle(w)
struct Window *w;
{
int option = PopUp(&CurveMenu,w);
switch (option) {
case TOGGLEAFRAME : DrawAFrame = !DrawAFrame; Redraw(w); break;
case REDRAW : Redraw(w); break;
case OPENB_TRIPLE:
if (LENGTH(&Control_Points) < 4) {
PrintError(w,"?Error: Triple Knot option require minimum of 4 points");
return; }
/* othewise fall through to action for the next case */
case OPENB_NATURAL : case CLOSEDB : case CLOSED_INTRPL : case OPEN_INTRPL :
if (option != CurveType) { CurveType = option; Redraw(w);}
break;
case QUIT : close_things(); exit(0); break;
}
}
/* Edit_ControlPoint : pops up the control point editing menu in <w> and
* allows the user to alter the given control point <p>. Assumes
* that <p> is the control point that the user just selected.
*/
Edit_ControlPoint(w,p)
struct Window *w;
DLISTPTR p;
{
int option = PopUp(&PointMenu,w);
switch (option) {
case ADD_AFTER :
if (LENGTH(&Control_Points) == MAXG) {
PrintError(w,"No! Don't you think you've added enough points?");
return;
}
else Insert_After(p,GetPoint(w),&Control_Points); break;
case ADD_BEFORE :
if (LENGTH(&Control_Points) == MAXG) {
PrintError(w,"No! Don't you think you've added enough points?");
return;
}
else Insert_Before(p,GetPoint(w),&Control_Points); break;
case MOVE_POINT :
{ DLISTPTR tmp;
EraseDot(w,p->contents); free(p->contents);
tmp = GetPoint(w); p->contents = tmp->contents;
free(tmp); break;
}
case REMOVE_POINT :
{ int len = LENGTH(&Control_Points);
if ((len == 4) && (CurveType == OPENB_TRIPLE)) {
PrintError(w,"?Error: Triple Knot option require minimum of 4 points");
return; }
else if (len == 3)
PrintError(w,"?Error: you must have a minimum of 3 control points");
else {
Remove_Element(p,&Control_Points);
free(p->contents); free(p);
}
} break;
default : return;
}
Redraw(w);
}
EraseDot(w,dot)
struct Window *w;
REAL_POINT *dot;
{
control_image.PlanePick = 0;
PlopDot(w,dot);
control_image.PlanePick = 1;
}
PlopDot(w,point)
struct Window *w;
REAL_POINT *point;
{
DrawImage(w->RPort,&control_image,(SHORT)point->x,(SHORT)point->y);
}
Draw_ControlPoints(w)
struct Window *w;
{
DLISTPTR tmp = &Control_Points;
while ((tmp = tmp->next) != &Control_Points)
PlopDot(w,POINT(tmp));
}
Redraw(w)
struct Window *w;
{
struct RastPort *rp = w->RPort;
SetRast(rp,ERASE);
SetAPen(rp, CURVECOLOR);
Draw_ControlPoints(w);
switch (CurveType) {
case CLOSEDB : Draw_Closed_Bspline(w,&Control_Points); break;
case CLOSED_INTRPL : Draw_Closed_Ispline(w,&Control_Points); break;
case OPEN_INTRPL : Draw_Open_Ispline(w,&Control_Points); break;
case OPENB_TRIPLE : Draw_TripleKnot_Bspline(w,&Control_Points); break;
default: Draw_Natural_Bspline(w,&Control_Points); break;
}
}