Flip Vertices Array
I have an array of position vertices that make up a 2D polygon.
Vector2[] _chassisConcaveVertices =
{
new Vector2(5.122f, 0.572f),
new Vector2(3.518f, 0.572f),
new Vector2(3.458f, 0.169f),
new Vector2(2.553f, 0.169f),
new Vector2(2.013f, 0.414f),
new Vector2(0.992f, 0.769f),
new Vector2(0.992f, 1.363f),
new Vector2(5.122f, 1.363f),
};
What algorithm can I use to modify the positions so the resultant po开发者_运维百科lygon is flipped? I need to flip the polygon both horizontally and vertically.
Assuming the Vector2
class has two properties/members names x
and y
:
public Vector2[] FlipHorizontally(Vector2[] original)
{
Vector2[] flipped = new Vector2[original.Length];
for (int i = 0; i < original.Length; i++)
{
flipped[i] = new Vector2(-1 * original[i].x, original[i].y);
}
return flipped;
}
public Vector2[] FlipVertically(Vector2[] original)
{
Vector2[] flipped = new Vector2[original.Length];
for (int i = 0; i < original.Length; i++)
{
flipped[i] = new Vector2(original[i].x, -1 * original[i].y);
}
return flipped;
}
This will flip the vertices in relation to the two axis. You do not specify what positioning you intend for the new polygon in relation to the original. If you need to "move" it then you simply need to add one value to all x
and another value to all y
.
If you're flipping around the point (0.0f,0.0f) you simply need to negate the values. So your shape would be:
Vector2[] _chassisConcaveVertices =
{
new Vector2(-5.122f, -0.572f),
new Vector2(-3.518f, -0.572f),
new Vector2(-3.458f, -0.169f),
new Vector2(-2.553f, -0.169f),
new Vector2(-2.013f, -0.414f),
new Vector2(-0.992f, -0.769f),
new Vector2(-0.992f, -1.363f),
new Vector2(-5.122f, -1.363f),
};
If you are flipping around a point (x,y) then each point will be (x - (p.x - x)) or (2*x-p.x) for the x value and (y - (p.y - y)) or (2*y-p.y) for the y value.
This explains:
. is the point you want to flip
* is the point you want to flip around
O is the point you want to end up with
x axis
^
|
. -
| | <-
| | <- Let this be distance a
* -
| | <-
| | <- This should be equal to a
O -
|
|
-------> y axis
Let's say the x values of . * and O are t, m and b respectively (top, middle and bottom). As you can see, the distance a = t-m and the b = m-a. Therefore b = m-(t-m) = m-t+m = m*2-t
You can then use this principle to write an algorithm to flip all the points around a different point and this will give you your flipped polygon!
First you have to take the center of the circumference that inscribes the polygon, then take the line that goes vertical and horitzontal across the center, for each point, first, take the symetric at the other side of the vertical line, then repeat the action for the symetric point at the other side of the horitzontal, you will have all point flipped.
See you!
Not sure if there is a "correct" way, but something like the below should work to flip a polygon in place, both horizontally and vertically.
- Find the center point by adding averaging x points and y points.
- For each point in the polygon, calculate the vertical and horizontal distance distance from the center point and add double each value to the point.
Untested example:
Vector2[] _chassisConcaveVertices =
{
new Vector2(5.122f, 0.572f),
new Vector2(3.518f, 0.572f),
new Vector2(3.458f, 0.169f),
new Vector2(2.553f, 0.169f),
new Vector2(2.013f, 0.414f),
new Vector2(0.992f, 0.769f),
new Vector2(0.992f, 1.363f),
new Vector2(5.122f, 1.363f),
};
// find center
float sumX = 0;
float sumY = 0;
foreach (var vector in _chassisConcaveVertices)
{
sumX += vector.X;
sumY += vector.Y;
}
Vector2 center = new Vector2(
sumX / _chassisConcaveVertices.Length,
sumY / _chassisConcaveVertices.Length);
// create a new version of the polygon flipped
Vector2[] flipped = _chassisConcaveVertices
.Select(v => new Vector2(
v.X + (center.X - v.X) * 2,
v.Y + (center.Y - v.Y) * 2))
.ToArray();
Tested example for horizontal flip. Supports multiple paths in a collider: The paths are mirrored relative to centre position of the collider.
void FlipHorizontally(PolygonCollider2D tpolygon)
{
// find centre X
float sumX = 0;
foreach (Vector2 v2 in tpolygon.points)
sumX += v2.x;
float centreX = sumX / tpolygon.points.Length;
// Flip each path in the polygon
for (int k = 0; k < tpolygon.pathCount; k++)
{
List<Vector2> mirrored = new List<Vector2>();
List<Vector2> pathPoints = new List<Vector2>(tpolygon.GetPath(k));
for (int i = 0; i < pathPoints.Count; i++)
{
Vector2 v2 = pathPoints[i];
float xx = v2.x - 2 * (v2.x - centreX);
mirrored.Add(new Vector2(xx, v2.y));
}
tpolygon.SetPath(k, mirrored);
}
Debug.Log("flipped paths: " + tpolygon.pathCount);
}
精彩评论