OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "SkMathPriv.h" | 9 #include "SkMathPriv.h" |
10 #include "SkPoint.h" | 10 #include "SkPoint.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 static inline float getLengthSquared(float dx, float dy) { | 81 static inline float getLengthSquared(float dx, float dy) { |
82 return dx * dx + dy * dy; | 82 return dx * dx + dy * dy; |
83 } | 83 } |
84 | 84 |
85 // Calculates the square of the Euclidian distance to (dx,dy) and stores it in | 85 // Calculates the square of the Euclidian distance to (dx,dy) and stores it in |
86 // *lengthSquared. Returns true if the distance is judged to be "nearly zero". | 86 // *lengthSquared. Returns true if the distance is judged to be "nearly zero". |
87 // | 87 // |
88 // This logic is encapsulated in a helper method to make it explicit that we | 88 // This logic is encapsulated in a helper method to make it explicit that we |
89 // always perform this check in the same manner, to avoid inconsistencies | 89 // always perform this check in the same manner, to avoid inconsistencies |
90 // (see http://code.google.com/p/skia/issues/detail?id=560 ). | 90 // (see http://code.google.com/p/skia/issues/detail?id=560 ). |
91 static inline bool isLengthNearlyZero(float dx, float dy, | 91 static inline bool is_length_nearly_zero(float dx, float dy, |
92 float *lengthSquared) { | 92 float *lengthSquared) { |
93 *lengthSquared = getLengthSquared(dx, dy); | 93 *lengthSquared = getLengthSquared(dx, dy); |
94 return *lengthSquared <= (SK_ScalarNearlyZero * SK_ScalarNearlyZero); | 94 return *lengthSquared <= (SK_ScalarNearlyZero * SK_ScalarNearlyZero); |
95 } | 95 } |
96 | 96 |
97 SkScalar SkPoint::Normalize(SkPoint* pt) { | 97 SkScalar SkPoint::Normalize(SkPoint* pt) { |
98 float x = pt->fX; | 98 float x = pt->fX; |
99 float y = pt->fY; | 99 float y = pt->fY; |
100 float mag2; | 100 float mag2; |
101 if (isLengthNearlyZero(x, y, &mag2)) { | 101 if (is_length_nearly_zero(x, y, &mag2)) { |
102 pt->set(0, 0); | 102 pt->set(0, 0); |
103 return 0; | 103 return 0; |
104 } | 104 } |
105 | 105 |
106 float mag, scale; | 106 float mag, scale; |
107 if (SkScalarIsFinite(mag2)) { | 107 if (SkScalarIsFinite(mag2)) { |
108 mag = sk_float_sqrt(mag2); | 108 mag = sk_float_sqrt(mag2); |
109 scale = 1 / mag; | 109 scale = 1 / mag; |
110 } else { | 110 } else { |
111 // our mag2 step overflowed to infinity, so use doubles instead. | 111 // our mag2 step overflowed to infinity, so use doubles instead. |
(...skipping 27 matching lines...) Expand all Loading... |
139 /* | 139 /* |
140 * We have to worry about 2 tricky conditions: | 140 * We have to worry about 2 tricky conditions: |
141 * 1. underflow of mag2 (compared against nearlyzero^2) | 141 * 1. underflow of mag2 (compared against nearlyzero^2) |
142 * 2. overflow of mag2 (compared w/ isfinite) | 142 * 2. overflow of mag2 (compared w/ isfinite) |
143 * | 143 * |
144 * If we underflow, we return false. If we overflow, we compute again using | 144 * If we underflow, we return false. If we overflow, we compute again using |
145 * doubles, which is much slower (3x in a desktop test) but will not overflow. | 145 * doubles, which is much slower (3x in a desktop test) but will not overflow. |
146 */ | 146 */ |
147 bool SkPoint::setLength(float x, float y, float length) { | 147 bool SkPoint::setLength(float x, float y, float length) { |
148 float mag2; | 148 float mag2; |
149 if (isLengthNearlyZero(x, y, &mag2)) { | 149 if (is_length_nearly_zero(x, y, &mag2)) { |
150 this->set(0, 0); | 150 this->set(0, 0); |
151 return false; | 151 return false; |
152 } | 152 } |
153 | 153 |
154 float scale; | 154 float scale; |
155 if (SkScalarIsFinite(mag2)) { | 155 if (SkScalarIsFinite(mag2)) { |
156 scale = length / sk_float_sqrt(mag2); | 156 scale = length / sk_float_sqrt(mag2); |
157 } else { | 157 } else { |
158 // our mag2 step overflowed to infinity, so use doubles instead. | 158 // our mag2 step overflowed to infinity, so use doubles instead. |
159 // much slower, but needed when x or y are very large, other wise we | 159 // much slower, but needed when x or y are very large, other wise we |
(...skipping 16 matching lines...) Expand all Loading... |
176 fY = y * scale; | 176 fY = y * scale; |
177 return true; | 177 return true; |
178 } | 178 } |
179 | 179 |
180 bool SkPoint::setLengthFast(float length) { | 180 bool SkPoint::setLengthFast(float length) { |
181 return this->setLengthFast(fX, fY, length); | 181 return this->setLengthFast(fX, fY, length); |
182 } | 182 } |
183 | 183 |
184 bool SkPoint::setLengthFast(float x, float y, float length) { | 184 bool SkPoint::setLengthFast(float x, float y, float length) { |
185 float mag2; | 185 float mag2; |
186 if (isLengthNearlyZero(x, y, &mag2)) { | 186 if (is_length_nearly_zero(x, y, &mag2)) { |
187 this->set(0, 0); | 187 this->set(0, 0); |
188 return false; | 188 return false; |
189 } | 189 } |
190 | 190 |
191 float scale; | 191 float scale; |
192 if (SkScalarIsFinite(mag2)) { | 192 if (SkScalarIsFinite(mag2)) { |
193 scale = length * sk_float_rsqrt(mag2); // <--- this is the difference | 193 scale = length * sk_float_rsqrt(mag2); // <--- this is the difference |
194 } else { | 194 } else { |
195 // our mag2 step overflowed to infinity, so use doubles instead. | 195 // our mag2 step overflowed to infinity, so use doubles instead. |
196 // much slower, but needed when x or y are very large, other wise we | 196 // much slower, but needed when x or y are very large, other wise we |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 return v.lengthSqd(); | 255 return v.lengthSqd(); |
256 } else if (uDotV > uLengthSqd) { | 256 } else if (uDotV > uLengthSqd) { |
257 return b.distanceToSqd(*this); | 257 return b.distanceToSqd(*this); |
258 } else { | 258 } else { |
259 SkScalar det = u.cross(v); | 259 SkScalar det = u.cross(v); |
260 SkScalar temp = det / uLengthSqd; | 260 SkScalar temp = det / uLengthSqd; |
261 temp *= det; | 261 temp *= det; |
262 return temp; | 262 return temp; |
263 } | 263 } |
264 } | 264 } |
OLD | NEW |