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 |