aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkPoint.cpp
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-06 19:26:26 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-06 19:26:26 +0000
commit7744c205f20b5617e83d4af8f97b5771bfa8d671 (patch)
treed63034e8dd4649c998ce01997417d3e0d015a0a7 /src/core/SkPoint.cpp
parent2e550127e68fcf050f07840fc1102b8471a3b6d0 (diff)
use SkPoint, creating an alias for GrPoint
Diffstat (limited to 'src/core/SkPoint.cpp')
-rw-r--r--src/core/SkPoint.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/core/SkPoint.cpp b/src/core/SkPoint.cpp
index feca12f7ff..b5941d589e 100644
--- a/src/core/SkPoint.cpp
+++ b/src/core/SkPoint.cpp
@@ -36,6 +36,29 @@ void SkIPoint::rotateCCW(SkIPoint* dst) const {
///////////////////////////////////////////////////////////////////////////////
+void SkPoint::setIRectFan(int l, int t, int r, int b, size_t stride) {
+ SkASSERT(stride >= sizeof(SkPoint));
+
+ ((SkPoint*)((intptr_t)this + 0 * stride))->set(SkIntToScalar(l),
+ SkIntToScalar(t));
+ ((SkPoint*)((intptr_t)this + 1 * stride))->set(SkIntToScalar(l),
+ SkIntToScalar(b));
+ ((SkPoint*)((intptr_t)this + 2 * stride))->set(SkIntToScalar(r),
+ SkIntToScalar(b));
+ ((SkPoint*)((intptr_t)this + 3 * stride))->set(SkIntToScalar(r),
+ SkIntToScalar(t));
+}
+
+void SkPoint::setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b,
+ size_t stride) {
+ SkASSERT(stride >= sizeof(SkPoint));
+
+ ((SkPoint*)((intptr_t)this + 0 * stride))->set(l, t);
+ ((SkPoint*)((intptr_t)this + 1 * stride))->set(l, b);
+ ((SkPoint*)((intptr_t)this + 2 * stride))->set(r, b);
+ ((SkPoint*)((intptr_t)this + 3 * stride))->set(r, t);
+}
+
void SkPoint::rotateCW(SkPoint* dst) const {
SkASSERT(dst);
@@ -343,3 +366,39 @@ bool SkPoint::setLength(SkFixed ox, SkFixed oy, SkFixed length) {
#endif
+///////////////////////////////////////////////////////////////////////////////
+
+SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
+ const SkPoint& b) const {
+ // See comments to distanceToLineBetweenSqd. If the projection of c onto
+ // u is between a and b then this returns the same result as that
+ // function. Otherwise, it returns the distance to the closer of a and
+ // b. Let the projection of v onto u be v'. There are three cases:
+ // 1. v' points opposite to u. c is not between a and b and is closer
+ // to a than b.
+ // 2. v' points along u and has magnitude less than y. c is between
+ // a and b and the distance to the segment is the same as distance
+ // to the line ab.
+ // 3. v' points along u and has greater magnitude than u. c is not
+ // not between a and b and is closer to b than a.
+ // v' = (u dot v) * u / |u|. So if (u dot v)/|u| is less than zero we're
+ // in case 1. If (u dot v)/|u| is > |u| we are in case 3. Otherwise
+ // we're in case 2. We actually compare (u dot v) to 0 and |u|^2 to
+ // avoid a sqrt to compute |u|.
+
+ SkVector u = b - a;
+ SkVector v = *this - a;
+
+ SkScalar uLengthSqd = u.lengthSqd();
+ SkScalar uDotV = SkPoint::DotProduct(u, v);
+
+ if (uDotV <= 0) {
+ return v.lengthSqd();
+ } else if (uDotV > uLengthSqd) {
+ return b.distanceToSqd(*this);
+ } else {
+ SkScalar det = u.cross(v);
+ return SkScalarMulDiv(det, det, uLengthSqd);
+ }
+}
+