package com.gebauz.bauzoid.math.collision;
import java.util.Vector;
import com.gebauz.bauzoid.graphics.Graphics;
import com.gebauz.bauzoid.graphics.RenderUtil;
import com.gebauz.bauzoid.graphics.sprite.SpriteTransform;
import com.gebauz.bauzoid.math.Line2;
import com.gebauz.bauzoid.math.Vector2;
import com.gebauz.bauzoid.math.Vector4;
/** Convex polygon element class. */
public class PolyElement
extends BaseShapeElement
{
// Constants========================================================================================
// Embedded Types===================================================================================
// Fields===========================================================================================
private Vector2
[] mPolyPoints =
null;
private Vector2 mTempA =
new Vector2
();
private Vector2 mTempB =
new Vector2
();
// Methods==========================================================================================
public PolyElement
(Shape shape, Vector2
[] points,
int startFrame,
int endFrame
)
{
super(shape, startFrame, endFrame
);
mPolyPoints =
new Vector2
[points.
length];
for (int i =
0; i
< points.
length; i++
)
mPolyPoints
[i
] = points
[i
].
copy();
}
public PolyElement
(Shape shape,
Vector<Vector2
> points,
int startFrame,
int endFrame
)
{
super(shape, startFrame, endFrame
);
mPolyPoints =
new Vector2
[points.
size()];
for (int i =
0; i
< points.
size(); i++
)
mPolyPoints
[i
] = points.
get(i
).
copy();
}
public PolyElement
(Shape shape, Vector2
[] points
)
{
this(shape, points, -
1, -
1);
}
public PolyElement
(Shape shape,
Vector<Vector2
> points
)
{
this(shape, points, -
1, -
1);
}
@
Override
public BaseShapeElement copy
(Shape newOwner
)
{
return new PolyElement
(newOwner, mPolyPoints
);
}
@
Override
public void renderDebug
(Graphics graphics, SpriteTransform t
)
{
for (int i =
0; i
< mPolyPoints.
length; i++
)
{
int j =
(i+
1) % mPolyPoints.
length;
RenderUtil.
drawLine(graphics, mPolyPoints
[i
].
x * t.
w, mPolyPoints
[i
].
y * t.
h, mPolyPoints
[j
].
x * t.
w, mPolyPoints
[j
].
y * t.
h, t,
new Vector4
(0,
1,
0,
1));
}
}
@
Override
public boolean isInside
(float x,
float y
)
{
/*Vector2[] points = getPoints();
int i;
int j;
boolean result = false;
for (i = 0, j = points.length - 1; i < points.length; j = i++)
{
if ((points[i].y > y) != (points[j].y > y) &&
(x < (points[j].x - points[i].x) * (y - points[i].y) / (points[j].y-points[i].y) + points[i].x))
{
result = !result;
}
}
return result;*/
/*public boolean contains(Point test) {
int i;
int j;
boolean result = false;
for (i = 0, j = points.length - 1; i < points.length; j = i++) {
if ((points[i].y > test.y) != (points[j].y > test.y) &&
(test.x < (points[j].x - points[i].x) * (test.y - points[i].y) / (points[j].y-points[i].y) + points[i].x)) {
result = !result;
}
}
return result;
}
}*/
Line2
[] lines = getUntransformedLineSegments
();
boolean negativeSide =
false;
/*float px = x/getOwner().transform.w;
float py = y/getOwner().transform.h;*/
float px = x
;
float py = y
;
/*Gdx.app.log("BLA", "-------------------------------------");
Gdx.app.log("BLA", "test: " + px + ", " + py);*/
for (int i =
0; i
< lines.
length; i++
)
{
//position = sign( (Bx-Ax)*(Y-Ay) - (By-Ay)*(X-Ax) )
Line2 l = lines
[i
];
//Gdx.app.log("BLA", "line[" + i + "]: " + l.a.x + ", " + l.a.y + " - " + l.b.x + ", " + l.b.y);
float side =
(l.
b.
x-l.
a.
x)*(py-l.
a.
y) -
(l.
b.
y-l.
a.
y)*(px-l.
a.
x);
if (i ==
0)
{
if (side
< 0)
negativeSide =
true;
else
negativeSide =
false;
}
else
{
if ((side
< 0) && (!negativeSide
))
return false;
if ((side
> 0) && (negativeSide
))
return false;
}
}
return true;
}
@
Override
public Vector2
[] getUntransformedPoints
()
{
if (mUntransformedPoints ==
null)
{
mUntransformedPoints =
new Vector2
[mPolyPoints.
length];
for (int i =
0; i
< mUntransformedPoints.
length; i++
)
mUntransformedPoints
[i
] =
new Vector2
();
}
for (int i =
0; i
< mUntransformedPoints.
length; i++
)
mUntransformedPoints
[i
].
setFrom(mPolyPoints
[i
]);
return mUntransformedPoints
;
}
@
Override
public Vector2
[] getPoints
()
{
SpriteTransform t = getOwner
().
transform;
if (mPoints ==
null)
{
mPoints =
new Vector2
[mPolyPoints.
length];
for (int i =
0; i
< mPoints.
length; i++
)
mPoints
[i
] =
new Vector2
();
}
for (int i =
0; i
< mPoints.
length; i++
)
{
//mPoints[i] = t.spriteToWorld(mPoints[i].x * t.w, mPoints[i].y * t.w);
t.
spriteToWorld(mPolyPoints
[i
].
x * t.
w, mPolyPoints
[i
].
y * t.
w, mPoints
[i
]);
}
return mPoints
;
}
@
Override
public Line2
[] getUntransformedLineSegments
()
{
if (mUntransformedLines ==
null)
{
mUntransformedLines =
new Line2
[mPolyPoints.
length];
for (int i =
0; i
< mUntransformedLines.
length; i++
)
mUntransformedLines
[i
] =
new Line2
();
}
SpriteTransform t = getOwner
().
transform;
for (int i =
0; i
< mPolyPoints.
length; i++
)
{
int j =
((i+
1) % mPolyPoints.
length);
//mUntransformedLines[i] = new Line2(mPolyPoints[i].x * t.w, mPolyPoints[i].y * t.h, mPolyPoints[j].x * t.w, mPolyPoints[j].y * t.h);
mUntransformedLines
[i
].
setPointA(mPolyPoints
[i
].
x * t.
w, mPolyPoints
[i
].
y * t.
h);
mUntransformedLines
[i
].
setPointB(mPolyPoints
[j
].
x * t.
w, mPolyPoints
[j
].
y * t.
h);
}
return mUntransformedLines
;
}
@
Override
public Line2
[] getLineSegments
()
{
if (mLines ==
null)
{
mLines =
new Line2
[mPolyPoints.
length];
for (int i =
0; i
< mLines.
length; i++
)
mLines
[i
] =
new Line2
();
}
SpriteTransform t = getOwner
().
transform;
for (int i =
0; i
< mPolyPoints.
length; i++
)
{
int j =
((i+
1) % mPolyPoints.
length);
//Vector2 a = t.spriteToWorld(mPolyPoints[i].x * t.w, mPolyPoints[i].y * t.h);
//Vector2 b = t.spriteToWorld(mPolyPoints[j].x * t.w, mPolyPoints[j].y * t.h);
t.
spriteToWorld(mPolyPoints
[i
].
x * t.
w, mPolyPoints
[i
].
y * t.
h, mTempA
);
t.
spriteToWorld(mPolyPoints
[j
].
x * t.
w, mPolyPoints
[j
].
y * t.
h, mTempB
);
mLines
[i
].
set(mTempA, mTempB
);
//mLines[i] = new Line2(a, b);
}
return mLines
;
}
/*
@Override
public Line2[] getSweepLineSegments(Vector2 move)
{
if (mSweepLines == null)
mSweepLines = new Line2[mPoints.length * 2];
SpriteTransform t = getOwner().transform;
for (int i = 0; i < mPoints.length; i++)
{
int j = ((i+1) % mPoints.length);
Vector2 a = t.spriteToWorld(mPoints[i].x * t.w, mPoints[i].y * t.h);
Vector2 b = t.spriteToWorld(mPoints[j].x * t.w, mPoints[j].y * t.h);
mSweepLines[i] = new Line2(a, b);
}
for (int i = 0; i < mPoints.length; i++)
{
int j = ((i+1) % mPoints.length);
Vector2 a = t.spriteToWorld(mPoints[i].x * t.w + move.x, mPoints[i].y * t.h + move.y);
Vector2 b = t.spriteToWorld(mPoints[j].x * t.w + move.x, mPoints[j].y * t.h + move.y);
mSweepLines[i+mPoints.length] = new Line2(a, b);
}
return mSweepLines;
}*/
@
Override
public Vector2
[] getProjectionAxes
()
{
if (mProjectionAxes ==
null)
{
mProjectionAxes =
new Vector2
[mPolyPoints.
length];
for (int i =
0; i
< mProjectionAxes.
length; i++
)
mProjectionAxes
[i
] =
new Vector2
();
}
SpriteTransform t = getOwner
().
transform;
for (int i =
0; i
< mPolyPoints.
length; i++
)
{
int j =
((i+
1) % mPolyPoints.
length);
//Vector2 a = t.spriteToWorld(mPolyPoints[i].x * t.w, mPolyPoints[i].y * t.h);
//Vector2 b = t.spriteToWorld(mPolyPoints[j].x * t.w, mPolyPoints[j].y * t.h);
t.
spriteToWorld(mPolyPoints
[i
].
x * t.
w, mPolyPoints
[i
].
y * t.
h, mTempA
);
t.
spriteToWorld(mPolyPoints
[j
].
x * t.
w, mPolyPoints
[j
].
y * t.
h, mTempB
);
//mProjectionAxes[i] = new Vector2(b.x-a.x, b.y-a.y);
mProjectionAxes
[i
].
set(mTempB.
x - mTempA.
x, mTempB.
y - mTempA.
y);
}
for (int i =
0; i
< mProjectionAxes.
length; i++
)
{
mProjectionAxes
[i
].
set(mProjectionAxes
[i
].
y, -mProjectionAxes
[i
].
x);
}
return mProjectionAxes
;
}
// Getters/Setters==================================================================================
}