mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
674 lines
18 KiB
674 lines
18 KiB
#include "common.h"
|
|
#include "crane.h"
|
|
|
|
// Convert 0-360 angle to absolute angle from Positive X axis.
|
|
|
|
__inline int Angle2XAngle(int angle)
|
|
{
|
|
return angle <= 180 ? angle : 360 - angle;
|
|
}
|
|
|
|
// Convert 0-360 angle to absolute angle from Positive Y axis.
|
|
|
|
__inline int Angle2YAngle(int angle)
|
|
{
|
|
// Convert to angle from Y axis.
|
|
|
|
angle = (angle + 90) % 360;
|
|
return Angle2XAngle(angle);
|
|
}
|
|
|
|
// Find scaled perpendiculare distance from stroke (end points) to a point.
|
|
// Note that cStroke is the point number of the start of the stroke.
|
|
|
|
int FindPerpDist(int cStoke, int cPoint, short *pX, short *pY)
|
|
{
|
|
int dX, dY;
|
|
int away;
|
|
|
|
// Get delta X and delta Y of (end - start of stroke) for our calculations.
|
|
|
|
dX = pX[cStoke + 1] - pX[cStoke];
|
|
dY = pY[cStoke + 1] - pY[cStoke];
|
|
|
|
// If both dX and dY are 0, force an X distance of 1.
|
|
|
|
if (dX == 0 && dY == 0) {
|
|
dX = 1;
|
|
}
|
|
|
|
// First calculate the away offset.
|
|
|
|
away = pY[cPoint] * dX - pX[cPoint] * dY;
|
|
|
|
// Then normalize the offset.
|
|
|
|
away -= pY[cStoke] * dX - pX[cStoke] * dY;
|
|
|
|
// Finally normalize the scale.
|
|
|
|
away *= 1000;
|
|
away /= dX * dX + dY * dY;
|
|
|
|
return away;
|
|
}
|
|
// Build up a bounding rectangle from a list of bounding rectangles.
|
|
void
|
|
BuildBoundingBox(RECTS *pRectsOut, RECTS *pRectsList, int first, int last)
|
|
{
|
|
short x1, x2, y1, y2;
|
|
ASSERT (first <= last);
|
|
|
|
// Always grab the first rect
|
|
x1 = pRectsList[first].x1;
|
|
x2 = pRectsList[first].x2;
|
|
if (x1 <= x2) {
|
|
pRectsOut->x1 = x1;
|
|
pRectsOut->x2 = x2;
|
|
} else {
|
|
pRectsOut->x1 = x2;
|
|
pRectsOut->x2 = x1;
|
|
}
|
|
|
|
y1 = pRectsList[first].y1;
|
|
y2 = pRectsList[first].y2;
|
|
if (y1 <= y2) {
|
|
pRectsOut->y1 = y1;
|
|
pRectsOut->y2 = y2;
|
|
} else {
|
|
pRectsOut->y1 = y2;
|
|
pRectsOut->y2 = y1;
|
|
}
|
|
|
|
// Now add in any additional rects
|
|
for (++first ; first <= last; ++first) {
|
|
x1 = pRectsList[first].x1;
|
|
x2 = pRectsList[first].x2;
|
|
if (x1 <= x2) {
|
|
if (pRectsOut->x1 > x1) {
|
|
pRectsOut->x1 = x1;
|
|
}
|
|
if (pRectsOut->x2 < x2) {
|
|
pRectsOut->x2 = x2;
|
|
}
|
|
} else {
|
|
if (pRectsOut->x1 > x2) {
|
|
pRectsOut->x1 = x2;
|
|
}
|
|
if (pRectsOut->x2 < x1) {
|
|
pRectsOut->x2 = x1;
|
|
}
|
|
}
|
|
|
|
y1 = pRectsList[first].y1;
|
|
y2 = pRectsList[first].y2;
|
|
if (y1 <= y2) {
|
|
if (pRectsOut->y1 > y1) {
|
|
pRectsOut->y1 = y1;
|
|
}
|
|
if (pRectsOut->y2 < y2) {
|
|
pRectsOut->y2 = y2;
|
|
}
|
|
} else {
|
|
if (pRectsOut->y1 > y1) {
|
|
pRectsOut->y1 = y1;
|
|
}
|
|
if (pRectsOut->y2 < y2) {
|
|
pRectsOut->y2 = y2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Answer a question
|
|
// Check if the answer to a question on the sample is Greater.
|
|
|
|
void AnswerQuestion(
|
|
WORD questionType, // What type of question, delta X, delta Y current choices
|
|
WORD part1, // Question constant part 1
|
|
WORD part2, // Question constant part 2
|
|
SAMPLE_INFO *pSamples,
|
|
int cSamples)
|
|
{
|
|
int ii;
|
|
int deltaX, deltaY;
|
|
int cStrokes, cPoints;
|
|
short *pByPointsX, *pByPointsY;
|
|
END_POINTS *pendX, *pendY;
|
|
SAMPLE_INFO *pLimit;
|
|
RECTS rects;
|
|
|
|
cStrokes = pSamples->pSample->cstrk; // All samples have the same stroke count
|
|
cPoints = cStrokes * 2;
|
|
pLimit = pSamples + cSamples;
|
|
switch (questionType)
|
|
{
|
|
case questionX:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = (int) ((short *)(pSamples->pSample->apfeat[FEATURE_XPOS]->data))[part1];
|
|
}
|
|
break;
|
|
|
|
case questionY:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = (int) ((short *)(pSamples->pSample->apfeat[FEATURE_YPOS]->data))[part1];
|
|
}
|
|
break;
|
|
|
|
case questionXDelta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pSamples->iAnswer = (int) pByPointsX[part1] - (int) pByPointsX[part2];
|
|
}
|
|
break;
|
|
|
|
case questionYDelta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
pSamples->iAnswer = (int)pByPointsY[part1] - (int)pByPointsY[part2];
|
|
}
|
|
break;
|
|
|
|
case questionXAngle:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
|
|
deltaX = (int)pByPointsX[part2] - (int)pByPointsX[part1];
|
|
deltaY = (int)pByPointsY[part2] - (int)pByPointsY[part1];
|
|
|
|
pSamples->iAnswer = Angle2XAngle(Arctan2(deltaY, deltaX));
|
|
}
|
|
break;
|
|
|
|
case questionYAngle:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
|
|
deltaX = (int)pByPointsX[part2] - (int)pByPointsX[part1];
|
|
deltaY = (int)pByPointsY[part2] - (int)pByPointsY[part1];
|
|
pSamples->iAnswer = Angle2YAngle(Arctan2(deltaY, deltaX));
|
|
}
|
|
break;
|
|
|
|
case questionDelta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
|
|
deltaX = (int)pByPointsX[part2] - (int)pByPointsX[part1];
|
|
deltaY = (int)pByPointsY[part2] - (int)pByPointsY[part1];
|
|
pSamples->iAnswer = Distance(deltaX, deltaY);
|
|
}
|
|
break;
|
|
|
|
case questionDakuTen:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = pSamples->pSample->fDakuten;
|
|
}
|
|
break;
|
|
|
|
case questionNetAngle:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = ((short *) (pSamples->pSample->apfeat[FEATURE_ANGLE_NET]->data))[part1];
|
|
}
|
|
break;
|
|
|
|
case questionCnsAngle :
|
|
for ( ; pSamples < pLimit; ++pSamples) {
|
|
int iAbsNetAngle, iAbsAngle;
|
|
|
|
// Get absolute value of net angle
|
|
iAbsNetAngle = ((SHORT *) (pSamples->pSample->apfeat[FEATURE_ANGLE_NET]->data))[part1];
|
|
if (iAbsNetAngle < 0) {
|
|
iAbsNetAngle = -iAbsNetAngle;
|
|
}
|
|
|
|
// Get absolute angle.
|
|
iAbsAngle = ((USHORT *) (pSamples->pSample->apfeat[FEATURE_ANGLE_ABS]->data))[part1];
|
|
|
|
// Answer is the difference
|
|
pSamples->iAnswer = iAbsAngle - iAbsNetAngle;
|
|
}
|
|
break;
|
|
|
|
case questionAbsAngle:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = ((USHORT *) (pSamples->pSample->apfeat[FEATURE_ANGLE_ABS]->data))[part1];
|
|
}
|
|
break;
|
|
|
|
case questionCSteps:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = ((BYTE *) (pSamples->pSample->apfeat[FEATURE_STEPS]->data))[part1];
|
|
}
|
|
break;
|
|
|
|
case questionCFeatures:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = ((BYTE *) (pSamples->pSample->apfeat[FEATURE_FEATURES]->data))[part1];
|
|
}
|
|
break;
|
|
|
|
case questionXPointsRight:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pSamples->iAnswer = 0;
|
|
for (ii = 0; ii < cPoints; ++ii)
|
|
{
|
|
if (pByPointsX[ii] > pByPointsX[part1])
|
|
{
|
|
++pSamples->iAnswer;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionYPointsBelow:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
pSamples->iAnswer = 0;
|
|
for (ii = 0; ii < cPoints; ++ii)
|
|
{
|
|
if (pByPointsY[ii] > pByPointsY[part1])
|
|
{
|
|
++pSamples->iAnswer;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionPerpDist:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer =
|
|
FindPerpDist(part1, part2,
|
|
((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data),
|
|
((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data));
|
|
}
|
|
break;
|
|
|
|
case questionSumXDelta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pSamples->iAnswer = 0;
|
|
for (ii = 0; ii < cPoints; ii += 2)
|
|
{
|
|
pSamples->iAnswer += (int) pByPointsX[ii + 1] - (int) pByPointsX[ii];
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionSumYDelta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
pSamples->iAnswer = 0;
|
|
for (ii = 0; ii < cPoints; ii += 2)
|
|
{
|
|
pSamples->iAnswer += (int) pByPointsY[ii + 1] - (int) pByPointsY[ii];
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionSumDelta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
pSamples->iAnswer = 0;
|
|
for (ii = 0; ii < cPoints; ii += 2)
|
|
{
|
|
deltaX = (int) pByPointsX[ii + 1] - (int) pByPointsX[ii];
|
|
deltaY = (int) pByPointsY[ii + 1] - (int) pByPointsY[ii];
|
|
pSamples->iAnswer += Distance(deltaX, deltaY);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionSumNetAngle:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
short *pNetAngle;
|
|
|
|
pNetAngle = (short *) pSamples->pSample->apfeat[FEATURE_ANGLE_NET]->data;
|
|
pSamples->iAnswer = 0;
|
|
for (ii = 0; ii < cStrokes; ++ii)
|
|
{
|
|
pSamples->iAnswer += (int) pNetAngle[ii];
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionSumAbsAngle:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
WORD *pAbsAngle;
|
|
|
|
pAbsAngle = (WORD *) pSamples->pSample->apfeat[FEATURE_ANGLE_ABS]->data;
|
|
pSamples->iAnswer = 0;
|
|
for (ii = 0; ii < cStrokes; ++ii)
|
|
{
|
|
pSamples->iAnswer += (int)pAbsAngle[ii];
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionCompareXDelta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
|
|
deltaX = (int) pByPointsX[part1 + 1] - (int) pByPointsX[part1];
|
|
pSamples->iAnswer = (deltaX >= 0) ? deltaX : - deltaX;
|
|
deltaX = (int) pByPointsX[part2 + 1] - (int) pByPointsX[part2];
|
|
pSamples->iAnswer -= (deltaX >= 0) ? deltaX : - deltaX;
|
|
}
|
|
break;
|
|
|
|
case questionCompareYDelta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
deltaY = (int) pByPointsY[part1 + 1] - (int) pByPointsY[part1];
|
|
pSamples->iAnswer = (deltaY >= 0) ? deltaY : - deltaY;
|
|
deltaY = (int) pByPointsY[part2 + 1] - (int) pByPointsY[part2];
|
|
pSamples->iAnswer -= (deltaY >= 0) ? deltaY : - deltaY;
|
|
}
|
|
break;
|
|
|
|
case questionCompareDelta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
|
|
deltaX = (int) pByPointsX[part1 + 1] - (int) pByPointsX[part1];
|
|
deltaY = (int) pByPointsY[part1 + 1] - (int) pByPointsY[part1];
|
|
pSamples->iAnswer = Distance(deltaX, deltaY);
|
|
|
|
deltaX = (int) pByPointsX[part2 + 1] - (int) pByPointsX[part2];
|
|
deltaY = (int) pByPointsY[part2 + 1] - (int) pByPointsY[part2];
|
|
pSamples->iAnswer -= Distance(deltaX, deltaY);
|
|
}
|
|
break;
|
|
|
|
case questionCompareAngle:
|
|
for ( ; pSamples < pLimit; ++pSamples) {
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
|
|
deltaX = (int) pByPointsX[part1 + 1] - (int) pByPointsX[part1];
|
|
deltaY = (int) pByPointsY[part1 + 1] - (int) pByPointsY[part1];
|
|
pSamples->iAnswer = Arctan2(deltaY, deltaX);
|
|
|
|
deltaX = (int) pByPointsX[part1 + 1] - (int) pByPointsX[part1];
|
|
deltaY = (int) pByPointsY[part1 + 1] - (int) pByPointsY[part1];
|
|
pSamples->iAnswer -= Arctan2(deltaY, deltaX);
|
|
if (pSamples->iAnswer < -180)
|
|
{
|
|
pSamples->iAnswer += 180;
|
|
}
|
|
else if (pSamples->iAnswer > 180)
|
|
{
|
|
pSamples->iAnswer -= 180;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionPointsInBBox:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
int lowerX, upperX, lowerY, upperY;
|
|
|
|
pByPointsX = ((short *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pByPointsY = ((short *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
|
|
if (pByPointsX[part1] <= pByPointsX[part2])
|
|
{
|
|
lowerX = pByPointsX[part1];
|
|
upperX = pByPointsX[part2];
|
|
}
|
|
else
|
|
{
|
|
lowerX = pByPointsX[part2];
|
|
upperX = pByPointsX[part1];
|
|
}
|
|
|
|
if (pByPointsY[part1] <= pByPointsY[part2])
|
|
{
|
|
lowerY = pByPointsY[part1];
|
|
upperY = pByPointsY[part2];
|
|
}
|
|
else
|
|
{
|
|
lowerY = pByPointsY[part2];
|
|
upperY = pByPointsY[part1];
|
|
}
|
|
|
|
pSamples->iAnswer = 0;
|
|
for (ii = 0; ii < cPoints; ++ii)
|
|
{
|
|
if ((lowerX <= pByPointsX[ii]) &&
|
|
(pByPointsX[ii] <= upperX) &&
|
|
(lowerY <= pByPointsY[ii]) &&
|
|
(pByPointsY[ii] <= upperY))
|
|
{
|
|
++pSamples->iAnswer;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionCharLeft:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = pSamples->pSample->drcs.x;
|
|
}
|
|
break;
|
|
|
|
case questionCharTop:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = pSamples->pSample->drcs.y;
|
|
}
|
|
break;
|
|
|
|
case questionCharWidth:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = pSamples->pSample->drcs.w;
|
|
}
|
|
break;
|
|
|
|
case questionCharHeight:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = pSamples->pSample->drcs.h;
|
|
}
|
|
break;
|
|
|
|
case questionCharDiagonal:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = Distance(pSamples->pSample->drcs.w, pSamples->pSample->drcs.h);
|
|
}
|
|
break;
|
|
|
|
case questionCharTheta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = Arctan2(pSamples->pSample->drcs.h, pSamples->pSample->drcs.w);
|
|
}
|
|
break;
|
|
|
|
case questionStrokeLeft:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
BuildBoundingBox(&rects,
|
|
(RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
|
|
);
|
|
pSamples->iAnswer = rects.x1;
|
|
}
|
|
break;
|
|
|
|
case questionStrokeTop:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
BuildBoundingBox(&rects,
|
|
(RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
|
|
);
|
|
pSamples->iAnswer = rects.y1;
|
|
}
|
|
break;
|
|
|
|
case questionStrokeWidth:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
BuildBoundingBox(&rects,
|
|
(RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
|
|
);
|
|
pSamples->iAnswer = rects.x2 - rects.x1;
|
|
}
|
|
break;
|
|
|
|
case questionStrokeHeight:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
BuildBoundingBox(&rects,
|
|
(RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
|
|
);
|
|
pSamples->iAnswer = rects.y2 - rects.y1;
|
|
}
|
|
break;
|
|
|
|
case questionStrokeDiagonal:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
short w, h;
|
|
|
|
BuildBoundingBox(&rects,
|
|
(RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
|
|
);
|
|
w = rects.x2 - rects.x1;
|
|
h = rects.y2 - rects.y1;
|
|
pSamples->iAnswer = Distance(w, h);
|
|
}
|
|
break;
|
|
|
|
case questionStrokeTheta:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
short w, h;
|
|
|
|
BuildBoundingBox(&rects,
|
|
(RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
|
|
);
|
|
w = rects.x2 - rects.x1;
|
|
h = rects.y2 - rects.y1;
|
|
pSamples->iAnswer = Arctan2(h, w);
|
|
}
|
|
break;
|
|
|
|
case questionStrokeRight:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
BuildBoundingBox(&rects,
|
|
(RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
|
|
);
|
|
pSamples->iAnswer = rects.x2;
|
|
}
|
|
break;
|
|
|
|
case questionStrokeBottom:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
BuildBoundingBox(&rects,
|
|
(RECTS *)(pSamples->pSample->apfeat[FEATURE_STROKE_BBOX]->data), part1, part2
|
|
);
|
|
pSamples->iAnswer = rects.y2;
|
|
}
|
|
break;
|
|
|
|
case questionStrokeLength:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = ((USHORT *)(pSamples->pSample->apfeat[FEATURE_LENGTH]->data))[part1];
|
|
}
|
|
break;
|
|
|
|
case questionStrokeCurve:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pendX = ((END_POINTS *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pendY = ((END_POINTS *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
deltaX = pendX[part1].end - pendX[part1].start;
|
|
deltaY = pendY[part1].end - pendY[part1].start;
|
|
pSamples->iAnswer = ((USHORT *)(pSamples->pSample->apfeat[FEATURE_LENGTH]->data))[part1] - Distance(deltaX, deltaY);
|
|
}
|
|
break;
|
|
|
|
case questionCharLength:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = 0;
|
|
for (ii = 0; ii < cStrokes; ii++)
|
|
pSamples->iAnswer += ((USHORT *)(pSamples->pSample->apfeat[FEATURE_LENGTH]->data))[ii];
|
|
}
|
|
break;
|
|
|
|
case questionCharCurve:
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = 0;
|
|
pendX = ((END_POINTS *) pSamples->pSample->apfeat[FEATURE_XPOS]->data);
|
|
pendY = ((END_POINTS *) pSamples->pSample->apfeat[FEATURE_YPOS]->data);
|
|
|
|
for (ii = 0; ii < cStrokes; ii++)
|
|
{
|
|
deltaX = pendX[ii].end - pendX[ii].start;
|
|
deltaY = pendY[ii].end - pendY[ii].start;
|
|
pSamples->iAnswer += ((USHORT *)(pSamples->pSample->apfeat[FEATURE_LENGTH]->data))[ii] - Distance(deltaX, deltaY);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case questionAltList :
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = MAX_RECOG_ALTS * 2;
|
|
for (ii = 0; ii < MAX_RECOG_ALTS; ++ii) {
|
|
if (pSamples->pSample->awchAlts[ii] == (wchar_t)part1) {
|
|
pSamples->iAnswer = ii;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT(FALSE); // Should never get here.
|
|
for ( ; pSamples < pLimit; ++pSamples)
|
|
{
|
|
pSamples->iAnswer = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|