1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /////////////////////////////
18 // Geometry.h
19 // $Id: Geometry.h,v 1.2 2011/06/17 13:35:48 mbansal Exp $
20
21 #pragma once
22 #include "MosaicTypes.h"
23
24 ///////////////////////////////////////////////////////////////
25 ///////////////// BEG GLOBAL ROUTINES /////////////////////////
26 ///////////////////////////////////////////////////////////////
27
28
hypotSq(double a,double b)29 inline double hypotSq(double a, double b)
30 {
31 return ((a)*(a)+(b)*(b));
32 }
33
ClipRect(double x,double y,BlendRect & brect)34 inline void ClipRect(double x, double y, BlendRect &brect)
35 {
36 if (y < brect.bot) brect.bot = y;
37 if (y > brect.top) brect.top = y;
38 if (x < brect.lft) brect.lft = x;
39 if (x > brect.rgt) brect.rgt = x;
40 }
41
ClipRect(BlendRect rrect,BlendRect & brect)42 inline void ClipRect(BlendRect rrect, BlendRect &brect)
43 {
44 if (rrect.bot < brect.bot) brect.bot = rrect.bot;
45 if (rrect.top > brect.top) brect.top = rrect.top;
46 if (rrect.lft < brect.lft) brect.lft = rrect.lft;
47 if (rrect.rgt > brect.rgt) brect.rgt = rrect.rgt;
48 }
49
50 // Clip x to be within [-border,width+border-1]
clipToSegment(int & x,int width,int border)51 inline void clipToSegment(int &x, int width, int border)
52 {
53 if(x < -border)
54 x = -border;
55 else if(x >= width+border)
56 x = width + border - 1;
57 }
58
59 // Return true if x within [-border,width+border-1]
inSegment(int x,int width,int border)60 inline bool inSegment(int x, int width, int border)
61 {
62 return (x >= -border && x < width + border - 1);
63 }
64
FindTriangleCentroid(double x0,double y0,double x1,double y1,double x2,double y2,double & mass,double & centX,double & centY)65 inline void FindTriangleCentroid(double x0, double y0, double x1, double y1,
66 double x2, double y2,
67 double &mass, double ¢X, double ¢Y)
68 {
69 // Calculate the centroid of the triangle
70 centX = (x0 + x1 + x2) / 3.0;
71 centY = (y0 + y1 + y2) / 3.0;
72
73 // Calculate 2*Area for the triangle
74 if (y0 == y2)
75 {
76 if (x0 == x1)
77 {
78 mass = fabs((y1 - y0) * (x2 - x0)); // Special case 1a
79 }
80 else
81 {
82 mass = fabs((y1 - y0) * (x1 - x0)); // Special case 1b
83 }
84 }
85 else if (x0 == x2)
86 {
87 if (x0 == x1)
88 {
89 mass = fabs((x2 - x0) * (y2 - y0)); // Special case 2a
90 }
91 else
92 {
93 mass = fabs((x1 - x0) * (y2 - y0)); // Special case 2a
94 }
95 }
96 else if (x1 == x2)
97 {
98 mass = fabs((x1 - x0) * (y2 - y0)); // Special case 3
99 }
100 else
101 {
102 // Calculate line equation from x0,y0 to x2,y2
103 double dx = x2 - x0;
104 double dy = y2 - y0;
105 // Calculate the length of the side
106 double len1 = sqrt(dx * dx + dy * dy);
107 double m1 = dy / dx;
108 double b1 = y0 - m1 * x0;
109 // Calculate the line that goes through x1,y1 and is perpendicular to
110 // the other line
111 double m2 = 1.0 / m1;
112 double b2 = y1 - m2 * x1;
113 // Calculate the intersection of the two lines
114 if (fabs( m1 - m2 ) > 1.e-6)
115 {
116 double x = (b2 - b1) / (m1 - m2);
117 // the mass is the base * height
118 dx = x1 - x;
119 dy = y1 - m1 * x + b1;
120 mass = len1 * sqrt(dx * dx + dy * dy);
121 }
122 else
123 {
124 mass = fabs( (y1 - y0) * (x2 - x0) );
125 }
126 }
127 }
128
FindQuadCentroid(double x0,double y0,double x1,double y1,double x2,double y2,double x3,double y3,double & centX,double & centY)129 inline void FindQuadCentroid(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3,
130 double ¢X, double ¢Y)
131
132 {
133 // To find the centroid:
134 // 1) Divide the quadrilateral into two triangles by scribing a diagonal
135 // 2) Calculate the centroid of each triangle (the intersection of the angle bisections).
136 // 3) Find the centroid of the quad by weighting each triangle centroids by their area.
137
138 // Calculate the corner points
139 double z;
140
141 // The quad is split from x0,y0 to x2,y2
142 double mass1, mass2, cent1x, cent2x, cent1y, cent2y;
143 FindTriangleCentroid(x0, y0, x1, y1, x2, y2, mass1, cent1x, cent1y);
144 FindTriangleCentroid(x0, y0, x3, y3, x2, y2, mass2, cent2x, cent2y);
145
146 // determine position of quad centroid
147 z = mass2 / (mass1 + mass2);
148 centX = cent1x + (cent2x - cent1x) * z;
149 centY = cent1y + (cent2y - cent1y) * z;
150 }
151
152 ///////////////////////////////////////////////////////////////
153 ////////////////// END GLOBAL ROUTINES ////////////////////////
154 ///////////////////////////////////////////////////////////////
155
156
157