Stub for conic section max curvature

BUG=skia:
R=reed@google.com

Author: humper@google.com

Review URL: https://codereview.chromium.org/175193003

git-svn-id: http://skia.googlecode.com/svn/trunk@13542 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
commit-bot@chromium.org 2014-02-21 19:49:10 +00:00
parent b988276362
commit def6468dd2
2 changed files with 53 additions and 20 deletions

View File

@ -255,6 +255,15 @@ struct SkConic {
void computeTightBounds(SkRect* bounds) const;
void computeFastBounds(SkRect* bounds) const;
/** Find the parameter value where the conic takes on its maximum curvature.
*
* @param t output scalar for max curvature. Will be unchanged if
* max curvature outside 0..1 range.
*
* @return true if max curvature found inside 0..1 range, false otherwise
*/
bool findMaxCurvature(SkScalar* t) const;
};
#include "SkTemplates.h"

View File

@ -8,7 +8,9 @@
#include "SkGeometry.h"
#include "SkMatrix.h"
bool SkXRayCrossesLine(const SkXRay& pt, const SkPoint pts[2], bool* ambiguous) {
bool SkXRayCrossesLine(const SkXRay& pt,
const SkPoint pts[2],
bool* ambiguous) {
if (ambiguous) {
*ambiguous = false;
}
@ -574,8 +576,8 @@ static void flatten_double_cubic_extrema(SkScalar coords[14]) {
}
/** Given 4 points on a cubic bezier, chop it into 1, 2, 3 beziers such that
the resulting beziers are monotonic in Y. This is called by the scan converter.
Depending on what is returned, dst[] is treated as follows
the resulting beziers are monotonic in Y. This is called by the scan
converter. Depending on what is returned, dst[] is treated as follows:
0 dst[0..3] is the original cubic
1 dst[0..3] and dst[3..6] are the two new cubics
2 dst[0..3], dst[3..6], dst[6..9] are the three new cubics
@ -632,7 +634,10 @@ int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[]) {
SkScalar Cx = src[3].fX + 3 * (src[1].fX - src[2].fX) - src[0].fX;
SkScalar Cy = src[3].fY + 3 * (src[1].fY - src[2].fY) - src[0].fY;
return SkFindUnitQuadRoots(Bx*Cy - By*Cx, Ax*Cy - Ay*Cx, Ax*By - Ay*Bx, tValues);
return SkFindUnitQuadRoots(Bx*Cy - By*Cx,
Ax*Cy - Ay*Cx,
Ax*By - Ay*Bx,
tValues);
}
int SkChopCubicAtInflections(const SkPoint src[], SkPoint dst[10]) {
@ -963,7 +968,9 @@ bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4],
return false;
}
int SkNumXRayCrossingsForCubic(const SkXRay& pt, const SkPoint cubic[4], bool* ambiguous) {
int SkNumXRayCrossingsForCubic(const SkXRay& pt,
const SkPoint cubic[4],
bool* ambiguous) {
int num_crossings = 0;
SkPoint monotonic_cubics[10];
int num_monotonic_cubics = SkChopCubicAtYExtrema(cubic, monotonic_cubics);
@ -971,19 +978,25 @@ int SkNumXRayCrossingsForCubic(const SkXRay& pt, const SkPoint cubic[4], bool* a
*ambiguous = false;
}
bool locally_ambiguous;
if (SkXRayCrossesMonotonicCubic(pt, &monotonic_cubics[0], &locally_ambiguous))
if (SkXRayCrossesMonotonicCubic(pt,
&monotonic_cubics[0],
&locally_ambiguous))
++num_crossings;
if (ambiguous) {
*ambiguous |= locally_ambiguous;
}
if (num_monotonic_cubics > 0)
if (SkXRayCrossesMonotonicCubic(pt, &monotonic_cubics[3], &locally_ambiguous))
if (SkXRayCrossesMonotonicCubic(pt,
&monotonic_cubics[3],
&locally_ambiguous))
++num_crossings;
if (ambiguous) {
*ambiguous |= locally_ambiguous;
}
if (num_monotonic_cubics > 1)
if (SkXRayCrossesMonotonicCubic(pt, &monotonic_cubics[6], &locally_ambiguous))
if (SkXRayCrossesMonotonicCubic(pt,
&monotonic_cubics[6],
&locally_ambiguous))
++num_crossings;
if (ambiguous) {
*ambiguous |= locally_ambiguous;
@ -1063,9 +1076,10 @@ static bool truncate_last_curve(const SkPoint quad[3], SkScalar x, SkScalar y,
static const SkPoint gQuadCirclePts[kSkBuildQuadArcStorage] = {
// The mid point of the quadratic arc approximation is half way between the two
// control points. The float epsilon adjustment moves the on curve point out by
// two bits, distributing the convex test error between the round rect approximation
// and the convex cross product sign equality test.
#define SK_MID_RRECT_OFFSET (SK_Scalar1 + SK_ScalarTanPIOver8 + FLT_EPSILON * 4) / 2
// two bits, distributing the convex test error between the round rect
// approximation and the convex cross product sign equality test.
#define SK_MID_RRECT_OFFSET \
(SK_Scalar1 + SK_ScalarTanPIOver8 + FLT_EPSILON * 4) / 2
{ SK_Scalar1, 0 },
{ SK_Scalar1, SK_ScalarTanPIOver8 },
{ SK_MID_RRECT_OFFSET, SK_MID_RRECT_OFFSET },
@ -1162,8 +1176,16 @@ int SkBuildQuadArc(const SkVector& uStart, const SkVector& uStop,
return pointCount;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// NURB representation for conics. Helpful explanations at:
//
// http://citeseerx.ist.psu.edu/viewdoc/
// download?doi=10.1.1.44.5740&rep=rep1&type=ps
// and
// http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/NURBS/RB-conics.html
//
// F = (A (1 - t)^2 + C t^2 + 2 B (1 - t) t w)
// ------------------------------------------
// ((1 - t)^2 + t^2 + 2 (1 - t) t w)
@ -1173,12 +1195,6 @@ int SkBuildQuadArc(const SkVector& uStart, const SkVector& uStop,
// {t^2 (2 - 2 w), t (-2 + 2 w), 1}
//
// Take the parametric specification for the conic (either X or Y) and return
// in coeff[] the coefficients for the simple quadratic polynomial
// coeff[0] for t^2
// coeff[1] for t
// coeff[2] for constant term
//
static SkScalar conic_eval_pos(const SkScalar src[], SkScalar w, SkScalar t) {
SkASSERT(src);
SkASSERT(t >= 0 && t <= SK_Scalar1);
@ -1210,7 +1226,9 @@ static SkScalar conic_eval_pos(const SkScalar src[], SkScalar w, SkScalar t) {
// coeff[1] for t^1
// coeff[2] for t^0
//
static void conic_deriv_coeff(const SkScalar src[], SkScalar w, SkScalar coeff[3]) {
static void conic_deriv_coeff(const SkScalar src[],
SkScalar w,
SkScalar coeff[3]) {
const SkScalar P20 = src[4] - src[0];
const SkScalar P10 = src[2] - src[0];
const SkScalar wP10 = w * P10;
@ -1300,7 +1318,8 @@ void SkConic::chopAt(SkScalar t, SkConic dst[2]) const {
// or
// w1 /= sqrt(w0*w2)
//
// However, in our case, we know that for dst[0], w0 == 1, and for dst[1], w2 == 1
// However, in our case, we know that for dst[0]:
// w0 == 1, and for dst[1], w2 == 1
//
SkScalar root = SkScalarSqrt(tmp2[1].fZ);
dst[0].fW = tmp2[0].fZ / root;
@ -1442,3 +1461,8 @@ void SkConic::computeTightBounds(SkRect* bounds) const {
void SkConic::computeFastBounds(SkRect* bounds) const {
bounds->set(fPts, 3);
}
bool SkConic::findMaxCurvature(SkScalar* t) const {
// TODO: Implement me
return false;
}