📄 circles.c
字号:
c->array[_i].r = sig->Y[2]; FSI_FOR_END; *pValueRes = (VALUE) c; return(circlesType);}/* * 'r' 'x' and 'y' fields */static void *GetExtractOptionsRXYCirclesV(CIRCLES c, void **arg){ static char *gextractOptionsCircles[] = {NULL}; return(gextractOptionsCircles);}static void *GetExtractInfoRXYCirclesV(CIRCLES c, void **arg){ static ExtractInfo extractInfo; static char flagInit = YES; unsigned long *options = ARG_EI_GetPOptions(arg); if (flagInit == YES) { extractInfo.nSignals = 1; extractInfo.xmin = 0; extractInfo.dx = 1; extractInfo.flags = EIIntIndex | EIErrorBound; } if (c->n == 0) { SetErrorf("No extraction possible on empty list of circles"); return(NULL); } extractInfo.xmax = c->n-1; return(&extractInfo);}static void * GetRXYCirclesV(CIRCLES c, void **arg, char flag){ SIGNAL sig; int i; void *res; sig = TNewSignal(); if (c->n != 0) SizeSignal(sig,c->n,YSIG); switch(flag) { case 'r' : for (i=0;i<c->n;i++) sig->Y[i] = c->array[i].r; break; case 'x' : for (i=0;i<c->n;i++) sig->Y[i] = c->array[i].x; break; case 'y' : for (i=0;i<c->n;i++) sig->Y[i] = c->array[i].y; break; } ARG_G_SetField(arg,NULL); res = GetSignalExtractField(sig,arg); if (res == NULL) return; if (res == signaliType) { sig = *((SIGNAL *) ARG_G_GetResPValue(arg)); sig->dx = 1; sig->x0 = 0; }}static void * SetRXYCirclesV(CIRCLES c, void **arg, char flag){ SIGNAL sig; int i; void *res; sig = TNewSignal(); if (c->n != 0) SizeSignal(sig,c->n,YSIG); switch(flag) { case 'r' : for (i=0;i<c->n;i++) sig->Y[i] = c->array[i].r; break; case 'x' : for (i=0;i<c->n;i++) sig->Y[i] = c->array[i].x; break; case 'y' : for (i=0;i<c->n;i++) sig->Y[i] = c->array[i].y; break; } if ((res = SetSignalField(sig,arg)) == NULL) return(NULL); if (sig->size != c->n) { SetErrorf("Sorry, right handside should have the same size as left handside"); return(NULL); } if (flag == 'r') { for (i=0;i<c->n;i++) { if (sig->Y[i]<0) { SetErrorf("Sorry, radii should be positive"); return(NULL); } } } switch(flag) { case 'r' : for (i=0;i<c->n;i++) c->array[i].r = sig->Y[i]; break; case 'x' : for (i=0;i<c->n;i++) c->array[i].x = sig->Y[i]; break; case 'y' : for (i=0;i<c->n;i++) c->array[i].y = sig->Y[i]; break; } return(res);}static char *rDoc = "{[[+-*/:]= (<signal> | <range>])} {Sets/Gets the radii}";static void * GetRCirclesV(CIRCLES c, void **arg){ if (c == NULL) return(rDoc); return(GetRXYCirclesV(c,arg,'r'));}static void * SetRCirclesV(CIRCLES c, void **arg){ if (c == NULL) return(rDoc); return(SetRXYCirclesV(c,arg,'r'));}static char *xDoc = "{[[+-*/:]= (<signal> | <range>])} {Sets/Gets the abscissa}";static void * GetXCirclesV(CIRCLES c, void **arg){ if (c == NULL) return(xDoc); return(GetRXYCirclesV(c,arg,'x'));}static void * SetXCirclesV(CIRCLES c, void **arg){ if (c == NULL) return(xDoc); return(SetRXYCirclesV(c,arg,'x'));}static char *yDoc = "{[[+-*/:]= (<signal> | <range>])} {Sets/Gets the ordinates}";static void * GetYCirclesV(CIRCLES c, void **arg){ if (c == NULL) return(yDoc); return(GetRXYCirclesV(c,arg,'y'));}static void * SetYCirclesV(CIRCLES c, void **arg){ if (c == NULL) return(yDoc); return(SetRXYCirclesV(c,arg,'y'));}/************************************************************************ * * * * GRAPHICS * * * ************************************************************************//* The GOBJECT structure for displaying a circles */typedef struct graphCircles { GObjectFields; /* The CIRCLES to be displayed */ CIRCLES circles; /* the fill color */ unsigned long fillColor; } GraphCircles, *GRAPHCIRCLES;/* The corresponding class */ GCLASS theGraphCirclesClass = NULL;/* Initialization of the GraphCircles structure */static void _InitGraphCircles(GOBJECT o){ GRAPHCIRCLES graph; graph = (GRAPHCIRCLES) o; graph->circles = NULL; graph->fillColor = graph->bgColor = invisibleColor; graph->rectType.left = graph->rectType.right = graph->rectType.bottom = graph->rectType.top = 1; }/* Deleting the content of a GraphCircles */extern int tCIRCLES, tCIRCLES_;static void _DeleteContentGraphCircles(GOBJECT o){ GRAPHCIRCLES graph; graph = (GRAPHCIRCLES) o; if (graph->circles != NULL) DeleteCircles(graph->circles);}void _GetCirclesBound(CIRCLES c,FLOAT *x,FLOAT *y,FLOAT *w,FLOAT *h){ int i; FLOAT f,x1,x2,y1,y2; if (c == NULL || c->n == 0) { *x = *y = *w = *h = 0; return; } x1 = FLT_MAX; x2 = FLT_MIN; y1 = FLT_MAX; y2 = FLT_MIN; for (i=0;i<c->n;i++) { f = c->array[i].x-c->array[i].r; x1 = MIN(x1,f); f = c->array[i].x+c->array[i].r; x2 = MAX(x2,f); f = c->array[i].y-c->array[i].r; y1 = MIN(y1,f); f = c->array[i].y+c->array[i].r; y2 = MAX(y2,f); } *x = x1; *y = y1; *w = x2-x1; *h = y2-y1;}/* The setg method */static int _SetGraphCircles (GOBJECT o, char *field, char**argv){ GRAPHCIRCLES graph; CIRCLES c; char *str; int i; LISTV lv; /* The help command */ if (o == NULL) { SetResultStr("{{{graph [<circles>]} {Gets/Sets the circles object to be displayed by the GraphCircles. (The '-cgraph' field \is equivalent to that field).}} \{{fill [<color>]} {Sets/Gets the color that will be used to fill up the circles.}}}"); return(YES); } graph = (GRAPHCIRCLES) o; c = graph->circles; /* the 'graph' and 'cgraph' fields */ if (!strcmp(field,"graph") || !strcmp(field,"cgraph")) { if (*argv == NULL) { SetResultValue(c); return(YES); } argv = ParseArgv(argv,tCIRCLES,&c,0); if (c->n == 0) Errorf("_SetGraphCircles() : You cannot display an empty 'circles'"); if (graph->circles != NULL) DeleteCircles(graph->circles); graph->circles = c; AddRefValue(c); _GetCirclesBound(c,&(o->rx),&(o->ry),&(o->rw),&(o->rh)); UpdateGlobalRectGObject(o); return(YES); } /* The fill field */ if (!strcmp(field,"fill")) { if (*argv == NULL) { SetResultStr(GetColorName(graph->fillColor)); return(YES); } argv = ParseArgv(argv,tCOLOR,&(graph->fillColor),0); return(YES); } /* The 'rect' field */ if (!strcmp(field,"rect")) { NoMoreArgs(argv); _GetCirclesBound(c,&(o->rx),&(o->ry),&(o->rw),&(o->rh)); UpdateGlobalRectGObject(o); lv = TNewListv(); SetResultValue(lv); AppendFloat2Listv(lv,o->rx); AppendFloat2Listv(lv,o->ry); AppendFloat2Listv(lv,o->rw); AppendFloat2Listv(lv,o->rh); return(YES); } return(NO);}/* The drawing procedure */static void _DrawGraphCircles (WINDOW win, GOBJECT obj, int x, int y,int w,int h){ GRAPHCIRCLES graph; GOBJECT o1; CIRCLES c; FLOAT x0,y0,x1,y1; unsigned long fg,fill; int i; /* Some inits */ graph = (GRAPHCIRCLES) obj; c = graph->circles; if (c == NULL) return; if (c->n == 0) return; /* Getting the minimum and maximum indexes the drawing should be performed on *//* Global2LocalRect(o,x,y,w,h,&x0,&y0,&x1,&y1,LargeRect); */ fg = graph->fgColor; fill = graph->fillColor; o1 = (GOBJECT) obj->father; for (i=0;i<c->n;i++) { if (fill != invisibleColor) { WSetColor(win,fill); WFillEllipse(obj,c->array[i].x-c->array[i].r,c->array[i].y-c->array[i].r,2*c->array[i].r,2*c->array[i].r,NO,LargeRect); } WSetColor(win,fg); WDrawEllipse(obj,c->array[i].x-c->array[i].r,c->array[i].y-c->array[i].r,2*c->array[i].r,2*c->array[i].r,NO,LargeRect); }}/* The isin procedure */static FLOAT _IsInGraphCircles(GOBJECT o, GOBJECT *o1, int x, int y){ FLOAT rx, ry; GRAPHCIRCLES g; int i; CIRCLES c; g = (GRAPHCIRCLES) o; c = g->circles; *o1 = NULL; /* Get the local coordinate */ Global2Local(o,x,y,&rx,&ry); /* is this point in a circle ? */ for (i=0;i<c->n;i++) { if ((c->array[i].x-rx)*(c->array[i].x-rx)+(c->array[i].y-ry)*(c->array[i].y-ry) < c->array[i].r*c->array[i].r) { *o1 = o; return(0); } } return(-1);}/* Defining the GraphCircles gclass */ void DefineGraphCircles(void){ theGraphCirclesClass = NewGClass("GraphCircles",theGObjectClass,"circles"); theGraphCirclesClass->nbBytes = sizeof(GraphCircles); theGraphCirclesClass->init = _InitGraphCircles; theGraphCirclesClass->deleteContent = _DeleteContentGraphCircles; theGraphCirclesClass->set = _SetGraphCircles; theGraphCirclesClass->draw = _DrawGraphCircles; theGraphCirclesClass->isIn = _IsInGraphCircles; theGraphCirclesClass->varType = circlesType; theGraphCirclesClass->flags &= ~(GClassMoveResize+GClassLocalCoor); theGraphCirclesClass->info = "Graphic Class that allows to display circles"; }/************************************************************************ * * * Useful commands * * ************************************************************************/void C_Circles(char **argv){ CIRCLES c; char *action; FLOAT x,y,dist,d; int i,i0; argv = ParseArgv(argv,tWORD,&action,tCIRCLES,&c,-1); if (!strcmp(action,"closest")) { argv = ParseArgv(argv,tFLOAT,&x, tFLOAT,&y,0); dist = FLT_MAX; i0 = -1; for (i=0;i<c->n;i++) { d = (c->array[i].x-x)*(c->array[i].x-x)+(c->array[i].y-y)*(c->array[i].y-y); if (d<dist) { i0 = i; dist = d; } } SetResultInt(i0); return; } Errorf("Unknown action '%s'",action);}static CProc circlesCommands[] = { "circles",C_Circles,"{{{closest <circles> <x> <y>} \{Gets the index of the closes circle}}}", NULL,NULL,NULL};static CProcTable circlesTable = {circlesCommands, "circles", "Commands related to circles"}; /************************************************************************ * * * Loading/Adding the circles package * * ************************************************************************/int tCIRCLES, tCIRCLES_;static void LoadCirclesPackage(void){ tCIRCLES = AddVariableTypeValue(circlesType, &tsCircles, NULL); tCIRCLES_ = tCIRCLES+1; DefineGraphCircles(); AddCProcTable(&circlesTable);}void DeclareCirclesPackage(void){ DeclarePackage("circles",LoadCirclesPackage,2003,"1.0","E.Bacry", "Demo package");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -