📄 mfx.cpp
字号:
** Parameters: ** Start starting point of micro-feature ** End ending point of micro-feature ** MicroFeature micro-feature whose bulges are to be computed ** Globals: none ** Operation: ** This routine computes the size of the "bulges" of the ** specified micro-feature. The bulges are the deviations ** of the micro-features from a straight line at the 1/3 ** and 2/3 points along the straight line approximation of ** the micro-feature. The size of each bulge is normalized ** to the range -0.5 to 0.5. A positive bulge indicates a ** deviation in the counterclockwise direction and vice versa. ** A size of 0.5 (+ or -) corresponds to the largest bulge that ** could ever occur for the given feature independent of ** orientation. This routine assumes that Start ** and End are not the same point. It also assumes that the ** orientation and length parameters of the micro-feature ** have already been computed. ** Return: none ** Exceptions: none ** History: 7/27/89, DSJ, Created. */ MATRIX_2D Matrix; MFEDGEPT *Origin; MFOUTLINE SegmentStart, SegmentEnd; FPOINT CurrentPoint, LastPoint; FLOAT32 BulgePosition; /* check for simple case */ if (End == NextPointAfter (Start)) FirstBulgeOf (MicroFeature) = SecondBulgeOf (MicroFeature) = 0; else { Origin = PointAt (Start); InitMatrix(&Matrix); RotateMatrix (&Matrix, OrientationOf (MicroFeature) * -2.0 * PI); TranslateMatrix (&Matrix, -XPositionOf (Origin), -YPositionOf (Origin)); SegmentEnd = Start; FillPoint (CurrentPoint, 0, 0); BulgePosition = LengthOf (MicroFeature) / 3; CopyPoint(CurrentPoint, LastPoint); while (Xof (CurrentPoint) < BulgePosition) { SegmentStart = SegmentEnd; SegmentEnd = NextPointAfter (SegmentStart); CopyPoint(CurrentPoint, LastPoint); MapPoint (&Matrix, PositionOf (PointAt (SegmentEnd)), CurrentPoint); } FirstBulgeOf (MicroFeature) = XIntersectionOf(LastPoint, CurrentPoint, BulgePosition); BulgePosition *= 2; // Prevents from copying the points before computing the bulge if // CurrentPoint will not change. (Which would cause to output nan // for the SecondBulge.) if (Xof (CurrentPoint) < BulgePosition) CopyPoint(CurrentPoint, LastPoint); while (Xof (CurrentPoint) < BulgePosition) { SegmentStart = SegmentEnd; SegmentEnd = NextPointAfter (SegmentStart); CopyPoint(CurrentPoint, LastPoint); MapPoint (&Matrix, PositionOf (PointAt (SegmentEnd)), CurrentPoint); } SecondBulgeOf (MicroFeature) = XIntersectionOf(LastPoint, CurrentPoint, BulgePosition); FirstBulgeOf (MicroFeature) /= BULGENORMALIZER * LengthOf(MicroFeature); SecondBulgeOf (MicroFeature) /= BULGENORMALIZER * LengthOf(MicroFeature); }} /* ComputeBulges *//*---------------------------------------------------------------------------*/FLOAT32 ComputeOrientation(MFEDGEPT *Start, MFEDGEPT *End) {/* ** Parameters: ** Start starting edge point of micro-feature ** End ending edge point of micro-feature ** Globals: none ** Operation: ** This routine computes the orientation parameter of the ** specified micro-feature. The orientation is the angle of ** the vector from Start to End. It is normalized to a number ** between 0 and 1 where 0 corresponds to 0 degrees and 1 ** corresponds to 360 degrees. The actual range is [0,1), i.e. ** 1 is excluded from the range (since it is actual the ** same orientation as 0). This routine assumes that Start ** and End are not the same point. ** Return: Orientation parameter for the specified micro-feature. ** Exceptions: none ** History: 7/27/89, DSJ, Created. */ FLOAT32 Orientation; Orientation = NormalizeAngle (AngleFrom (PositionOf (Start), PositionOf (End))); /* ensure that round-off errors do not put circular param out of range */ if ((Orientation < 0) || (Orientation >= 1)) Orientation = 0; return (Orientation);} /* ComputeOrientation *//*---------------------------------------------------------------------------*/MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline, MICROFEATURES MicroFeatures) {/* ** Parameters: ** Outline outline to extract micro-features from ** MicroFeatures list of micro-features to add to ** Globals: none ** Operation: ** This routine ** Return: List of micro-features with new features added to front. ** Exceptions: none ** History: 7/26/89, DSJ, Created. */ MFOUTLINE Current; MFOUTLINE Last; MFOUTLINE First; MICROFEATURE NewFeature; if (DegenerateOutline (Outline)) return (MicroFeatures); First = NextExtremity (Outline); Last = First; do { Current = NextExtremity (Last); NewFeature = ExtractMicroFeature (Last, Current); if (NewFeature != NULL) MicroFeatures = push (MicroFeatures, NewFeature); Last = Current; } while (Last != First); return (MicroFeatures);} /* ConvertToMicroFeatures *//*---------------------------------------------------------------------------*/MICROFEATURE ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End) {/* ** Parameters: ** Start starting point of micro-feature ** End ending point of micro-feature ** Globals: none ** Operation: ** This routine computes the feature parameters which describe ** the micro-feature that starts and Start and ends at End. ** A new micro-feature is allocated, filled with the feature ** parameters, and returned. The routine assumes that ** Start and End are not the same point. If they are the ** same point, NULL is returned, a warning message is ** printed, and the current outline is dumped to stdout. ** Return: New micro-feature or NULL if the feature was rejected. ** Exceptions: none ** History: 7/26/89, DSJ, Created. ** 11/17/89, DSJ, Added handling for Start and End same point. */ MICROFEATURE NewFeature; MFEDGEPT *P1, *P2; P1 = PointAt (Start); P2 = PointAt (End); NewFeature = NewMicroFeature (); CenterX (NewFeature) = AverageOf (XPositionOf (P1), XPositionOf (P2)); CenterY (NewFeature) = AverageOf (YPositionOf (P1), YPositionOf (P2)); LengthOf (NewFeature) = DistanceBetween (PositionOf (P1), PositionOf (P2)); OrientationOf (NewFeature) = NormalizedAngleFrom (&(PositionOf (P1)), &(PositionOf (P2)), 1.0); ComputeBulges(Start, End, NewFeature); return (NewFeature);} /* ExtractMicroFeature *//*---------------------------------------------------------------------------*/void SmearBulges(MICROFEATURES MicroFeatures, FLOAT32 XScale, FLOAT32 YScale) {/* ** Parameters: ** MicroFeatures features to be smeared ** XScale # of normalized units per pixel in x dir ** YScale # of normalized units per pixel in y dir ** Globals: none ** Operation: Add a random amount to each bulge parameter of each ** feature. The amount added is between -0.5 pixels and ** 0.5 pixels. This is done to prevent the prototypes ** generated in training from being unrealistically tight. ** Return: none ** Exceptions: none ** History: Thu Jun 28 18:03:38 1990, DSJ, Created. */ MICROFEATURE MicroFeature; FLOAT32 MinSmear; FLOAT32 MaxSmear; FLOAT32 Cos, Sin; FLOAT32 Scale; iterate(MicroFeatures) { MicroFeature = NextFeatureOf (MicroFeatures); Cos = fabs (cos (2.0 * PI * OrientationOf (MicroFeature))); Sin = fabs (sin (2.0 * PI * OrientationOf (MicroFeature))); Scale = YScale * Cos + XScale * Sin; MinSmear = -0.5 * Scale / (BULGENORMALIZER * LengthOf (MicroFeature)); MaxSmear = 0.5 * Scale / (BULGENORMALIZER * LengthOf (MicroFeature)); FirstBulgeOf (MicroFeature) += UniformRandomNumber (MinSmear, MaxSmear); SecondBulgeOf (MicroFeature) += UniformRandomNumber (MinSmear, MaxSmear); }} /* SmearBulges */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -