Я пытаюсь нарисовать меньший заполненный многоугольник (который в моем случае всегда является выпуклым, а не самопересекающимся четырехугольником) поверх другого заполненного многоугольника, чтобы получить впечатление границы вокруг этого заполненного многоугольника.Для этого я узнал, как рассчитать центроид четырехугольника - это будет точка, вокруг которой будет уменьшен заполненный меньший многоугольник.Я скопировал алгоритм отсюда: https://math.stackexchange.com/a/2878092
И вот полный код класса:
public class BodyPartActor extends Actor {
private static TextureRegion textureRegion = Globals.getTextureRegion();
private static Color borderColor = Assets.getSkin().getColor("pink");
private static Color bodyPartColor = Assets.getSkin().getColor("green");
private static short[] triangles = new short[] {
0, 1, 2, // Two triangles using vertex indices.
0, 2, 3 // Take care of the counter-clockwise direction.
};
private PolygonRegion polygonRegion;
private BodyPart bodyPart;
private Vector2 centroid;
public BodyPartActor(BodyPart bodyPart) {
this.bodyPart = bodyPart;
polygonRegion = new PolygonRegion(textureRegion, this.bodyPart.getVertices(), triangles);
centroid = getCentroidOfQuadrangle();
}
private Vector2 getCentroidOfQuadrangle() {
float[] v = bodyPart.getVertices();
Vector2 centroidA = getCentroidOfTriangle(new float[]{v[0], v[1], v[2], v[3], v[4], v[5]});
Vector2 centroidB = getCentroidOfTriangle(new float[]{v[2], v[3], v[4], v[5], v[6], v[7]});
Vector2 centroidC = getCentroidOfTriangle(new float[]{v[4], v[5], v[6], v[7], v[0], v[1]});
Vector2 centroidD = getCentroidOfTriangle(new float[]{v[6], v[7], v[0], v[1], v[2], v[3]});
return getPointOfLinesIntersection(centroidA, centroidC, centroidB, centroidD);
}
private Vector2 getCentroidOfTriangle(float[] vertices) {
return new Vector2 (
(vertices[0] + vertices[2] + vertices[4]) / 3,
(vertices[1] + vertices[3] + vertices[5]) / 3
);
}
private Vector2 getPointOfLinesIntersection(Vector2 startLineA, Vector2 endLineA, Vector2 startLineB,
Vector2 endLineB) {
float detOfLineA = det2x2(startLineA.x, startLineA.y, endLineA.x, endLineA.y);
float detOfLineB = det2x2(startLineB.x, startLineB.y, endLineB.x, endLineB.y);
float xDeltaOfLineA = startLineA.x - endLineA.x;
float xDeltaOfLineB = startLineB.x - endLineB.x;
float yDeltaOfLineA = startLineA.y - endLineA.y;
float yDeltaOfLineB = startLineB.y - endLineB.y;
float xNom = det2x2(detOfLineA, xDeltaOfLineA, detOfLineB, xDeltaOfLineB);
float yNom = det2x2(detOfLineA, yDeltaOfLineA, detOfLineB, yDeltaOfLineB);
float deNom = det2x2(xDeltaOfLineA, yDeltaOfLineA, xDeltaOfLineB, yDeltaOfLineB);
return new Vector2(xNom / deNom, yNom / deNom);
}
/**
* Calculate determinant of a 2x2 matrix:
* |a b|
* |c d|
*/
private float det2x2(float a, float b, float c, float d) {
return (a * d) - (b * c);
}
@Override
public void draw(Batch batch, float parentAlpha) {
float x = bodyPart.getBody().getPosition().x;
float y = bodyPart.getBody().getPosition().y;
float width = polygonRegion.getRegion().getRegionWidth();
float height = polygonRegion.getRegion().getRegionHeight();
float originX = centroid.x;
float originY = centroid.y;
float rotation = calculateRotation(originX, originY);
PolygonSpriteBatch polygonSpriteBatch = (PolygonSpriteBatch) batch;
polygonSpriteBatch.setColor(borderColor.r, borderColor.g, borderColor.b, borderColor.a * parentAlpha);
polygonSpriteBatch.draw(polygonRegion, x, y, originX, originY, width, height, 1f, 1f, rotation);
polygonSpriteBatch.setColor(bodyPartColor.r, bodyPartColor.g, bodyPartColor.b, bodyPartColor.a * parentAlpha);
polygonSpriteBatch.draw(polygonRegion, x, y, originX, originY, width, height, 0.9f, 0.9f, rotation);
}
private float calculateRotation(float originX, float originY) {
// How to calculate when originX and originY are the center of quadrangle???
return bodyPart.getBody().getAngle() * MathUtils.radiansToDegrees; // Works only if originX and originY are 0.
}
}
Кажется, правильно вычислить центроид, я проверил егоздесь : http://eguruchela.com/math/Calculator/polygon-centroid-point но результирующие границы не выглядят хорошо .Я даже думал, что есть некоторые арифметические проблемы с плавающей точкой в libGDX при вычислении позиций вершин, но я не смог их найти, поэтому я не знаю, в чем проблема.Также есть проблема с вращением, потому что теперь я рисую с точкой начала координат в центре четырехугольника, поэтому он не рендерится должным образом (перед попыткой нарисовать границу, originX и originY были 0, что сделало правильный рендеринг повернутых тел правильным, теперь он не выравнивается так, как должен).
Знаете ли вы, как правильно отрисовать эту границу и с правильным вращением многоугольника?Или, может быть, весь подход к этой проблеме неверен, и есть лучший способ сделать это?