Я пытаюсь найти решение для лучшей производительности.Как найти ближайшую точку на многосегментной линии
Мне нужно найти точку шкафа на многосегментной линии (точки списка) до заданной точки.
У моей линии есть тысячи точек, и мне нужно проверить расстояние до этой линии несколько раз в секунду. Поэтому решение должно быть очень быстрым.
Прямо сейчас у меня есть что-то вроде ниже. Он работает, но он будет медленным, если у линии есть 10000 + очков.
Возможно, у кого-то есть идея, как сделать это быстрее?
public static float GetSqrDistXZ(Vector3 a, Vector3 b)
{
Vector3 vector = new Vector3(a.x - b.x, 0, a.z - b.z);
return vector.sqrMagnitude;
}
public static Vector3 NearestPointOnFiniteLine(Vector3 start, Vector3 end, Vector3 pnt)
{
Vector3 line = (end - start);
float len = Mathf.Sqrt(line.sqrMagnitude);
line.Normalize();
Vector3 v = pnt - start;
float d = (v.x * line.x) + (v.z * line.z);
d = Mathf.Clamp(d, 0f, len);
return start + line * d;
}
int pointsCount = line.points3.Count - 1; // line - List<Vector3> points.
float[] distances = new float[pointsCount];
for (int i = 0; i < pointsCount+1; i++) {
if (i >= 1) {
distances [i - 1] = GetSqrDistXZ (point, NearestPointOnFiniteLine (line.points3 [i - 1], line.points3 [i], point));
}
}
int minListIndexLeft = System.Array.IndexOf (distances, Mathf.Min (distances));
float minimalDistance = distances[minListIndexLeft];
Vector3 closestPoint = NearestPointOnFiniteLine (line.points3[minListIndexLeft], line.points3[minListIndexLeft+1], point);
Я не упоминал, что моя многосегментная линия обновляется (пользователь добавляет новые очки) все время. Я думаю, что обновление этой сетки при каждой обновленной строке займет больше ms :( – seek
Если пользователь добавляет только точки в конец вашей линии, обновление очень дешево, потому что существующие пересечения не меняются, вам просто нужно добавить новые добавленные пересечения каждый раз, когда пользователь добавляет точку. Но даже если пользователь может изменить существующие точки, вы можете удалить пересечения для измененных сегментов и добавить новые. Оба тоже довольно дешевы, если ваши структуры данных предназначены для этого. –
Вы правы. Хорошая идея. Это не так просто реализовать для меня, но я постараюсь сделать это. – seek