| 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 |