soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SRect.cpp
1
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include <souistd.h>
10#include "matrix/SRect.h"
11
12SNSBEGIN
13
14void SRect::sort()
15{
16 if (fLeft > fRight)
17 {
18 STSwap<float>(fLeft, fRight);
19 }
20 if (fTop > fBottom)
21 {
22 STSwap<float>(fTop, fBottom);
23 }
24}
25
26void SRect::toQuad(SPoint quad[4]) const
27{
28 SASSERT(quad);
29
30 quad[0].set(fLeft, fTop);
31 quad[1].set(fRight, fTop);
32 quad[2].set(fRight, fBottom);
33 quad[3].set(fLeft, fBottom);
34}
35
36bool SRect::setBoundsCheck(const SPoint pts[], int count)
37{
38 SASSERT((pts && count > 0) || count == 0);
39
40 bool isFinite = true;
41
42 if (count <= 0)
43 {
44 memset(this, 0, sizeof(SRect));
45 }
46 else
47 {
48 float l, t, r, b;
49
50 l = r = pts[0].fX;
51 t = b = pts[0].fY;
52
53 // If all of the points are finite, accum should stay 0. If we encounter
54 // a NaN or infinity, then accum should become NaN.
55 float accum = 0;
56 accum *= l;
57 accum *= t;
58
59 for (int i = 1; i < count; i++)
60 {
61 float x = pts[i].fX;
62 float y = pts[i].fY;
63
64 accum *= x;
65 accum *= y;
66
67 // we use if instead of if/else, so we can generate min/max
68 // float instructions (at least on SSE)
69 if (x < l)
70 l = x;
71 if (x > r)
72 r = x;
73
74 if (y < t)
75 t = y;
76 if (y > b)
77 b = y;
78 }
79
80 SASSERT(!accum || !SFloatIsFinite(accum));
81 if (accum)
82 {
83 l = t = r = b = 0;
84 isFinite = false;
85 }
86 this->set(l, t, r, b);
87 }
88
89 return isFinite;
90}
91
92// http://www.blackpawn.com/texts/pointinpoly/default.html
93// return true if pt is inside triangle; false if outside or on the line
94bool STriangle::contains(const SPoint &pt) const
95{
96 // Compute vectors
97 SPoint v0 = fPts[2] - fPts[0];
98 SPoint v1 = fPts[1] - fPts[0];
99 SPoint v2 = pt - fPts[0];
100
101 // Compute dot products
102 double dot00 = v0.dot(v0);
103 double dot01 = v0.dot(v1);
104 double dot02 = v0.dot(v2);
105 double dot11 = v1.dot(v1);
106 double dot12 = v1.dot(v2);
107
108 double w = dot00 * dot11 - dot01 * dot01;
109 if (w == 0)
110 {
111 return false;
112 }
113 double wSign = w < 0 ? -1 : 1;
114 double u = (dot11 * dot02 - dot01 * dot12) * wSign;
115 if (u <= 0)
116 {
117 return false;
118 }
119 double v = (dot00 * dot12 - dot01 * dot02) * wSign;
120 if (v <= 0)
121 {
122 return false;
123 }
124 return u + v < w * wSign;
125}
126
127bool SQuad::contains(const SPoint &pt) const
128{
129 bool bRet = false;
130 if (!bRet)
131 {
132 STriangle tri;
133 tri.fPts[0] = fPts[0];
134 tri.fPts[1] = fPts[1];
135 tri.fPts[2] = fPts[2];
136 bRet = tri.contains(pt);
137 }
138 if (!bRet)
139 {
140 STriangle tri;
141 tri.fPts[0] = fPts[0];
142 tri.fPts[1] = fPts[2];
143 tri.fPts[2] = fPts[3];
144 bRet = tri.contains(pt);
145 }
146 return bRet;
147}
148
149SNSEND