aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu/include/GrPoint.h
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-12-22 21:39:39 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-12-22 21:39:39 +0000
commitac10a2d039c5d52eed66e27cbbc503ab523c1cd5 (patch)
treec5be0c3dd15052016e7d32f376507cb1ea7101dd /gpu/include/GrPoint.h
parentea8509cd3b1771b36054313d3ccd56679df56044 (diff)
add gpu backend (not hooked up yet)
git-svn-id: http://skia.googlecode.com/svn/trunk@649 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu/include/GrPoint.h')
-rw-r--r--gpu/include/GrPoint.h287
1 files changed, 287 insertions, 0 deletions
diff --git a/gpu/include/GrPoint.h b/gpu/include/GrPoint.h
new file mode 100644
index 0000000000..bb24959c34
--- /dev/null
+++ b/gpu/include/GrPoint.h
@@ -0,0 +1,287 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrPoint_DEFINED
+#define GrPoint_DEFINED
+
+#include "GrTypes.h"
+#include "GrScalar.h"
+
+/**
+ * 2D Point struct
+ */
+struct GrPoint {
+public:
+ GrScalar fX, fY;
+
+ GrPoint() {}
+ GrPoint(GrScalar x, GrScalar y) { fX = x; fY = y; }
+
+ GrScalar x() const { return fX; }
+ GrScalar y() const { return fY; }
+
+ void set(GrScalar x, GrScalar y) {
+ fX = x;
+ fY = y;
+ }
+
+ void setAsMidPoint(const GrPoint& a, const GrPoint& b) {
+ fX = GrScalarAve(a.fX, b.fX);
+ fY = GrScalarAve(a.fY, b.fY);
+ }
+
+ void offset(GrScalar dx, GrScalar dy) {
+ fX += dx;
+ fY += dy;
+ }
+
+ GrScalar distanceToSqd(const GrPoint& p) const {
+ GrScalar dx = (p.fX - fX);
+ GrScalar dy = (p.fY - fY);
+ return GrMul(dx, dx) + GrMul(dy, dy);
+ }
+
+ GrScalar distanceTo(const GrPoint& p) const {
+ // TODO: fixed point sqrt
+ return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToSqd(p))));
+ }
+
+ GrScalar distanceToOriginSqd() const {
+ return GrMul(fX, fX) + GrMul(fY, fY);
+ }
+
+ GrScalar distanceToOrigin() const {
+ return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToOriginSqd())));
+ }
+
+ inline GrScalar distanceToLineBetweenSqd(const GrPoint& a,
+ const GrPoint& b) const;
+
+ inline GrScalar distanceToLineBetween(const GrPoint& a,
+ const GrPoint& b) const;
+
+ inline GrScalar distanceToLineSegmentBetweenSqd(const GrPoint& a,
+ const GrPoint& b) const;
+
+ inline GrScalar distanceToLineSegmentBetween(const GrPoint& a,
+ const GrPoint& b) const;
+
+ // counter-clockwise fan
+ void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b) {
+ GrPoint* v = this;
+ v[0].set(l, t);
+ v[1].set(l, b);
+ v[2].set(r, b);
+ v[3].set(r, t);
+ }
+
+ void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b, size_t stride) {
+ GrAssert(stride >= sizeof(GrPoint));
+ ((GrPoint*)((intptr_t)this + 0 * stride))->set(l, t);
+ ((GrPoint*)((intptr_t)this + 1 * stride))->set(l, b);
+ ((GrPoint*)((intptr_t)this + 2 * stride))->set(r, b);
+ ((GrPoint*)((intptr_t)this + 3 * stride))->set(r, t);
+ }
+
+ // counter-clockwise fan
+ void setIRectFan(int l, int t, int r, int b) {
+ GrPoint* v = this;
+ v[0].set(GrIntToScalar(l), GrIntToScalar(t));
+ v[1].set(GrIntToScalar(l), GrIntToScalar(b));
+ v[2].set(GrIntToScalar(r), GrIntToScalar(b));
+ v[3].set(GrIntToScalar(r), GrIntToScalar(t));
+ }
+
+ void setIRectFan(int l, int t, int r, int b, size_t stride) {
+ GrAssert(stride >= sizeof(GrPoint));
+ ((GrPoint*)((intptr_t)this + 0 * stride))->set(GrIntToScalar(l),
+ GrIntToScalar(t));
+ ((GrPoint*)((intptr_t)this + 1 * stride))->set(GrIntToScalar(l),
+ GrIntToScalar(b));
+ ((GrPoint*)((intptr_t)this + 2 * stride))->set(GrIntToScalar(r),
+ GrIntToScalar(b));
+ ((GrPoint*)((intptr_t)this + 3 * stride))->set(GrIntToScalar(r),
+ GrIntToScalar(t));
+ }
+
+ bool operator ==(const GrPoint& p) const {
+ return fX == p.fX && fY == p.fY;
+ }
+
+ bool operator !=(const GrPoint& p) const {
+ return fX != p.fX || fY != p.fY;
+ }
+};
+
+struct GrIPoint16 {
+ int16_t fX, fY;
+
+ void set(intptr_t x, intptr_t y) {
+ fX = GrToS16(x);
+ fY = GrToS16(y);
+ }
+};
+
+struct GrVec {
+public:
+ GrScalar fX, fY;
+
+ GrVec() {}
+ GrVec(GrScalar x, GrScalar y) { fX = x; fY = y; }
+
+ GrScalar x() const { return fX; }
+ GrScalar y() const { return fY; }
+
+ /**
+ * set x and y length of the vector.
+ */
+ void set(GrScalar x, GrScalar y) {
+ fX = x;
+ fY = y;
+ }
+
+ /**
+ * set vector to point from a to b.
+ */
+ void setBetween(const GrPoint& a, const GrPoint& b) {
+ fX = b.fX - a.fX;
+ fY = b.fY - a.fY;
+ }
+
+ /**
+ * length of the vector squared.
+ */
+ GrScalar lengthSqd() const {
+ return GrMul(fX, fX) + GrMul(fY, fY);
+ }
+
+ /**
+ * length of the vector.
+ */
+ GrScalar length() const {
+ // TODO: fixed point sqrt
+ return GrFloatToScalar(sqrtf(GrScalarToFloat(lengthSqd())));
+ }
+
+ /**
+ * normalizes the vector if it's length is not 0.
+ * @return true if normalized, otherwise false.
+ */
+ bool normalize() {
+ GrScalar l = lengthSqd();
+ if (l) {
+ // TODO: fixed point sqrt and invert
+ l = 1 / sqrtf(l);
+ fX *= l;
+ fY *= l;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Dot product of this with vec.
+ */
+ GrScalar dot(const GrVec& vec) const {
+ return GrMul(vec.fX, fX) + GrMul(vec.fY, fY);
+ }
+
+ /**
+ * z-value of this cross vec.
+ */
+ GrScalar cross(const GrVec& vec) const {
+ return GrMul(fX, vec.fY) - GrMul(fY, vec.fX);
+ }
+
+ bool operator ==(const GrPoint& p) const {
+ return fX == p.fX && fY == p.fY;
+ }
+
+ bool operator !=(const GrPoint& p) const {
+ return fX != p.fX || fY != p.fY;
+ }
+};
+
+GrScalar GrPoint::distanceToLineBetweenSqd(const GrPoint& a,
+ const GrPoint& b) const {
+ // Let d be the distance between c (this) and line ab.
+ // The area of the triangle defined by a, b, and c is
+ // A = |b-a|*d/2. Let u = b-a and v = c-a. The cross product of
+ // u and v is aligned with the z axis and its magnitude is 2A.
+ // So d = |u x v| / |u|.
+ GrVec u, v;
+ u.setBetween(a,b);
+ v.setBetween(a,*this);
+
+ GrScalar det = u.cross(v);
+ return (GrMul(det, det)) / u.lengthSqd();
+}
+
+GrScalar GrPoint::distanceToLineBetween(const GrPoint& a,
+ const GrPoint& b) const {
+ GrVec u, v;
+ u.setBetween(a,b);
+ v.setBetween(a,*this);
+
+ GrScalar det = u.cross(v);
+ return (GrScalarAbs(det)) / u.length();
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetweenSqd(const GrPoint& a,
+ const GrPoint& 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|.
+
+ GrVec u, v;
+ u.setBetween(a,b);
+ v.setBetween(a,*this);
+
+ GrScalar uLengthSqd = u.lengthSqd();
+ GrScalar uDotV = u.dot(v);
+
+ if (uDotV <= 0) {
+ return v.lengthSqd();
+ } else if (uDotV > uLengthSqd) {
+ return b.distanceToSqd(*this);
+ } else {
+ GrScalar det = u.cross(v);
+ return (GrMul(det, det)) / uLengthSqd;
+ }
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetween(const GrPoint& a,
+ const GrPoint& b) const {
+ // TODO: fixed point sqrt
+ return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToLineSegmentBetweenSqd(a,b))));
+}
+
+
+#endif
+