425 lines
12 KiB
C++
425 lines
12 KiB
C++
|
|
#include "polygon.hpp"
|
|
#include "plane.hpp"
|
|
|
|
#define POLYGON_VALIDATE() assert(n >= POLYGON_MIN && n < POLYGON_MAX);
|
|
/*******************************************************************************
|
|
** PolygonMerge
|
|
*******************************************************************************/
|
|
int
|
|
PolygonMerge(Polygon dst, Vector* p1, int n1, Vector* p2, int n2)
|
|
{
|
|
int k = 0;
|
|
|
|
for (int i = 0; i < n1; i++)
|
|
{
|
|
v3dcpy(dst[k++], p1[i]);
|
|
|
|
for (int j = 0; j < n2; j++)
|
|
{
|
|
if (VectorsAreEqual(p1[i], p2[j]))
|
|
{
|
|
i = j;
|
|
|
|
int n3 = n1; n1 = n2; n2 = n3;
|
|
Vector* p3 = p1; p1 = p2; p2 = p3;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return k;
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonCopy
|
|
*******************************************************************************/
|
|
void
|
|
PolygonCopy(Polygon dst, Polygon src, int n)
|
|
{
|
|
memcpy(dst, src, sizeof(Vector) * n);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonRotate
|
|
*******************************************************************************/
|
|
void
|
|
PolygonRotate(Polygon dst, Polygon src, int n, Matrix matrix)
|
|
{
|
|
while (n--) VectorRotate(dst[n], src[n], matrix);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonTranslate
|
|
*******************************************************************************/
|
|
void
|
|
PolygonTranslate(Polygon dst, Polygon src, int n, Matrix matrix)
|
|
{
|
|
while (n--) VectorTranslate(dst[n], src[n], matrix);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonTransform
|
|
*******************************************************************************/
|
|
void
|
|
PolygonTransform(Polygon dst, Polygon src, int n, Matrix matrix)
|
|
{
|
|
while (n--) VectorTransform(dst[n], src[n], matrix);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonScale
|
|
*******************************************************************************/
|
|
void
|
|
PolygonScale(Polygon dst, Polygon src, int n, float scale)
|
|
{
|
|
while (n--) VectorScale(dst[n], src[n], scale);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonInterpolate
|
|
*******************************************************************************/
|
|
void
|
|
PolygonInterpolate(Polygon dst, Polygon A, Polygon B, int n, float scale)
|
|
{
|
|
while (n--) VectorInterpolate(dst[n], A[n], B[n], scale);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonAddition
|
|
*******************************************************************************/
|
|
void
|
|
PolygonAddition(Polygon dst, Polygon src, int n, Vector vector)
|
|
{
|
|
while (n--)
|
|
{
|
|
dst[n][0] = src[n][0] + vector[0];
|
|
dst[n][1] = src[n][1] + vector[1];
|
|
dst[n][2] = src[n][2] + vector[2];
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonSubtract
|
|
*******************************************************************************/
|
|
void
|
|
PolygonSubtract(Polygon dst, Polygon src, int n, Vector vector)
|
|
{
|
|
while (n--)
|
|
{
|
|
dst[n][0] = src[n][0] - vector[0];
|
|
dst[n][1] = src[n][1] - vector[1];
|
|
dst[n][2] = src[n][2] - vector[2];
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonMultiply
|
|
*******************************************************************************/
|
|
void
|
|
PolygonMultiply(Polygon dst, Polygon src, int n, Vector vector)
|
|
{
|
|
while (n--)
|
|
{
|
|
dst[n][0] = src[n][0] * vector[0];
|
|
dst[n][1] = src[n][1] * vector[1];
|
|
dst[n][2] = src[n][2] * vector[2];
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonDivide
|
|
*******************************************************************************/
|
|
void
|
|
PolygonDivide(Polygon dst, Polygon src, int n, Vector vector)
|
|
{
|
|
while (n--)
|
|
{
|
|
dst[n][0] = src[n][0] / vector[0];
|
|
dst[n][1] = src[n][1] / vector[1];
|
|
dst[n][2] = src[n][2] / vector[2];
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonSize
|
|
*******************************************************************************/
|
|
void
|
|
PolygonSize(Vector size, Polygon src, int n)
|
|
{
|
|
Vector lo, hi;
|
|
PolygonExtent(lo, hi, src, n);
|
|
VectorSubtract(size, hi, lo);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonMagnitude
|
|
*******************************************************************************/
|
|
float
|
|
PolygonMagnitude(Polygon src, int n)
|
|
{
|
|
float dst = 0.0;
|
|
|
|
while (n--)
|
|
{
|
|
dst = Max(dst, (float)fabs(src[n][0]));
|
|
dst = Max(dst, (float)fabs(src[n][1]));
|
|
dst = Max(dst, (float)fabs(src[n][2]));
|
|
}
|
|
return dst;
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonNormalize
|
|
*******************************************************************************/
|
|
void
|
|
PolygonNormalize(Polygon dst, Polygon src, int n, float size)
|
|
{
|
|
PolygonScale(dst, src, n, size / PolygonMagnitude(src, n));
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonCentrePoint
|
|
*******************************************************************************/
|
|
void
|
|
PolygonCentrePoint(Vector dst, Polygon src, int n)
|
|
{
|
|
Vector lo, hi;
|
|
|
|
PolygonExtent(lo, hi, src, n);
|
|
VectorSubtract(hi, hi, lo);
|
|
VectorScale(hi, hi, 0.5f);
|
|
VectorAddition(dst, lo, hi);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonSum
|
|
*******************************************************************************/
|
|
void
|
|
PolygonSum(Vector dst, Polygon src, int n)
|
|
{
|
|
VectorCreate(dst, 0.0f, 0.0f, 0.0f);
|
|
|
|
while (n--) VectorAddition(dst, dst, src[n]);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonMean
|
|
*******************************************************************************/
|
|
void
|
|
PolygonMean(Vector dst, Polygon src, int n)
|
|
{
|
|
assert(n);
|
|
PolygonSum(dst, src, n);
|
|
VectorScale(dst, dst, 1.0f / n);
|
|
}
|
|
/*******************************************************************************
|
|
** VectorMidPoint
|
|
*******************************************************************************/
|
|
void
|
|
VectorMidPoint(Vector A, Vector B, Vector C)
|
|
{
|
|
VectorInterpolate(A, B, C, 0.5f);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonCentre
|
|
*******************************************************************************/
|
|
void
|
|
PolygonCentre(Polygon dst, Polygon src, int n)
|
|
{
|
|
Vector lo, hi, shift;
|
|
|
|
PolygonExtent(lo, hi, src, n);
|
|
VectorSubtract(shift, hi, lo);
|
|
VectorScale(shift, shift, 0.5f);
|
|
VectorAddition(shift, shift, lo);
|
|
PolygonSubtract(dst, src, n, shift);
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonExtent
|
|
*******************************************************************************/
|
|
void
|
|
PolygonExtent(Vector lo, Vector hi, Polygon src, int n)
|
|
{
|
|
assert(n);
|
|
|
|
v3dcpy(lo, src[0]);
|
|
v3dcpy(hi, src[0]);
|
|
|
|
while (n--)
|
|
{
|
|
VectorMinimize(lo, lo, src[n]);
|
|
VectorMaximize(hi, hi, src[n]);
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonMergePoints
|
|
*******************************************************************************/
|
|
int
|
|
PolygonMergePoints(Polygon dst, Polygon src, int n)
|
|
{
|
|
int i, j, k = 0;
|
|
|
|
assert(n >= POLYGON_MIN && n < POLYGON_MAX);
|
|
|
|
for (j = n - 1, i = 0; i < n; j = i++)
|
|
{
|
|
if (!VectorsAreEqual(src[i], src[j]))
|
|
{
|
|
v3dcpy(dst[k++], src[i]);
|
|
}
|
|
}
|
|
return k;
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonEdges
|
|
*******************************************************************************/
|
|
void
|
|
PolygonEdges(Polygon dst, Polygon src, int n)
|
|
{
|
|
int i, j;
|
|
|
|
for (j = n - 1, i = 0; i < n; j = i++)
|
|
{
|
|
VectorSubtract(dst[j], src[i], src[j]);
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonNormals
|
|
*******************************************************************************/
|
|
void
|
|
PolygonNormals(Polygon dst, Polygon src, int n)
|
|
{
|
|
int i, j;
|
|
|
|
Polygon edges;
|
|
|
|
PolygonEdges(edges, src, n);
|
|
|
|
for (j = n - 1, i = 0; i < n; j = i++)
|
|
{
|
|
VectorCrossProduct(dst[i], edges[j], edges[i]);
|
|
VectorNormalize(dst[i], dst[i]);
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonIsConvex
|
|
*******************************************************************************/
|
|
int
|
|
PolygonIsConvex(Polygon src, int n)
|
|
{
|
|
Polygon normals;
|
|
|
|
PolygonNormals(normals, src, n);
|
|
|
|
while (n--) if (!VectorsAreEqual(src[0], src[n])) return 0;
|
|
|
|
return 1;
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonCollinear
|
|
*******************************************************************************/
|
|
int
|
|
PolygonCollinear(Polygon dst, Polygon src, int n)
|
|
{
|
|
int i, j, k = 0;
|
|
Vector A, B;
|
|
|
|
assert(n >= POLYGON_MIN && n < POLYGON_MAX);
|
|
|
|
VectorSubtract(A, src[n - 1], src[n - 2]);
|
|
|
|
for (j = n - 1, i = 0; i < n; j = i++)
|
|
{
|
|
VectorSubtract(B, src[i], src[j]);
|
|
|
|
if (!VectorsAreCollinear(A, B))
|
|
{
|
|
v3dcpy(dst[k++], src[j]);
|
|
}
|
|
v3dcpy(A, B);
|
|
}
|
|
return k;
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonsAreJoined
|
|
*******************************************************************************/
|
|
int
|
|
PolygonsAreJoined(Polygon p1, int n1, Polygon p2, int n2)
|
|
{
|
|
int a1, b1, a2, b2;
|
|
|
|
for (a1 = n1 - 1, b1 = 0; b1 < n1; a1 = b1++)
|
|
{
|
|
for (a2 = n2 - 1, b2 = 0; b2 < n2; a2 = b2++)
|
|
{
|
|
if
|
|
(
|
|
(VectorsAreEqual(p1[a1], p2[a2]) && VectorsAreEqual(p1[b1], p2[b2]))
|
|
||
|
|
(VectorsAreEqual(p1[a1], p2[b2]) && VectorsAreEqual(p1[b1], p2[a2]))
|
|
) return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonClipToPlane
|
|
*******************************************************************************/
|
|
int
|
|
PolygonClipToPlane(Polygon dst, Polygon src, int n, Plane plane)
|
|
{
|
|
int i, j, k = 0;
|
|
float dist1, dist2;
|
|
|
|
if (n >= POLYGON_MIN && n < POLYGON_MAX)
|
|
{
|
|
dist1 = PlaneDistanceTo(plane, src[n - 1]);
|
|
|
|
for (j = n - 1, i = 0; i < n; j = i++)
|
|
{
|
|
if (dist1 >= 0.0f) v3dcpy(dst[k++], src[j]);
|
|
|
|
dist2 = PlaneDistanceTo(plane, src[i]);
|
|
|
|
if (dist1 < 0.0f ^ dist2 < 0.0f)
|
|
{
|
|
VectorInterpolate(dst[k++], src[j], src[i], dist1 / (dist1 - dist2));
|
|
}
|
|
|
|
dist1 = dist2;
|
|
}
|
|
}
|
|
return k;
|
|
}
|
|
void
|
|
PolygonDistPlane(float out[], Vector in[], int n, Plane plane)
|
|
{
|
|
assert(n >= POLYGON_MIN && n < POLYGON_MAX);
|
|
while (n--) out[n] = PlaneDistanceTo(plane, in[n]);
|
|
}
|
|
|
|
void
|
|
PolygonDistLeftViewPlane(float out[], Vector in[], int n)
|
|
{
|
|
assert(n >= POLYGON_MIN && n < POLYGON_MAX);
|
|
while (n--) out[n] = in[n][0] + in[n][2];
|
|
}
|
|
|
|
void
|
|
PolygonDistRightViewPlane(float out[], Vector in[], int n)
|
|
{
|
|
assert(n >= POLYGON_MIN && n < POLYGON_MAX);
|
|
while (n--) out[n] = in[n][2] - in[n][0];
|
|
}
|
|
|
|
void
|
|
PolygonDistTopViewPlane(float out[], Vector in[], int n)
|
|
{
|
|
assert(n >= POLYGON_MIN && n < POLYGON_MAX);
|
|
while (n--) out[n] = in[n][1] + in[n][2];
|
|
}
|
|
|
|
void
|
|
PolygonDistBotViewPlane(float out[], Vector in[], int n)
|
|
{
|
|
assert(n >= POLYGON_MIN && n < POLYGON_MAX);
|
|
while (n--) out[n] = in[n][2] - in[n][1];
|
|
}
|
|
/*******************************************************************************
|
|
** PolygonProject
|
|
*******************************************************************************/
|
|
void
|
|
PolygonProject(Polygon src, int n, Camera* camera)
|
|
{
|
|
while (n--)
|
|
{
|
|
src[n][0] = camera->origin[0] * src[n][0] / src[n][2] + camera->origin[0];
|
|
src[n][1] = - camera->origin[1] * src[n][1] / src[n][2] + camera->origin[1];
|
|
}
|
|
}
|
|
|