Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1051 chris 1
package com.gebauz.bauzoid.math.collisionx;
2
 
3
import com.badlogic.gdx.Gdx;
4
import com.gebauz.bauzoid.graphics.spritex.Sprite;
5
import com.gebauz.bauzoid.math.Line2;
6
import com.gebauz.bauzoid.math.MathUtil;
7
import com.gebauz.bauzoid.math.Matrix4;
8
import com.gebauz.bauzoid.math.Vector2;
9
import com.gebauz.bauzoid.math.Vector4;
10
 
11
public class EllipseElement extends BaseShapeElement
12
{
13
        // Constants========================================================================================
14
 
15
        public static final int NUM_LINE_SEGMENTS = 12;
16
 
17
        // Embedded Types===================================================================================
18
 
19
        // Fields===========================================================================================
20
 
21
        public float x;
22
        public float y;
23
        public float radiusX;
24
        public float radiusY;
25
 
26
        // Methods==========================================================================================
27
 
28
        public EllipseElement(float initX, float initY, float initRadiusX, float initRadiusY)
29
        {
30
                x = initX; y = initY;
31
                radiusX = initRadiusX; radiusY = initRadiusY;
32
        }
33
 
34
        @Override
35
        public boolean isInside(float pX, float pY)
36
        {
37
                float diffX = pX - x;
38
                float diffY = pY - y;
39
 
40
                return (((diffX * diffX) / (radiusX * radiusX) + (diffY * diffY) / (radiusY * radiusY)) <= 1.0f);
41
        }
42
 
43
        private Vector4[] getLineSegments(Matrix4 transform)
44
        {
45
                Vector4 points[] = new Vector4[NUM_LINE_SEGMENTS];
46
 
47
                final float angleStep = 360.0f / NUM_LINE_SEGMENTS;
48
 
49
                if (transform != null)
50
                {
51
                        for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
52
                        {
53
                                points[i] = transform.transform(new Vector4(x + MathUtil.sin(angleStep * (float)i) * radiusX, y + MathUtil.cos(angleStep * (float)i) * radiusY, 0, 1));
54
                        }
55
                }
56
                else
57
                {
58
                        for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
59
                        {
60
                                //points[i] = new Vector4(MathUtil.sin(angleStep * (float)i), MathUtil.cos(angleStep * (float)i), 0, 1);
61
                                points[i] = new Vector4(x + MathUtil.sin(angleStep * (float)i) * radiusX, y + MathUtil.cos(angleStep * (float)i) * radiusY, 0, 1);
62
                        }
63
                }
64
                return points;
65
        }
66
 
67
        private Vector4[] getLineSegments()
68
        {
69
                return getLineSegments(null);
70
        }
71
 
72
        @Override
73
        public boolean intersects(Shape shape, Matrix4 transform)
74
        {
75
                Vector4 points[] = getLineSegments(transform);
76
 
77
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
78
                {
79
                        int j = (i + 1) % (NUM_LINE_SEGMENTS-1);
80
 
81
                        if (shape.isInside(points[i].x, points[i].y) || shape.isInside(points[j].x, points[j].y))
82
                        {
83
                                return true;
84
                        }
85
 
86
                        Line2 line = new Line2(points[i].x, points[i].y, points[j].x, points[j].y);
87
                        if (shape.intersectsLine(line))
88
                                return true;
89
                }              
90
 
91
                return false;
92
        }
93
 
94
        /*
95
     bool SegmentIntersectRectangle(double a_rectangleMinX,
96
                                 double a_rectangleMinY,
97
                                 double a_rectangleMaxX,
98
                                 double a_rectangleMaxY,
99
                                 double a_p1x,
100
                                 double a_p1y,
101
                                 double a_p2x,
102
                                 double a_p2y)
103
  {
104
    // Find min and max X for the segment
105
 
106
    double minX = a_p1x;
107
    double maxX = a_p2x;
108
 
109
    if(a_p1x > a_p2x)
110
    {
111
      minX = a_p2x;
112
      maxX = a_p1x;
113
    }
114
 
115
    // Find the intersection of the segment's and rectangle's x-projections
116
 
117
    if(maxX > a_rectangleMaxX)
118
    {
119
      maxX = a_rectangleMaxX;
120
    }
121
 
122
    if(minX < a_rectangleMinX)
123
    {
124
      minX = a_rectangleMinX;
125
    }
126
 
127
    if(minX > maxX) // If their projections do not intersect return false
128
    {
129
      return false;
130
    }
131
 
132
    // Find corresponding min and max Y for min and max X we found before
133
 
134
    double minY = a_p1y;
135
    double maxY = a_p2y;
136
 
137
    double dx = a_p2x - a_p1x;
138
 
139
    if(Math::Abs(dx) > 0.0000001)
140
    {
141
      double a = (a_p2y - a_p1y) / dx;
142
      double b = a_p1y - a * a_p1x;
143
      minY = a * minX + b;
144
      maxY = a * maxX + b;
145
    }
146
 
147
    if(minY > maxY)
148
    {
149
      double tmp = maxY;
150
      maxY = minY;
151
      minY = tmp;
152
    }
153
 
154
    // Find the intersection of the segment's and rectangle's y-projections
155
 
156
    if(maxY > a_rectangleMaxY)
157
    {
158
      maxY = a_rectangleMaxY;
159
    }
160
 
161
    if(minY < a_rectangleMinY)
162
    {
163
      minY = a_rectangleMinY;
164
    }
165
 
166
    if(minY > maxY) // If Y-projections do not intersect return false
167
    {
168
      return false;
169
    }
170
 
171
    return true;
172
  }
173
        */
174
        @Override
175
        public boolean intersects(Shape shape, Matrix4 transform, Vector2 displaceResult)
176
        {
177
                return intersects(shape, transform);
178
 
179
                // shape is static level element, this shape element is from ship
180
                // transform this shape element's element into static level element space
181
                // check if there is an intersection and get the displacement vector from the static level element's shape
182
                // the caller needs to transform the displace result back into global space (half of transform.inv)
183
 
184
                /*Vector4 points[] = getLineSegments(transform);
185
                Vector2 displaceVectors[] = new Vector2[points.length];
186
 
187
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
188
                {
189
                        displaceVectors[i] = new Vector2(0, 0);
190
                }
191
 
192
                boolean result = false;
193
 
194
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
195
                {
196
                        int j = (i + 1) % (NUM_LINE_SEGMENTS-1);
197
 
198
                        Line2 line = new Line2(points[i].x, points[j].y, points[j].x, points[j].y);
199
 
200
                        if (shape.isInside(points[i].x, points[i].y))
201
                        {
202
                                Vector2 v = line.getMinimalVectorFrom(points[i].x, points[i].y);
203
 
204
                                if (v.squaredLength() > displaceVectors[i].squaredLength())
205
                                        displaceResult.set(v.x, v.y);
206
 
207
                                result = true;
208
                        }
209
 
210
                        if (shape.isInside(points[j].x, points[j].y))
211
                        {                              
212
                                Vector2 v = line.getMinimalVectorFrom(points[j].x, points[j].y);
213
 
214
                                if (v.squaredLength() > displaceVectors[i].squaredLength())
215
                                        displaceResult.set(v.x, v.y);
216
 
217
                                result = true;
218
                        }
219
 
220
                        if (shape.intersectsLine(line))
221
                        {
222
                                Vector2 v = line.getMinimalVectorFrom(points[j].x, points[j].y);
223
 
224
                                if (v.squaredLength() > displaceVectors[i].squaredLength())
225
                                        displaceResult.set(v.x, v.y);
226
 
227
                                result = true;
228
                        }
229
                }              
230
 
231
                return result;*/
232
        }
233
 
234
 
235
 
236
        public boolean intersectsLine(Line2 line)
237
        {
238
                // speed up by not using line segments but actual ellipse formula
239
 
240
                Vector4 points[] = getLineSegments();
241
 
242
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
243
                {
244
                        int j = (i + 1) % (NUM_LINE_SEGMENTS-1);
245
 
246
                        Line2 thisLine = new Line2(points[i].x, points[i].y, points[j].x, points[j].y);
247
                        if (thisLine.intersectsSegment(line))
248
                                return true;
249
                }
250
 
251
                return false;
252
        }
253
 
254
        public void debugRender(Sprite sprite)
255
        {
256
 
257
        }
258
 
259
        // Getters/Setters==================================================================================
260
 
261
}
262
 
263