Skip to content

Instantly share code, notes, and snippets.

@MalcolmMacDonald
Last active January 29, 2024 20:47
Show Gist options
  • Select an option

  • Save MalcolmMacDonald/130be34ba189bc8cce29dcef00ebd6df to your computer and use it in GitHub Desktop.

Select an option

Save MalcolmMacDonald/130be34ba189bc8cce29dcef00ebd6df to your computer and use it in GitHub Desktop.
using UnityEngine;
//https://www.cs.jhu.edu/~misha/MyPapers/EUROG20.pdf Appendix A
namespace PolygonCenterFinder
{
public static class PolygonCenter
{
public static Vector2 GetPolygonCenter(Vector2[] verts)
{
var matA = CreateAMatrix(verts);
var vecB = CreateBVector(verts);
alglib.rmatrixsolve(matA, vecB.Length - 1, vecB, out _, out _, out var x);
return FindCenter(verts, x);
}
/// <summary>
/// Creates an (N+1)xN matrix with 1s in the final column
/// </summary>
/// <param name="verts"></param>
/// <returns></returns>
public static double[,] CreateAMatrix(Vector2[] verts)
{
var outMatrix = new double[verts.Length + 1, verts.Length];
for (var i = 0; i < verts.Length; i++)
{
for (var j = 0; j < verts.Length; j++)
{
for (var k = 0; k < verts.Length; k++)
{
var leftSide = Vector3.Cross(verts[j], verts[(k + 1) % verts.Length] - verts[k]);
var rightSide = Vector3.Cross(verts[i], verts[(k + 1) % verts.Length] - verts[k]);
outMatrix[i, j] += 2 * Vector3.Dot(leftSide, rightSide);
}
}
}
for (var i = 0; i < verts.Length; i++)
{
outMatrix[verts.Length, i] = 1f;
}
return outMatrix;
}
/// <summary>
/// Creates an (N+1)x1 Vector
/// </summary>
/// <param name="vertices"></param>
/// <returns></returns>
public static double[] CreateBVector(Vector2[] vertices)
{
var outVector = new double[vertices.Length + 1];
for (var i = 0; i < vertices.Length; i++)
{
for (var k = 0; k < vertices.Length; k++)
{
var leftSide = Vector3.Cross(vertices[i], vertices[(k + 1) % vertices.Length] - vertices[k]);
var rightSide = Vector3.Cross(vertices[(k + 1) % vertices.Length] - vertices[k], vertices[k]);
outVector[i] += 2 * Vector3.Dot(leftSide, rightSide);
}
}
outVector[vertices.Length] = 1d;
return outVector;
}
public static Vector2 FindCenter(Vector2[] positions, double[] weights)
{
var weightedAverage = Vector2.zero;
for (var i = 0; i < positions.Length; i++)
{
weightedAverage += positions[i] * (float)-weights[i];
}
return weightedAverage;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment