room101/POLYGON.CPP

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];
}
}