2023-03-14 08:02:43 +03:00
|
|
|
/*
|
|
|
|
recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
|
|
|
|
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
|
|
warranty. In no event will the authors be held liable for any damages
|
|
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
|
|
including commercial applications, and to alter it and redistribute it
|
|
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
|
|
claim that you wrote the original software. If you use this software
|
|
|
|
in a product, an acknowledgment in the product documentation would be
|
|
|
|
appreciated but is not required.
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
misrepresented as being the original software.
|
|
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
|
|
*/
|
|
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
2023-03-16 19:09:10 +03:00
|
|
|
namespace DotRecast.Core
|
|
|
|
{
|
2023-03-16 19:48:49 +03:00
|
|
|
public static class ConvexUtils
|
|
|
|
{
|
|
|
|
// Calculates convex hull on xz-plane of points on 'pts',
|
|
|
|
// stores the indices of the resulting hull in 'out' and
|
|
|
|
// returns number of points on hull.
|
2023-05-05 02:44:48 +03:00
|
|
|
public static List<int> Convexhull(List<float> pts)
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
|
|
|
int npts = pts.Count / 3;
|
|
|
|
List<int> @out = new List<int>();
|
|
|
|
// Find lower-leftmost point.
|
|
|
|
int hull = 0;
|
|
|
|
for (int i = 1; i < npts; ++i)
|
|
|
|
{
|
2023-06-03 15:47:26 +03:00
|
|
|
RcVec3f a = RcVec3f.Of(pts[i * 3], pts[i * 3 + 1], pts[i * 3 + 2]);
|
|
|
|
RcVec3f b = RcVec3f.Of(pts[hull * 3], pts[hull * 3 + 1], pts[hull * 3 + 2]);
|
2023-05-05 02:44:48 +03:00
|
|
|
if (Cmppt(a, b))
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
|
|
|
hull = i;
|
|
|
|
}
|
|
|
|
}
|
2023-03-16 19:09:10 +03:00
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
// Gift wrap hull.
|
|
|
|
int endpt = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
@out.Add(hull);
|
|
|
|
endpt = 0;
|
|
|
|
for (int j = 1; j < npts; ++j)
|
|
|
|
{
|
2023-06-03 15:47:26 +03:00
|
|
|
RcVec3f a = RcVec3f.Of(pts[hull * 3], pts[hull * 3 + 1], pts[hull * 3 + 2]);
|
|
|
|
RcVec3f b = RcVec3f.Of(pts[endpt * 3], pts[endpt * 3 + 1], pts[endpt * 3 + 2]);
|
|
|
|
RcVec3f c = RcVec3f.Of(pts[j * 3], pts[j * 3 + 1], pts[j * 3 + 2]);
|
2023-05-05 02:44:48 +03:00
|
|
|
if (hull == endpt || Left(a, b, c))
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
|
|
|
endpt = j;
|
|
|
|
}
|
|
|
|
}
|
2023-03-14 08:02:43 +03:00
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
hull = endpt;
|
|
|
|
} while (endpt != @out[0]);
|
2023-03-14 08:02:43 +03:00
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
return @out;
|
2023-03-14 08:02:43 +03:00
|
|
|
}
|
2023-03-16 19:48:49 +03:00
|
|
|
|
|
|
|
// Returns true if 'a' is more lower-left than 'b'.
|
2023-06-03 15:47:26 +03:00
|
|
|
private static bool Cmppt(RcVec3f a, RcVec3f b)
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
2023-04-29 06:41:07 +03:00
|
|
|
if (a.x < b.x)
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
|
|
|
return true;
|
2023-03-14 08:02:43 +03:00
|
|
|
}
|
|
|
|
|
2023-04-29 06:41:07 +03:00
|
|
|
if (a.x > b.x)
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-04-29 06:41:07 +03:00
|
|
|
if (a.z < b.z)
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-04-29 06:41:07 +03:00
|
|
|
if (a.z > b.z)
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2023-03-14 08:02:43 +03:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
// Returns true if 'c' is left of line 'a'-'b'.
|
2023-06-03 15:47:26 +03:00
|
|
|
private static bool Left(RcVec3f a, RcVec3f b, RcVec3f c)
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
2023-04-29 06:41:07 +03:00
|
|
|
float u1 = b.x - a.x;
|
|
|
|
float v1 = b.z - a.z;
|
|
|
|
float u2 = c.x - a.x;
|
|
|
|
float v2 = c.z - a.z;
|
2023-03-16 19:48:49 +03:00
|
|
|
return u1 * v2 - v1 * u2 < 0;
|
|
|
|
}
|
2023-03-14 08:02:43 +03:00
|
|
|
}
|
2023-04-29 06:41:07 +03:00
|
|
|
}
|