Added a EditorSocial.
[UnsignedByte.git] / src / Resource / Path.cpp
blob8fd6bee64cdebda47c30a172ac195102b73c8e67
1 /***************************************************************************
2 * Copyright (C) 2007 by Daniel Brody *
3 * erasnode@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "Coordinate.h"
22 #include "Path.h"
24 Path::Path(const Coordinate& from, const Coordinate& to ) :
25 m_from(from),
26 m_to(to)
28 reset();
31 void Path::reset()
33 //assign the component values in the transform
34 m_xcomponent = m_to.getXCoordinate() - m_from.getXCoordinate();
35 m_ycomponent = m_to.getYCoordinate() - m_from.getYCoordinate();
36 m_zcomponent = m_to.getZCoordinate() - m_from.getZCoordinate();
39 void Path::setFrom(const Coordinate& from)
41 m_from = from;
42 reset();
45 void Path::setTo(const Coordinate& to)
47 m_to = to;
48 reset();
51 const Coordinate& Path::getFrom() const
53 return m_from;
56 const Coordinate& Path::getTo() const
58 return m_to;
61 long Path::length() const
63 long x_length = abs(m_xcomponent);
64 long y_length = abs(m_ycomponent);
65 long z_length = abs(m_zcomponent);
67 if (x_length >= y_length && x_length >= z_length)
68 return x_length;
69 else if (y_length >= z_length)
70 return y_length;
71 else
72 return z_length;
75 const Coordinate& Path::direction() const
77 long ratio = 10;
78 long threshold = 20;
80 long x = m_xcomponent;
81 long y = m_ycomponent;
82 long z = m_zcomponent;
84 long x_length = abs(x);
85 long y_length = abs(y);
86 long z_length = abs(z);
89 //********* x is largest component **********//
91 if (x_length >= y_length && x_length >= z_length)
93 if (x>0) //x is +ve (east)
95 if (y>0 && (x_length*ratio)/y_length<=threshold) //y is +ve and a decent ratio of x
97 if (z==0) //z will be 0 in most situations
98 return Coordinate::NE;
99 else if (z>0 && (x_length*ratio)/z_length<=threshold) //z has to be a decent ratio too
100 return Coordinate::NEUP;
101 else if (z<0 && (x_length*ratio)/z_length<=threshold)
102 return Coordinate::NEDOWN;
103 else
104 return Coordinate::NE; //in case z isn't 0, but irrelevant
106 else if (y<0 && (x_length*ratio)/y_length<=threshold) //y is -ve and a decent ratio of x
108 if (z==0)
109 return Coordinate::SE;
110 else if (z>0 && (x_length*ratio)/z_length<=threshold)
111 return Coordinate::SEUP;
112 else if (z<0 && (x_length*ratio)/z_length<=threshold)
113 return Coordinate::SEDOWN;
114 else
115 return Coordinate::SE;
117 else //catch the irrelevant and 0 cases of y
119 if (z==0)
120 return Coordinate::EAST;
121 else if (z>0 && (x_length*ratio)/z_length<=threshold)
122 return Coordinate::EUP;
123 else if (z<0 && (x_length*ratio)/z_length<=threshold)
124 return Coordinate::EDOWN;
125 else
126 return Coordinate::EAST;
130 else if (x<0) //x is -ve (west)
132 if (y>0 && (x_length*ratio)/y_length<=threshold) //same stuff as x +ve
134 if (z==0)
135 return Coordinate::NW; //west this time
136 else if (z>0 && (x_length*ratio)/z_length<=threshold)
137 return Coordinate::NWUP;
138 else if (z<0 && (x_length*ratio)/z_length<=threshold)
139 return Coordinate::NWDOWN;
140 else
141 return Coordinate::NW;
143 else if (y<0 && (x_length*ratio)/y_length<=threshold)
145 if (z==0)
146 return Coordinate::SW;
147 else if (z>0 && (x_length*ratio)/z_length<=threshold)
148 return Coordinate::SWUP;
149 else if (z<0 && (x_length*ratio)/z_length<=threshold)
150 return Coordinate::SWDOWN;
151 else
152 return Coordinate::SW;
154 else
156 if (z==0)
157 return Coordinate::WEST;
158 else if (z>0 && (x_length*ratio)/z_length<=threshold)
159 return Coordinate::WUP;
160 else if (z<0 && (x_length*ratio)/z_length<=threshold)
161 return Coordinate::WDOWN;
162 else
163 return Coordinate::WEST;
168 //********* y is largest component **********//
170 else if (y_length >= z_length) //x has been checked already
172 if (y>0) //y is +ve (north)
174 if (x>0 && (y_length*ratio)/x_length<=threshold) //x is +ve (east)
176 if (z==0) //the rest is very similar to before
177 return Coordinate::NE;
178 else if (z>0 && (y_length*ratio)/z_length<=threshold)
179 return Coordinate::NEUP;
180 else if (z<0 && (y_length*ratio)/z_length<=threshold)
181 return Coordinate::NEDOWN;
182 else
183 return Coordinate::NE; //in case z isn't 0, but irrelevant
185 else if (x<0 && (y_length*ratio)/x_length<=threshold) //x is -ve (west)
187 if (z==0)
188 return Coordinate::NW;
189 else if (z>0 && (y_length*ratio)/z_length<=threshold)
190 return Coordinate::NWUP;
191 else if (z<0 && (y_length*ratio)/z_length<=threshold)
192 return Coordinate::NWDOWN;
193 else
194 return Coordinate::NW;
196 else //x is irrelevant or 0
198 if (z==0)
199 return Coordinate::NORTH;
200 else if (z>0 && (y_length*ratio)/z_length<=threshold)
201 return Coordinate::NUP;
202 else if (z<0 && (y_length*ratio)/z_length<=threshold)
203 return Coordinate::NDOWN;
204 else
205 return Coordinate::NORTH;
209 else if (y<0) //y is -ve (south)
211 if (x>0 && (y_length*ratio)/x_length<=threshold) //x is +ve (east)
213 if (z==0)
214 return Coordinate::SE;
215 else if (z>0 && (y_length*ratio)/z_length<=threshold)
216 return Coordinate::SEUP;
217 else if (z<0 && (y_length*ratio)/z_length<=threshold)
218 return Coordinate::SEDOWN;
219 else
220 return Coordinate::SE;
222 else if (x<0 && (y_length*ratio)/x_length<=threshold) //x is -ve (west)
224 if (z==0)
225 return Coordinate::SW;
226 else if (z>0 && (y_length*ratio)/z_length<=threshold)
227 return Coordinate::SWUP;
228 else if (z<0 && (y_length*ratio)/z_length<=threshold)
229 return Coordinate::SWDOWN;
230 else
231 return Coordinate::SW;
233 else //if x is irrelevant
235 if (z==0)
236 return Coordinate::SOUTH;
237 else if (z>0 && (y_length*ratio)/z_length<=threshold)
238 return Coordinate::SUP;
239 else if (z<0 && (y_length*ratio)/z_length<=threshold)
240 return Coordinate::SDOWN;
241 else
242 return Coordinate::SOUTH;
247 //********* z is largest component **********//
249 else //z has to be largest
251 if (z>0) //z is +ve (up)
253 if (x>0 && (z_length*ratio)/x_length<=threshold) //using a bigger ratio to narrow
254 { //the 'cone' of pure UP
255 if (y>0 && (z_length*ratio)/y_length<=threshold)
256 return Coordinate::NEUP;
257 else if (y<0 && (z_length*ratio)/y_length<=threshold)
258 return Coordinate::SEUP;
259 else
260 return Coordinate::EUP; //in case y is irrelevant
262 else if (x<0 && (z_length*ratio)/x_length<=threshold) //x is -ve (west)
264 if (y>0 && (z_length*ratio)/y_length<=threshold) //y is +ve (north)
265 return Coordinate::NWUP;
266 else if (y<0 && (z_length*ratio)/y_length<=threshold) //y is -ve (south)
267 return Coordinate::SWUP;
268 else
269 return Coordinate::WUP;
271 else //x is irrelevant or 0
273 if (y>0 && (z_length*ratio)/y_length<=threshold) //if y is +ve and decent ratio
274 return Coordinate::NUP;
275 else if (y<0 && (z_length*ratio)/y_length<=threshold) //y is -ve
276 return Coordinate::SUP;
277 else
278 return Coordinate::UP; //y AND x are irrelevant or 0
282 else if (z<0) //z is -ve (down)
284 if (x>0 && (z_length*ratio)/x_length<=threshold) //x is +ve (east)
286 if (y>0 && (z_length*ratio)/y_length<=threshold)
287 return Coordinate::NEDOWN;
288 else if (y<0 && (z_length*ratio)/y_length<=threshold)
289 return Coordinate::SEDOWN;
290 else
291 return Coordinate::EDOWN;
293 else if (x<0 && (z_length*ratio)/x_length<=threshold) //x is -ve (west)
295 if (y>0 && (z_length*ratio)/y_length<=threshold)
296 return Coordinate::NWDOWN;
297 else if (y<0 && (z_length*ratio)/y_length<=threshold)
298 return Coordinate::SWDOWN;
299 else
300 return Coordinate::WDOWN;
302 else //if x is irrelevant
304 if (y>0 && (z_length*ratio)/y_length<=threshold)
305 return Coordinate::NDOWN;
306 else if (y<0 && (z_length*ratio)/y_length<=threshold)
307 return Coordinate::SDOWN;
308 else
309 return Coordinate::DOWN; //x AND y are irrelevant or 0
315 std::vector<Coordinate> Path::route() const
317 std::vector<Coordinate> route;
318 long distance = length();
319 Path thePath(m_from, m_to);
321 for(long i = 0; i < distance; i++)
323 route.push_back(thePath.getTo()); //push destination to route
324 thePath.setTo(thePath.getTo() - thePath.direction()); //increment destination closer
327 return route;