1 /*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
5 package cz.cuni.amis.pogamut.usar2004.samples.AirScanner;
6
7 import math.geom2d.Point2D;
8
9 /**
10 *
11 * @author vejmanm
12 */
13 public class Obstacle1
14 {
15 public static final double obstacleSize = 1d;
16 public static final double joinDistance = 1.5d;
17 public static final double maxExtendRatio = 4;
18 public static final double maxEdgeSize = 5;
19 private Point2D start;
20 private Point2D stop;
21
22 public Obstacle1(Point2D corner, double width, double height)
23 {
24 this.start = corner;
25 this.stop = new Point2D(corner.x + width, corner.y + height);
26 }
27
28 public Obstacle1(Point2D start, Point2D stop)
29 {
30 this.start = start;
31 this.stop = stop;
32 }
33
34 /**
35 * Initial constructor, center is the center of an obstacle, width and
36 * height is given by robot dimension(0.5). From the center point it is
37 * computed the corner Point also.
38 *
39 * @param center Center of a new obstacle.
40 */
41 public Obstacle1(Point2D center)
42 {
43 this(center.x, center.y);
44 }
45
46 public Obstacle1(double centerX, double centerY)
47 {
48 this.start = new Point2D(centerX - obstacleSize / 2, centerY - obstacleSize / 2);
49 this.stop = new Point2D(centerX + obstacleSize / 2, centerY + obstacleSize / 2);
50 }
51
52 /**
53 * Extends obstacle bounds when new obstacle found near existing one.
54 *
55 * @param x X coordinate of the centre of a new obstacle
56 * @param y Y coordinate of the centre of a new obstacle
57 * @return Returns true if obstacle was extended, false otherwise
58 */
59 private boolean extend(double x, double y)
60 {
61 boolean success = false;
62
63 if(x + obstacleSize / 2 > stop.x)
64 {
65 stop.x = x + obstacleSize / 2;
66 success = true;
67 }
68 if(y + obstacleSize / 2 > stop.y)
69 {
70 stop.y = y + obstacleSize / 2;
71 success = true;
72 }
73 if(x - obstacleSize / 2 < start.x)
74 {
75 start.x = x - obstacleSize / 2;
76 success = true;
77 }
78 if(y - obstacleSize / 2 < start.y)
79 {
80 start.y = y - obstacleSize / 2;
81 success = true;
82 }
83
84 return success;
85 }
86
87 // <editor-fold desc="Getters" defaultstatestate="collapsed">
88 public double getWidth()
89 {
90 return stop.x - start.x;
91 }
92
93 public double getHeight()
94 {
95 return stop.y - start.y;
96 }
97
98 public Point2D getCorner()
99 {
100 return start;
101 }
102 // </editor-fold>
103
104 /**
105 * If new Obstacle [x,y] is within the distance of joinDistance, i will
106 * extend this Obstacle boundbox by this point [x,y] plus its own boundbox
107 * of obstacleSize. If a small square is within the absorb region of this
108 * rectangle, it will enlarge itself to absorb this square so we don't need
109 * to create a new obstacle object.
110 *
111 * @param x x coordinate of new obstacle (Obstacle of a minimum size)
112 * @param y y coordinate of new obstacle (Obstacle of a minimum size)
113 * @return Returns Can = 1, Can not = -1 and is already inside = 0
114 */
115 public Obstacle1 tryExtend(double x, double y)
116 {
117 if(x > this.start.x - joinDistance
118 && x < this.stop.x + joinDistance
119 && y > this.start.y - joinDistance
120 && y < this.stop.y + joinDistance)
121 {
122 if(extend(x, y))
123 extendCount++;
124 return this;
125 }
126 return null;
127 }
128 private int extendCount = 0;
129
130 /**
131 * If Obstacle grows only one dimension enough we don't want to extend it
132 * nomore. It is good to have more smaller more accurate than fewer larger
133 * and sitorted obstacle boundboxes.
134 *
135 * @return Returns if obstacle is able to grow
136 */
137 public boolean canExtend()
138 {
139 return extendCount<3;
140 // double width = Math.abs(start.x - stop.x);
141 // double height = Math.abs(start.y - stop.y);
142 // double edgeRatio = width / height;
143 // if(edgeRatio > maxEdgeSize || edgeRatio < 1 / maxEdgeSize)
144 // {
145 // return false;
146 // }
147 // if(width > maxEdgeSize || height > maxEdgeSize)
148 // {
149 // return false;
150 // }
151 // return true;
152 }
153
154 public boolean isInside(double x, double y)
155 {
156 if(x > this.start.x
157 && x < this.stop.x
158 && y > this.start.y
159 && y < this.stop.y)
160 {
161 return true;
162 }
163 return false;
164 }
165
166 public boolean isWithin(double x, double y)
167 {
168 if(x > this.start.x - obstacleSize / 2
169 && x < this.stop.x + obstacleSize / 2
170 && y > this.start.y - obstacleSize / 2
171 && y < this.stop.y + obstacleSize / 2)
172 {
173 return true;
174 }
175 return false;
176 }
177
178 public static Obstacle1 MergeObstacles(Obstacle1 blockA, Obstacle1 blockB)
179 {
180 //shorter terms
181 double xA = blockA.start.x;
182 double xB = blockB.start.x;
183 double yA = blockA.start.y;
184 double yB = blockB.start.y;
185 //C = right lower corner of block A
186 //D = right lower corner of block B
187 double xC = blockA.start.x;
188 double yC = blockA.start.y;
189 double xD = blockB.stop.x;
190 double yD = blockB.stop.y;
191 //leftest and highest Point
192 Point2D newStart = new Point2D(Math.min(xA, xB), Math.min(yA, yB));
193 Point2D newStop = new Point2D(Math.min(xC, xD), Math.min(yC, yD));
194 return new Obstacle1(newStart, newStop);
195 }
196 }