1 /* Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "poly_shape_hit_test.h"
23 void view::poly_shape_hit_test::add_point(const float x, const float y)
29 bool view::poly_shape_hit_test::hit_test(const float x, const float y,
30 const bool polygon, const int w) const
35 /* 1. Check if the point in the bounding box of a poly-figure */
36 if (!hit_test_bounding_box(x, y))
39 /* 2. Check if the point near the polyline */
40 if (hit_test_polyline(x, y, polygon, w))
43 /* 3. Check if the point near the vertices */
44 if (hit_test_vertices(x, y))
47 /* 4. Check if the point inside the polygon (for polygon only) */
55 bool view::poly_shape_hit_test::hit_test_bounding_box(const float x, const float y) const
57 float x_min = 1. * FLT_MAX;
58 float x_max = 1. * FLT_MIN;
59 float y_min = 1. * FLT_MAX;
60 float y_max = 1. * FLT_MIN;
61 for (unsigned int i = 0; i < __x.size(); i ++) {
76 return ((x >= x_min) && (x <= x_max)
77 && (y >= y_min) && (y <= y_max));
80 bool view::poly_shape_hit_test::hit_test_segment(const float x1, const float y1,
81 const float x2, const float y2, const float x, const float y, const int w) const
85 float c = sqrt(a * a + b * b);
91 float x_shifted = x - x1;
92 float y_shifted = y - y1;
93 float x_rotated = x_shifted * cosa + y_shifted * sina;
94 float y_rotated = x_shifted * sina - y_shifted * cosa;
96 if ((x_rotated >= 0) && (x_rotated <= c)
97 && (y_rotated >= (-1. * (accuracy + w / 2)))
98 && (y_rotated <= (accuracy + w / 2)))
103 bool view::poly_shape_hit_test::hit_test_polyline(const float x, const float y,
104 const bool polygon, const int w) const
109 for (unsigned int i = 1; i < __x.size(); i ++) {
110 if (hit_test_segment(__x[i - 1], __y[i - 1],
111 __x[i], __y[i], x, y, w))
117 if (hit_test_segment(__x[__x.size() - 1], __y[__x.size() - 1],
118 __x[0], __y[0], x, y))
125 bool view::poly_shape_hit_test::hit_test_vertices(const float x, const float y) const
127 for (unsigned int i = 0; i < __x.size(); i ++) {
128 float cur_x_min = __x[i] - accuracy;
129 float cur_x_max = __x[i] + accuracy;
130 float cur_y_min = __y[i] - accuracy;
131 float cur_y_max = __y[i] + accuracy;
132 if ((x >= cur_x_min) && (x <= cur_x_max)
133 && (y >= cur_y_min) && (y <= cur_y_max))
141 * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
143 bool view::poly_shape_hit_test::pnpoly(const float x, const float y) const
146 const int nvert = int(__x.size());
147 for (i = 0, j = nvert-1; i < nvert; j = i++) {
148 if ( ((__y[i] > y) != (__y[j] > y)) &&
149 (x < (__x[j] - __x[i]) * (y - __y[i])
150 / (__y[j] - __y[i]) + __x[i]) ) {