| OLD | NEW |
| 1 /* | 1 /* |
| 2 http://stackoverflow.com/questions/2009160/how-do-i-convert-the-2-control-points
-of-a-cubic-curve-to-the-single-control-poi | 2 http://stackoverflow.com/questions/2009160/how-do-i-convert-the-2-control-points
-of-a-cubic-curve-to-the-single-control-poi |
| 3 */ | 3 */ |
| 4 | 4 |
| 5 /* | 5 /* |
| 6 Let's call the control points of the cubic Q0..Q3 and the control points of the
quadratic P0..P2. | 6 Let's call the control points of the cubic Q0..Q3 and the control points of the
quadratic P0..P2. |
| 7 Then for degree elevation, the equations are: | 7 Then for degree elevation, the equations are: |
| 8 | 8 |
| 9 Q0 = P0 | 9 Q0 = P0 |
| 10 Q1 = 1/3 P0 + 2/3 P1 | 10 Q1 = 1/3 P0 + 2/3 P1 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 | 114 |
| 115 // flavor that returns T values only, deferring computing the quads until they a
re needed | 115 // flavor that returns T values only, deferring computing the quads until they a
re needed |
| 116 // FIXME: when called from recursive intersect 2, this could take the original c
ubic | 116 // FIXME: when called from recursive intersect 2, this could take the original c
ubic |
| 117 // and do a more precise job when calling chop at and sub divide by computing th
e fractional ts. | 117 // and do a more precise job when calling chop at and sub divide by computing th
e fractional ts. |
| 118 // it would still take the prechopped cubic for reduce order and find cubic infl
ections | 118 // it would still take the prechopped cubic for reduce order and find cubic infl
ections |
| 119 void SkDCubic::toQuadraticTs(double precision, SkTArray<double, true>* ts) const
{ | 119 void SkDCubic::toQuadraticTs(double precision, SkTArray<double, true>* ts) const
{ |
| 120 SkReduceOrder reducer; | 120 SkReduceOrder reducer; |
| 121 int order = reducer.reduce(*this, SkReduceOrder::kAllow_Quadratics, SkReduce
Order::kFill_Style); | 121 int order = reducer.reduce(*this, SkReduceOrder::kAllow_Quadratics); |
| 122 if (order < 3) { | 122 if (order < 3) { |
| 123 return; | 123 return; |
| 124 } | 124 } |
| 125 double inflectT[5]; | 125 double inflectT[5]; |
| 126 int inflections = findInflections(inflectT); | 126 int inflections = findInflections(inflectT); |
| 127 SkASSERT(inflections <= 2); | 127 SkASSERT(inflections <= 2); |
| 128 if (!endsAreExtremaInXOrY()) { | 128 if (!endsAreExtremaInXOrY()) { |
| 129 inflections += findMaxCurvature(&inflectT[inflections]); | 129 inflections += findMaxCurvature(&inflectT[inflections]); |
| 130 SkASSERT(inflections <= 5); | 130 SkASSERT(inflections <= 5); |
| 131 } | 131 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 146 continue; | 146 continue; |
| 147 } | 147 } |
| 148 memmove(&inflectT[start], &inflectT[next], sizeof(inflectT[0]) * (--infl
ections - start)); | 148 memmove(&inflectT[start], &inflectT[next], sizeof(inflectT[0]) * (--infl
ections - start)); |
| 149 } while (true); | 149 } while (true); |
| 150 while (inflections && approximately_greater_than_one(inflectT[inflections -
1])) { | 150 while (inflections && approximately_greater_than_one(inflectT[inflections -
1])) { |
| 151 --inflections; | 151 --inflections; |
| 152 } | 152 } |
| 153 SkDCubicPair pair; | 153 SkDCubicPair pair; |
| 154 if (inflections == 1) { | 154 if (inflections == 1) { |
| 155 pair = chopAt(inflectT[0]); | 155 pair = chopAt(inflectT[0]); |
| 156 int orderP1 = reducer.reduce(pair.first(), SkReduceOrder::kNo_Quadratics
, | 156 int orderP1 = reducer.reduce(pair.first(), SkReduceOrder::kNo_Quadratics
); |
| 157 SkReduceOrder::kFill_Style); | |
| 158 if (orderP1 < 2) { | 157 if (orderP1 < 2) { |
| 159 --inflections; | 158 --inflections; |
| 160 } else { | 159 } else { |
| 161 int orderP2 = reducer.reduce(pair.second(), SkReduceOrder::kNo_Quadr
atics, | 160 int orderP2 = reducer.reduce(pair.second(), SkReduceOrder::kNo_Quadr
atics); |
| 162 SkReduceOrder::kFill_Style); | |
| 163 if (orderP2 < 2) { | 161 if (orderP2 < 2) { |
| 164 --inflections; | 162 --inflections; |
| 165 } | 163 } |
| 166 } | 164 } |
| 167 } | 165 } |
| 168 if (inflections == 0 && add_simple_ts(*this, precision, ts)) { | 166 if (inflections == 0 && add_simple_ts(*this, precision, ts)) { |
| 169 return; | 167 return; |
| 170 } | 168 } |
| 171 if (inflections == 1) { | 169 if (inflections == 1) { |
| 172 pair = chopAt(inflectT[0]); | 170 pair = chopAt(inflectT[0]); |
| 173 addTs(pair.first(), precision, 0, inflectT[0], ts); | 171 addTs(pair.first(), precision, 0, inflectT[0], ts); |
| 174 addTs(pair.second(), precision, inflectT[0], 1, ts); | 172 addTs(pair.second(), precision, inflectT[0], 1, ts); |
| 175 return; | 173 return; |
| 176 } | 174 } |
| 177 if (inflections > 1) { | 175 if (inflections > 1) { |
| 178 SkDCubic part = subDivide(0, inflectT[0]); | 176 SkDCubic part = subDivide(0, inflectT[0]); |
| 179 addTs(part, precision, 0, inflectT[0], ts); | 177 addTs(part, precision, 0, inflectT[0], ts); |
| 180 int last = inflections - 1; | 178 int last = inflections - 1; |
| 181 for (int idx = 0; idx < last; ++idx) { | 179 for (int idx = 0; idx < last; ++idx) { |
| 182 part = subDivide(inflectT[idx], inflectT[idx + 1]); | 180 part = subDivide(inflectT[idx], inflectT[idx + 1]); |
| 183 addTs(part, precision, inflectT[idx], inflectT[idx + 1], ts); | 181 addTs(part, precision, inflectT[idx], inflectT[idx + 1], ts); |
| 184 } | 182 } |
| 185 part = subDivide(inflectT[last], 1); | 183 part = subDivide(inflectT[last], 1); |
| 186 addTs(part, precision, inflectT[last], 1, ts); | 184 addTs(part, precision, inflectT[last], 1, ts); |
| 187 return; | 185 return; |
| 188 } | 186 } |
| 189 addTs(*this, precision, 0, 1, ts); | 187 addTs(*this, precision, 0, 1, ts); |
| 190 } | 188 } |
| OLD | NEW |