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"
24 void view::poly_shape_hit_test::add_point(const float x, const float y)
30 bool view::poly_shape_hit_test::hit_test(const float x, const float y,
31 const bool polygon, const int w) const
36 /* 1. Check if the point in the bounding box of a poly-figure */
37 if (!hit_test_bounding_box(x, y))
40 /* 2. Check if the point near the polyline */
41 if (hit_test_polyline(x, y, polygon, w))
44 /* 3. Check if the point near the vertices */
45 if (hit_test_vertices(x, y))
48 /* 4. Check if the point inside the polygon (for polygon only) */
56 bool view::poly_shape_hit_test::hit_test_bounding_box(const float x, const float y) const
58 float x_min = 1. * FLT_MAX;
59 float x_max = 1. * FLT_MIN;
60 float y_min = 1. * FLT_MAX;
61 float y_max = 1. * FLT_MIN;
62 for (unsigned int i = 0; i < __x.size(); i ++) {
77 return ((x >= x_min) && (x <= x_max)
78 && (y >= y_min) && (y <= y_max));
81 bool view::poly_shape_hit_test::hit_test_segment(const float x1, const float y1,
82 const float x2, const float y2, const float x, const float y, const int w) const
86 float c = sqrt(a * a + b * b);
92 float x_shifted = x - x1;
93 float y_shifted = y - y1;
94 float x_rotated = x_shifted * cosa + y_shifted * sina;
95 float y_rotated = x_shifted * sina - y_shifted * cosa;
97 if ((x_rotated >= 0) && (x_rotated <= c)
98 && (y_rotated >= (-1. * (accuracy + (float)w / 2))
99 && (y_rotated <= (accuracy + (float)w / 2)))
104 bool view::poly_shape_hit_test::hit_test_polyline(const float x, const float y,
105 const bool polygon, const int w) const
110 for (unsigned int i = 1; i < __x.size(); i ++) {
111 if (hit_test_segment(__x[i - 1], __y[i - 1],
112 __x[i], __y[i], x, y, w))
118 if (hit_test_segment(__x[__x.size() - 1], __y[__x.size() - 1],
119 __x[0], __y[0], x, y))
126 bool view::poly_shape_hit_test::hit_test_vertices(const float x, const float y) const
128 for (unsigned int i = 0; i < __x.size(); i ++) {
129 float cur_x_min = __x[i] - accuracy;
130 float cur_x_max = __x[i] + accuracy;
131 float cur_y_min = __y[i] - accuracy;
132 float cur_y_max = __y[i] + accuracy;
133 if ((x >= cur_x_min) && (x <= cur_x_max)
134 && (y >= cur_y_min) && (y <= cur_y_max))
142 * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
144 bool view::poly_shape_hit_test::pnpoly(const float x, const float y) const
147 const int nvert = int(__x.size());
148 for (i = 0, j = nvert-1; i < nvert; j = i++) {
149 if ( ((__y[i] > y) != (__y[j] > y)) &&
150 (x < (__x[j] - __x[i]) * (y - __y[i])
151 / (__y[j] - __y[i]) + __x[i]) ) {