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
29inline double hypotSq(double a, double b)
30{
31    return ((a)*(a)+(b)*(b));
32}
33
34inline 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
42inline 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]
51inline 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]
60inline bool inSegment(int x, int width, int border)
61{
62    return (x >= -border && x < width + border - 1);
63}
64
65inline void FindTriangleCentroid(double x0, double y0, double x1, double y1,
66                                    double x2, double y2,
67                                    double &mass, double &centX, double &centY)
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
129inline void FindQuadCentroid(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3,
130                                     double &centX, double &centY)
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