📄 intproto.cpp
字号:
FLOAT32 *EndPad, FLOAT32 *SidePad, FLOAT32 *AnglePad) {/* ** Parameters: ** Level "tightness" level to return pads for ** EndPad place to put end pad for Level ** SidePad place to put side pad for Level ** AnglePad place to put angle pad for Level ** Globals: none ** Operation: This routine copies the appropriate global pad variables ** into EndPad, SidePad, and AnglePad. This is a kludge used ** to get around the fact that global control variables cannot ** be arrays. If the specified level is illegal, the tightest ** possible pads are returned. ** Return: none (results are returned in EndPad, SidePad, and AnglePad. ** Exceptions: none ** History: Thu Feb 14 08:26:49 1991, DSJ, Created. */ switch (Level) { case 0: *EndPad = CPEndPadLoose * GetPicoFeatureLength (); *SidePad = CPSidePadLoose * GetPicoFeatureLength (); *AnglePad = CPAnglePadLoose / 360.0; break; case 1: *EndPad = CPEndPadMedium * GetPicoFeatureLength (); *SidePad = CPSidePadMedium * GetPicoFeatureLength (); *AnglePad = CPAnglePadMedium / 360.0; break; case 2: *EndPad = CPEndPadTight * GetPicoFeatureLength (); *SidePad = CPSidePadTight * GetPicoFeatureLength (); *AnglePad = CPAnglePadTight / 360.0; break; default: *EndPad = CPEndPadTight * GetPicoFeatureLength (); *SidePad = CPSidePadTight * GetPicoFeatureLength (); *AnglePad = CPAnglePadTight / 360.0; break; } if (*AnglePad > 0.5) *AnglePad = 0.5;} /* GetCPPadsForLevel *//*---------------------------------------------------------------------------*/C_COL GetMatchColorFor(FLOAT32 Evidence) {/* ** Parameters: ** Evidence evidence value to return color for ** Globals: none ** Operation: ** Return: Color which corresponds to specified Evidence value. ** Exceptions: none ** History: Thu Mar 21 15:24:52 1991, DSJ, Created. */ assert (Evidence >= 0.0); assert (Evidence <= 1.0); if (Evidence >= 0.90) return White; else if (Evidence >= 0.75) return Green; else if (Evidence >= 0.50) return Red; else return Blue;} /* GetMatchColorFor *//*---------------------------------------------------------------------------*/void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill) {/* ** Parameters: ** Filler filler to get next fill spec from ** Fill place to put spec for next fill ** Globals: none ** Operation: This routine returns (in Fill) the specification of ** the next line to be filled from Filler. FillerDone() should ** always be called before GetNextFill() to ensure that we ** do not run past the end of the fill table. ** Return: none (results are returned in Fill) ** Exceptions: none ** History: Tue Feb 19 10:17:42 1991, DSJ, Created. */ FILL_SWITCH *Next; /* compute the fill assuming no switches will be encountered */ Fill->AngleStart = Filler->AngleStart; Fill->AngleEnd = Filler->AngleEnd; Fill->X = Filler->X; Fill->YStart = Filler->YStart >> 8; Fill->YEnd = Filler->YEnd >> 8; /* update the fill info and the filler for ALL switches at this X value */ Next = &(Filler->Switch[Filler->NextSwitch]); while (Filler->X >= Next->X) { Fill->X = Filler->X = Next->X; if (Next->Type == StartSwitch) { Fill->YStart = Next->Y; Filler->StartDelta = Next->Delta; Filler->YStart = Next->YInit; } else if (Next->Type == EndSwitch) { Fill->YEnd = Next->Y; Filler->EndDelta = Next->Delta; Filler->YEnd = Next->YInit; } else { /* Type must be LastSwitch */ break; } Filler->NextSwitch++; Next = &(Filler->Switch[Filler->NextSwitch]); } /* prepare the filler for the next call to this routine */ Filler->X++; Filler->YStart += Filler->StartDelta; Filler->YEnd += Filler->EndDelta;} /* GetNextFill *//*---------------------------------------------------------------------------*/voidInitTableFiller (FLOAT32 EndPad,FLOAT32 SidePad,FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER * Filler)/* ** Parameters: ** EndPad, SidePad, AnglePad padding to add to proto ** Proto proto to create a filler for ** Filler place to put table filler ** Globals: none ** Operation: This routine computes a data structure (Filler) ** which can be used to fill in a rectangle surrounding ** the specified Proto. ** Return: none (results are returned in Filler) ** Exceptions: none ** History: Thu Feb 14 09:27:05 1991, DSJ, Created. */#define XS X_SHIFT#define YS Y_SHIFT#define AS ANGLE_SHIFT#define NB NUM_CP_BUCKETS{ FLOAT32 Angle; FLOAT32 X, Y, HalfLength; FLOAT32 Cos, Sin; FLOAT32 XAdjust, YAdjust; FPOINT Start, Switch1, Switch2, End; int S1 = 0; int S2 = 1; Angle = ProtoAngle (Proto); X = ProtoX (Proto); Y = ProtoY (Proto); HalfLength = ProtoLength (Proto) / 2.0; Filler->AngleStart = CircBucketFor (Angle - AnglePad, AS, NB); Filler->AngleEnd = CircBucketFor (Angle + AnglePad, AS, NB); Filler->NextSwitch = 0; if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) { /* horizontal proto - handle as special case */ Filler->X = BucketFor (X - HalfLength - EndPad, XS, NB); Filler->YStart = BucketFor (Y - SidePad, YS, NB * 256); Filler->YEnd = BucketFor (Y + SidePad, YS, NB * 256); Filler->StartDelta = 0; Filler->EndDelta = 0; Filler->Switch[0].Type = LastSwitch; Filler->Switch[0].X = BucketFor (X + HalfLength + EndPad, XS, NB); } else if (fabs (Angle - 0.25) < HV_TOLERANCE || fabs (Angle - 0.75) < HV_TOLERANCE) { /* vertical proto - handle as special case */ Filler->X = BucketFor (X - SidePad, XS, NB); Filler->YStart = BucketFor (Y - HalfLength - EndPad, YS, NB * 256); Filler->YEnd = BucketFor (Y + HalfLength + EndPad, YS, NB * 256); Filler->StartDelta = 0; Filler->EndDelta = 0; Filler->Switch[0].Type = LastSwitch; Filler->Switch[0].X = BucketFor (X + SidePad, XS, NB); } else { /* diagonal proto */ if (Angle > 0.0 && Angle < 0.25 || Angle > 0.5 && Angle < 0.75) { /* rising diagonal proto */ Angle *= 2.0 * PI; Cos = fabs (cos (Angle)); Sin = fabs (sin (Angle)); /* compute the positions of the corners of the acceptance region */ Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin; Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos; End.x = 2.0 * X - Start.x; End.y = 2.0 * Y - Start.y; Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin; Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos; Switch2.x = 2.0 * X - Switch1.x; Switch2.y = 2.0 * Y - Switch1.y; if (Switch1.x > Switch2.x) { S1 = 1; S2 = 0; } /* translate into bucket positions and deltas */ Filler->X = (INT8) MapParam (Start.x, XS, NB); Filler->StartDelta = -(INT16) ((Cos / Sin) * 256); Filler->EndDelta = (INT16) ((Sin / Cos) * 256); XAdjust = BucketEnd (Filler->X, XS, NB) - Start.x; YAdjust = XAdjust * Cos / Sin; Filler->YStart = (INT16) MapParam (Start.y - YAdjust, YS, NB * 256); YAdjust = XAdjust * Sin / Cos; Filler->YEnd = (INT16) MapParam (Start.y + YAdjust, YS, NB * 256); Filler->Switch[S1].Type = StartSwitch; Filler->Switch[S1].X = (INT8) MapParam (Switch1.x, XS, NB); Filler->Switch[S1].Y = (INT8) MapParam (Switch1.y, YS, NB); XAdjust = Switch1.x - BucketStart (Filler->Switch[S1].X, XS, NB); YAdjust = XAdjust * Sin / Cos; Filler->Switch[S1].YInit = (INT16) MapParam (Switch1.y - YAdjust, YS, NB * 256); Filler->Switch[S1].Delta = Filler->EndDelta; Filler->Switch[S2].Type = EndSwitch; Filler->Switch[S2].X = (INT8) MapParam (Switch2.x, XS, NB); Filler->Switch[S2].Y = (INT8) MapParam (Switch2.y, YS, NB); XAdjust = Switch2.x - BucketStart (Filler->Switch[S2].X, XS, NB); YAdjust = XAdjust * Cos / Sin; Filler->Switch[S2].YInit = (INT16) MapParam (Switch2.y + YAdjust, YS, NB * 256); Filler->Switch[S2].Delta = Filler->StartDelta; Filler->Switch[2].Type = LastSwitch; Filler->Switch[2].X = (INT8) MapParam (End.x, XS, NB); } else { /* falling diagonal proto */ Angle *= 2.0 * PI; Cos = fabs (cos (Angle)); Sin = fabs (sin (Angle)); /* compute the positions of the corners of the acceptance region */ Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin; Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos; End.x = 2.0 * X - Start.x; End.y = 2.0 * Y - Start.y; Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin; Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos; Switch2.x = 2.0 * X - Switch1.x; Switch2.y = 2.0 * Y - Switch1.y; if (Switch1.x > Switch2.x) { S1 = 1; S2 = 0; } /* translate into bucket positions and deltas */ Filler->X = (INT8) MapParam (Start.x, XS, NB); Filler->StartDelta = -(INT16) ((Sin / Cos) * 256); Filler->EndDelta = (INT16) ((Cos / Sin) * 256); XAdjust = BucketEnd (Filler->X, XS, NB) - Start.x; YAdjust = XAdjust * Sin / Cos; Filler->YStart = (INT16) MapParam (Start.y - YAdjust, YS, NB * 256); YAdjust = XAdjust * Cos / Sin; Filler->YEnd = (INT16) MapParam (Start.y + YAdjust, YS, NB * 256); Filler->Switch[S1].Type = EndSwitch; Filler->Switch[S1].X = (INT8) MapParam (Switch1.x, XS, NB); Filler->Switch[S1].Y = (INT8) MapParam (Switch1.y, YS, NB); XAdjust = Switch1.x - BucketStart (Filler->Switch[S1].X, XS, NB); YAdjust = XAdjust * Sin / Cos; Filler->Switch[S1].YInit = (INT16) MapParam (Switch1.y + YAdjust, YS, NB * 256); Filler->Switch[S1].Delta = Filler->StartDelta; Filler->Switch[S2].Type = StartSwitch; Filler->Switch[S2].X = (INT8) MapParam (Switch2.x, XS, NB); Filler->Switch[S2].Y = (INT8) MapParam (Switch2.y, YS, NB); XAdjust = Switch2.x - BucketStart (Filler->Switch[S2].X, XS, NB); YAdjust = XAdjust * Cos / Sin; Filler->Switch[S2].YInit = (INT16) MapParam (Switch2.y - YAdjust, YS, NB * 256); Filler->Switch[S2].Delta = Filler->EndDelta; Filler->Switch[2].Type = LastSwitch; Filler->Switch[2].X = (INT8) MapParam (End.x, XS, NB); } }} /* InitTableFiller *//*---------------------------------------------------------------------------*/#ifndef GRAPHICS_DISABLEDvoid RenderIntFeature(void *window, INT_FEATURE Feature, C_COL Color) {/* ** Parameters: ** ShapeList shape list to add feature rendering to ** Feature feature to be rendered ** Color color to use for feature rendering ** Globals: none ** Operation: This routine renders the specified feature into ShapeList. ** Return: New shape list with rendering of Feature added. ** Exceptions: none ** History: Thu Mar 21 14:57:41 1991, DSJ, Created. */ FLOAT32 X, Y, Dx, Dy, Length; c_line_color_index(window, Color); assert (Feature != NULL); assert (Color != 0); X = Feature->X - DISPLAY_OFFSET; Y = Feature->Y - DISPLAY_OFFSET; Length = GetPicoFeatureLength () * 0.7 * INT_CHAR_NORM_RANGE; Dx = (Length / 2.0) * cos ((Feature->Theta / 256.0) * 2.0 * PI); Dy = (Length / 2.0) * sin ((Feature->Theta / 256.0) * 2.0 * PI); c_move (window, X - Dx, Y - Dy); c_draw (window, X + Dx, Y + Dy); c_move (window, X - Dx - Dy * DOUBLE_OFFSET, Y - Dy + Dx * DOUBLE_OFFSET); c_draw (window, X + Dx - Dy * DOUBLE_OFFSET, Y + Dy + Dx * DOUBLE_OFFSET);} /* RenderIntFeature *//*---------------------------------------------------------------------------*/void RenderIntProto(void *window, INT_CLASS Class, PROTO_ID ProtoId, C_COL Color) {/* ** Parameters: ** ShapeList shape list to append proto rendering onto ** Class class that proto is contained in ** ProtoId id of proto to be rendered ** Color color to render proto in ** Globals: none ** Operation: This routine extracts the parameters of the specified ** proto from the class description and adds a rendering of ** the proto onto the ShapeList. ** Return: New shape list with a rendering of one proto added. ** Exceptions: none ** History: Thu Mar 21 10:21:09 1991, DSJ, Created. */ PROTO_SET ProtoSet; INT_PROTO Proto; int ProtoSetIndex; int ProtoWordIndex; FLOAT32 Length; int Xmin, Xmax, Ymin, Ymax; FLOAT32 X, Y, Dx, Dy; UINT32 ProtoMask; int Bucket; assert (ProtoId >= 0); assert (Class != NULL); assert (ProtoId < NumIntProtosIn (Class)); assert (Color != 0); c_line_color_index(window, Color); ProtoSet = ProtoSetIn (Class, SetForProto (ProtoId)); ProtoSetIndex = IndexForProto (ProtoId); Proto = &(ProtoSet->Protos[ProtoSetIndex]); Length = (LengthForProtoId (Class, ProtoId) * GetPicoFeatureLength () * INT_CHAR_NORM_RANGE); ProtoMask = PPrunerMaskFor (ProtoId); ProtoWordIndex = PPrunerWordIndexFor (ProtoId); // find the x and y extent of the proto from the proto pruning table Xmin = Ymin = NUM_PP_BUCKETS; Xmax = Ymax = 0; for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) { if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) if (Bucket < Xmin) Xmin = Bucket; else if (Bucket > Xmax) Xmax = Bucket; if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) if (Bucket < Ymin) Ymin = Bucket; else if (Bucket > Ymax) Ymax = Bucket; } X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE - DISPLAY_OFFSET; Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE - DISPLAY_OFFSET; Dx = (Length / 2.0) * cos ((Proto->Angle / 256.0) * 2.0 * PI); Dy = (Length / 2.0) * sin ((Proto->Angle / 256.0) * 2.0 * PI); c_move (window, X - Dx, Y - Dy); c_draw (window, X + Dx, Y + Dy);} /* RenderIntProto */#endif/*---------------------------------------------------------------------------*/int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id) {/* ** Parameters: ** Param parameter value to be truncated ** Min, Max parameter limits (inclusive) ** Id string id of parameter for error messages ** Globals: none ** Operation: This routine truncates Param to lie within the range ** of Min-Max inclusive. If a truncation is performed, and ** Id is not null, an warning message is printed. ** Return: Truncated parameter. ** Exceptions: none ** History: Fri Feb 8 11:54:28 1991, DSJ, Created. */ if (Param < Min) { if (Id) cprintf ("Warning: Param %s truncated from %f to %d!\n", Id, Param, Min); Param = Min; } else if (Param > Max) { if (Id) cprintf ("Warning: Param %s truncated from %f to %d!\n", Id, Param, Max); Param = Max; } return (int) floor (Param);} /* TruncateParam */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -