bool SkDQuad::isLinear(int startIndex, int endIndex) const { SkLineParameters lineParameters; lineParameters.quadEndPoints(*this, startIndex, endIndex); // FIXME: maybe it's possible to avoid this and compare non-normalized lineParameters.normalize(); double distance = lineParameters.controlPtDistance(*this); return approximately_zero(distance); }
bool SkDQuad::isLinear(int startIndex, int endIndex) const { SkLineParameters lineParameters; lineParameters.quadEndPoints(*this, startIndex, endIndex); // FIXME: maybe it's possible to avoid this and compare non-normalized lineParameters.normalize(); double distance = lineParameters.controlPtDistance(*this); double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); largest = SkTMax(largest, -tiniest); return approximately_zero_when_compared_to(distance, largest); }
bool SkDCubic::isLinear(int startIndex, int endIndex) const { if (fPts[0].approximatelyDEqual(fPts[3])) { return ((const SkDQuad *) this)->isLinear(0, 2); } SkLineParameters lineParameters; lineParameters.cubicEndPoints(*this, startIndex, endIndex); // FIXME: maybe it's possible to avoid this and compare non-normalized lineParameters.normalize(); double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY), fPts[3].fX), fPts[3].fY); double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY), fPts[3].fX), fPts[3].fY); largest = SkTMax(largest, -tiniest); double distance = lineParameters.controlPtDistance(*this, 1); if (!approximately_zero_when_compared_to(distance, largest)) { return false; } distance = lineParameters.controlPtDistance(*this, 2); return approximately_zero_when_compared_to(distance, largest); }
static void LineParameterTest(skiatest::Reporter* reporter) { for (size_t index = 0; index < tests_count; ++index) { SkLineParameters lineParameters; const SkDCubic& cubic = tests[index]; lineParameters.cubicEndPoints(cubic); double denormalizedDistance[2]; denormalizedDistance[0] = lineParameters.controlPtDistance(cubic, 1); denormalizedDistance[1] = lineParameters.controlPtDistance(cubic, 2); double normalSquared = lineParameters.normalSquared(); size_t inner; for (inner = 0; inner < 2; ++inner) { double distSq = denormalizedDistance[inner]; distSq *= distSq; double answersSq = answers[index][inner]; answersSq *= answersSq; if (AlmostEqualUlps(distSq, normalSquared * answersSq)) { continue; } SkDebugf("%s [%d,%d] denormalizedDistance:%g != answer:%g" " distSq:%g answerSq:%g normalSquared:%g\n", __FUNCTION__, static_cast<int>(index), (int)inner, denormalizedDistance[inner], answers[index][inner], distSq, answersSq, normalSquared); } lineParameters.normalize(); double normalizedDistance[2]; normalizedDistance[0] = lineParameters.controlPtDistance(cubic, 1); normalizedDistance[1] = lineParameters.controlPtDistance(cubic, 2); for (inner = 0; inner < 2; ++inner) { if (AlmostEqualUlps(fabs(normalizedDistance[inner]), answers[index][inner])) { continue; } SkDebugf("%s [%d,%d] normalizedDistance:%1.10g != answer:%g\n", __FUNCTION__, static_cast<int>(index), (int)inner, normalizedDistance[inner], answers[index][inner]); REPORTER_ASSERT(reporter, 0); } } }