Blame |
Last modification |
View Log
| RSS feed
package com.gebauz.bauzoid.math.collisionx;
import com.badlogic.gdx.Gdx;
import com.gebauz.bauzoid.graphics.spritex.Sprite;
import com.gebauz.bauzoid.math.Line2;
import com.gebauz.bauzoid.math.MathUtil;
import com.gebauz.bauzoid.math.Matrix4;
import com.gebauz.bauzoid.math.Vector2;
import com.gebauz.bauzoid.math.Vector4;
public class EllipseElement
extends BaseShapeElement
{
// Constants========================================================================================
public static final int NUM_LINE_SEGMENTS =
12;
// Embedded Types===================================================================================
// Fields===========================================================================================
public float x
;
public float y
;
public float radiusX
;
public float radiusY
;
// Methods==========================================================================================
public EllipseElement
(float initX,
float initY,
float initRadiusX,
float initRadiusY
)
{
x = initX
; y = initY
;
radiusX = initRadiusX
; radiusY = initRadiusY
;
}
@
Override
public boolean isInside
(float pX,
float pY
)
{
float diffX = pX - x
;
float diffY = pY - y
;
return (((diffX
* diffX
) /
(radiusX
* radiusX
) +
(diffY
* diffY
) /
(radiusY
* radiusY
)) <= 1.0f
);
}
private Vector4
[] getLineSegments
(Matrix4 transform
)
{
Vector4 points
[] =
new Vector4
[NUM_LINE_SEGMENTS
];
final float angleStep = 360.0f / NUM_LINE_SEGMENTS
;
if (transform
!=
null)
{
for (int i =
0; i
< NUM_LINE_SEGMENTS
; i++
)
{
points
[i
] = transform.
transform(new Vector4
(x + MathUtil.
sin(angleStep
* (float)i
) * radiusX, y + MathUtil.
cos(angleStep
* (float)i
) * radiusY,
0,
1));
}
}
else
{
for (int i =
0; i
< NUM_LINE_SEGMENTS
; i++
)
{
//points[i] = new Vector4(MathUtil.sin(angleStep * (float)i), MathUtil.cos(angleStep * (float)i), 0, 1);
points
[i
] =
new Vector4
(x + MathUtil.
sin(angleStep
* (float)i
) * radiusX, y + MathUtil.
cos(angleStep
* (float)i
) * radiusY,
0,
1);
}
}
return points
;
}
private Vector4
[] getLineSegments
()
{
return getLineSegments
(null);
}
@
Override
public boolean intersects
(Shape shape, Matrix4 transform
)
{
Vector4 points
[] = getLineSegments
(transform
);
for (int i =
0; i
< NUM_LINE_SEGMENTS
; i++
)
{
int j =
(i +
1) % (NUM_LINE_SEGMENTS-
1);
if (shape.
isInside(points
[i
].
x, points
[i
].
y) || shape.
isInside(points
[j
].
x, points
[j
].
y))
{
return true;
}
Line2 line =
new Line2
(points
[i
].
x, points
[i
].
y, points
[j
].
x, points
[j
].
y);
if (shape.
intersectsLine(line
))
return true;
}
return false;
}
/*
bool SegmentIntersectRectangle(double a_rectangleMinX,
double a_rectangleMinY,
double a_rectangleMaxX,
double a_rectangleMaxY,
double a_p1x,
double a_p1y,
double a_p2x,
double a_p2y)
{
// Find min and max X for the segment
double minX = a_p1x;
double maxX = a_p2x;
if(a_p1x > a_p2x)
{
minX = a_p2x;
maxX = a_p1x;
}
// Find the intersection of the segment's and rectangle's x-projections
if(maxX > a_rectangleMaxX)
{
maxX = a_rectangleMaxX;
}
if(minX < a_rectangleMinX)
{
minX = a_rectangleMinX;
}
if(minX > maxX) // If their projections do not intersect return false
{
return false;
}
// Find corresponding min and max Y for min and max X we found before
double minY = a_p1y;
double maxY = a_p2y;
double dx = a_p2x - a_p1x;
if(Math::Abs(dx) > 0.0000001)
{
double a = (a_p2y - a_p1y) / dx;
double b = a_p1y - a * a_p1x;
minY = a * minX + b;
maxY = a * maxX + b;
}
if(minY > maxY)
{
double tmp = maxY;
maxY = minY;
minY = tmp;
}
// Find the intersection of the segment's and rectangle's y-projections
if(maxY > a_rectangleMaxY)
{
maxY = a_rectangleMaxY;
}
if(minY < a_rectangleMinY)
{
minY = a_rectangleMinY;
}
if(minY > maxY) // If Y-projections do not intersect return false
{
return false;
}
return true;
}
*/
@
Override
public boolean intersects
(Shape shape, Matrix4 transform, Vector2 displaceResult
)
{
return intersects
(shape, transform
);
// shape is static level element, this shape element is from ship
// transform this shape element's element into static level element space
// check if there is an intersection and get the displacement vector from the static level element's shape
// the caller needs to transform the displace result back into global space (half of transform.inv)
/*Vector4 points[] = getLineSegments(transform);
Vector2 displaceVectors[] = new Vector2[points.length];
for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
{
displaceVectors[i] = new Vector2(0, 0);
}
boolean result = false;
for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
{
int j = (i + 1) % (NUM_LINE_SEGMENTS-1);
Line2 line = new Line2(points[i].x, points[j].y, points[j].x, points[j].y);
if (shape.isInside(points[i].x, points[i].y))
{
Vector2 v = line.getMinimalVectorFrom(points[i].x, points[i].y);
if (v.squaredLength() > displaceVectors[i].squaredLength())
displaceResult.set(v.x, v.y);
result = true;
}
if (shape.isInside(points[j].x, points[j].y))
{
Vector2 v = line.getMinimalVectorFrom(points[j].x, points[j].y);
if (v.squaredLength() > displaceVectors[i].squaredLength())
displaceResult.set(v.x, v.y);
result = true;
}
if (shape.intersectsLine(line))
{
Vector2 v = line.getMinimalVectorFrom(points[j].x, points[j].y);
if (v.squaredLength() > displaceVectors[i].squaredLength())
displaceResult.set(v.x, v.y);
result = true;
}
}
return result;*/
}
public boolean intersectsLine
(Line2 line
)
{
// speed up by not using line segments but actual ellipse formula
Vector4 points
[] = getLineSegments
();
for (int i =
0; i
< NUM_LINE_SEGMENTS
; i++
)
{
int j =
(i +
1) % (NUM_LINE_SEGMENTS-
1);
Line2 thisLine =
new Line2
(points
[i
].
x, points
[i
].
y, points
[j
].
x, points
[j
].
y);
if (thisLine.
intersectsSegment(line
))
return true;
}
return false;
}
public void debugRender
(Sprite sprite
)
{
}
// Getters/Setters==================================================================================
}