View Javadoc

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