File: VScalePoly.c

package info (click to toggle)
acm 5.0-19
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 7,852 kB
  • ctags: 4,792
  • sloc: ansic: 42,427; makefile: 706; cpp: 293; perl: 280; sh: 198
file content (121 lines) | stat: -rwxr-xr-x 2,761 bytes parent folder | download | duplicates (9)
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;
}