/** * Test if we have a circle; inertia has been precomputed by caller */ double CircleRecognizer::scoreCircle(Stroke* s, Inertia& inertia) { if (inertia.getMass() == 0.0) { return 0; } double sum = 0.0; double x0 = inertia.centerX(); double y0 = inertia.centerY(); double r0 = inertia.rad(); ArrayIterator<Point> it = s->pointIterator(); if (!it.hasNext()) { return 0; } Point p1 = it.next(); while (it.hasNext()) { Point p2 = it.next(); double dm = hypot(p2.x - p1.x, p2.y - p1.y); double deltar = hypot(p1.x - x0, p1.y - y0) - r0; sum += dm * fabs(deltar); p1 = p2; } return sum / (inertia.getMass() * r0); }
Stroke* CircleRecognizer::recognize(Stroke* stroke) { Inertia s; s.calc(stroke->getPoints(), 0, stroke->getPointCount()); RDEBUG("Mass=%.0f, Center=(%.1f,%.1f), I=(%.0f,%.0f, %.0f), Rad=%.2f, Det=%.4f", s.getMass(), s.centerX(), s.centerY(), s.xx(), s.yy(), s.xy(), s.rad(), s.det()); if (s.det() > CIRCLE_MIN_DET) { double score = CircleRecognizer::scoreCircle(stroke, s); RDEBUG("Circle score: %.2f", score); if (score < CIRCLE_MAX_SCORE) { return CircleRecognizer::makeCircleShape(stroke, s); } } return NULL; }