1 -- Swamp Bike Opera embedded system for Kaffe Matthews
2 -- Copyright (C) 2012 Wolfgang Hauptfleisch, Dave Griffiths
3 --
4 -- This program is free software: you can redistribute it and/or modify
5 -- it under the terms of the GNU General Public License as published by
6 -- the Free Software Foundation, either version 3 of the License, or
7 -- (at your option) any later version.
8 --
9 -- This program is distributed in the hope that it will be useful,
10 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 -- GNU General Public License for more details.
13 --
14 -- You should have received a copy of the GNU General Public License
15 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 module("poly", package.seeall)
19 ---
20 -- define if point is inside a polygon
21 function is_in_polygon(vertices, x, y)
22         local intersectionCount = 0
24         local x0 = vertices[#vertices].x - x
25         local y0 = vertices[#vertices].y - y
27         for i=1,#vertices do
28                 local x1 = vertices[i].x - x
29                 local y1 = vertices[i].y - y
31                 if y0 > 0 and y1 <= 0 and x1 * y0 > y1 * x0 then
32                         intersectionCount = intersectionCount + 1
33                 end
35                 if y1 > 0 and y0 <= 0 and x0 * y1 > y0 * x1 then
36                         intersectionCount = intersectionCount + 1
37                 end
39                 x0 = x1
40                 y0 = y1
41         end
43         return (intersectionCount % 2) == 1
44 end
47 ---
48 -- calculate the centre of a polygon
49 function centroid(polygon)
50   local xsum = 0
51   local ysum = 0
53 for i, p in ipairs(polygon) do
54     xsum = xsum + p.x
55     ysum = ysum + p.y
56 end
58 local k = table.getn(polygon)
59 local cx = xsum / k
60 local cy = ysum / k
62 return cx, cy
63 end
67 ---
68 -- calculate the distance between two coordinates
69 function distance(x1, y1, x2, y2)
70  local d = math.sqrt( math.pow((x2 - x1),2) + math.pow((y2 - y1), 2) )
72 return d
73 end
76 ---
77 --
78 function direction()
80 -- todo
82 end
85 ---
86 --
87 function angle(x1,y1,x2,y2)
88    local radians = math.atan((x2-x1)/(y2-y1));
89    local degrees = radians *  180 / math.pi;
91 return degrees
92 end
95 ---
96 --
97 function direction(x1, x2, y1, y2)
98     local angle = math.atan2(y2 - y1, x2 - x1) * 180 / math.pi;
100 return angle
101 end
104 ---
105 -- we can shift(move) a polygon into 4 directions
106 --
107 function polygon_shift(polygon, towards, offset)
109 local offset = offset or 1
110 local new_polygon = {}
112 for i, point in ipairs(polygon) do
114    if towards == "east" then
115       local x = point.x + offset
116       table.insert(new_polygon, { x = x, y = point.y } )
117    elseif towards == "north" then
118       local y = y + offset
119       table.insert(new_polygon, { x = point.x, y = y } )
120    elseif towards == "west" then
121       local x = point.x - offset
122       table.insert(new_polygon, { x = x, y = point.y } )
123    elseif towards == "south" then
124       local y = y - offset
125       table.insert(new_polygon, { x = point.x, y = y } )
126    end
128 end
130 return new_polygon
131 end