Алгоритм поиска точки в нерегулярном многоугольнике
Предположим, у меня есть многоугольник, подобный следующему:
![Irregular Polygon]()
Я ищу алгоритм С#, с которым я могу найти точку (может быть как среднюю, так и случайную точку) внутри любого полигона.
Для нахождения центра масс я использовал следующий алгоритм:
private Point3d GetPolyLineCentroid(DBObject pObject, double pImageWidth, double pImageHeight)
{
Point2d[] pointArray = GetPointArrayOfRoomPolygon(pObject);
double centroidX = 0.0;
double centroidY = 0.0;
double signedArea = 0.0;
double x0 = 0.0; // Current vertex X
double y0 = 0.0; // Current vertex Y
double x1 = 0.0; // Next vertex X
double y1 = 0.0; // Next vertex Y
double a = 0.0; // Partial signed area
int i = 0;
for (i = 0; i < pointArray.Length - 1; ++i)
{
x0 = pointArray[i].X;
y0 = pointArray[i].Y;
x1 = pointArray[i + 1].X;
y1 = pointArray[i + 1].Y;
a = x0 * y1 - x1 * y0;
signedArea += a;
centroidX += (x0 + x1) * a;
centroidY += (y0 + y1) * a;
}
x0 = pointArray[i].X;
y0 = pointArray[i].Y;
x1 = pointArray[0].X;
y1 = pointArray[0].Y;
a = x0 * y1 - x1 * y0;
signedArea += a;
centroidX += (x0 + x1) * a;
centroidY += (y0 + y1) * a;
signedArea *= 0.5;
centroidX /= (6.0 * signedArea);
centroidY /= (6.0 * signedArea);
Point3d centroid = new Point3d(centroidX, centroidY, 0);
return centroid;
}
Это хорошо работает с полигонами:
![L-Polygon]()
Но если мой многоугольник имеет форму C или что-то подобное, этот алгоритм n не работает, потому что центральная масса не находится за пределами многоугольника.
Есть ли у кого-нибудь идея, как всегда получать точки внутри любого полигона?
Ответы
Ответ 1
Вы можете использовать триангуляцию многоугольника, чтобы разделить ваш многоугольник на треугольники.
Один такой алгоритм демонстрируется с помощью С# в этой статье CodeProject.
Как только у вас есть треугольники, найти произвольные точки, лежащие в треугольнике, легко. Любая барицентрическая координата с суммой 1.0, умноженная на вершины треугольника, даст вам точку внутри треугольника.
Центр можно получить с помощью барицентрической координаты [0.333333, 0.333333, 0.333333]:
float centerX = A.x * 0.333333 + B.x * 0.333333 + C.x * 0.3333333;
float centerY = A.y * 0.333333 + B.y * 0.333333 + C.y * 0.3333333;
или более просто:
float centerX = (A.x + B.x + C.x) / 3f;
float centerY = (A.y + B.y + C.y) / 3f;
Ответ 2
Используйте это:
private Point getCentroid(pointArray)
{
double centroidX = 0.0;
double centroidY = 0.0;
for (int i = 0; i < pointArray.Length; i++)
{
centroidX += pointArray[i].X;
centroidY += pointArray[i].Y;`
}
centroidX /= pointArray.Length;
centroidY /= pointArray.Length;
return(new Point(centroidX ,centroidY));
}
этот код - это просто найти Центр масс полигона. Чтобы проверить, находится ли точка внутри или вне полигона, проверьте эту ссылку http://bbs.dartmouth.edu/~fangq/MATH/download/source/Determining%20if%20a%20point%20lies%20on%20the%20interior%20of%20a%20polygon.htm