1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
#include <Vlib.h>
#include <math.h>
void ComputeRotationMatrix(double r, VPoint * e, VMatrix * m);
VPolygon *
ScalePolygon(VPolygon * in, VPoint * offset, VPoint * scale, VPoint *e, double r)
{
int numVtces = in->numVtces, i;
VPoint *vert;
VPolygon *p;
VPoint a, b, tmp, offset1;
VMatrix m;
p = (VPolygon *) Vmalloc(sizeof(VPolygon));
#ifdef DEBUG
fprintf(stderr, "scaling %d-point polygon %g, %g, %g; rotation %g; offset %g, %g, %g\n",
in->numVtces, scale->x, scale->y, scale->z, r,
offset->x, offset->y, offset->z);
#endif
*p = *in;
p->numVtces = numVtces;
vert = p->vertex = (VPoint *) Vmalloc(sizeof(VPoint) * numVtces);
ComputeRotationMatrix(r, e, &m);
VTransform_ (offset, &m, &offset1);
for (i = 0; i < numVtces; ++i) {
p->vertex[i] = in->vertex[i];
#ifdef notdef
p->vertex[i].x -= offset->x;
p->vertex[i].y -= offset->y;
p->vertex[i].z -= offset->z;
#endif
VTransform_(&p->vertex[i], &m, &tmp);
#ifdef notdef
tmp.x += offset1.x;
tmp.y += offset1.y;
tmp.z += offset1.z;
#endif
p->vertex[i].x = tmp.x * scale->x;
p->vertex[i].y = tmp.y * scale->y;
p->vertex[i].z = tmp.z * scale->z;
#ifdef notdef
p->vertex[i].x += offset->x;
p->vertex[i].y += offset->y;
p->vertex[i].z += offset->z;
p->vertex[i].x += offset1.x;
p->vertex[i].y += offset1.y;
p->vertex[i].z += offset1.z;
#endif
}
if ((p->flags & PolyNormalValid) == 0) {
if ((p->flags & PolyClipBackface) != 0 ||
p->backColor != (VColor *) NULL) {
a.x = vert[0].x - vert[1].x;
a.y = vert[0].y - vert[1].y;
a.z = vert[0].z - vert[1].z;
b.x = vert[2].x - vert[1].x;
b.y = vert[2].y - vert[1].y;
b.z = vert[2].z - vert[1].z;
VCrossProd(&a, &b, &p->normal);
p->flags |= PolyNormalValid;
}
}
return p;
}
void
ComputeRotationMatrix(double r, VPoint * e, VMatrix * m)
{
double one64th = 1.0 / 64.0, ma;
VPoint Ax, Ay, Wy =
{0, 1, 0}, Wz =
{0, 0, 1};
VMatrix tm, tm1;
VIdentMatrix(&tm);
if (r != 0.0) {
VRotate(&tm, ZRotation, r * M_PI / 180.0);
}
if (fabs(e->x) < one64th && fabs(e->y) < one64th) {
VCrossProd(&Wy, e, &Ax);
}
else {
VCrossProd(&Wz, e, &Ax);
}
ma = sqrt(Ax.x * Ax.x + Ax.y * Ax.y + Ax.z * Ax.z);
Ax.x /= ma;
Ax.y /= ma;
Ax.z /= ma;
VCrossProd(e, &Ax, &Ay);
ma = sqrt(Ay.x * Ay.x + Ay.y * Ay.y + Ay.z * Ay.z);
Ay.x /= ma;
Ay.y /= ma;
Ay.z /= ma;
VIdentMatrix(m);
m->m[0][0] = Ax.x;
m->m[1][0] = Ax.y;
m->m[2][0] = Ax.z;
m->m[0][1] = Ay.x;
m->m[1][1] = Ay.y;
m->m[2][1] = Ay.z;
m->m[0][2] = e->x;
m->m[1][2] = e->y;
m->m[2][2] = e->z;
VMatrixMultByRank(&tm, m, &tm1, 3);
*m = tm1;
}
|