ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pmapgen.c
Revision: 2.1
Committed: Wed Oct 11 10:39:26 1995 UTC (28 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /* Copyright (c) 1995 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * pmapgen.c: general routines for 2-D perspective mappings.
9 * These routines are independent of the poly structure,
10 * so we do not think in terms of texture and screen space.
11 *
12 * Paul Heckbert 5 Nov 85, 12 Dec 85
13 */
14
15 static char rcsid[] = "$Header: pmapgen.c,v 2.0 88/10/12 21:58:33 ph Locked $";
16 #include <stdio.h>
17 #include "pmap.h"
18 #include "mx3.h"
19
20 #define TOLERANCE 1e-13
21 #define ZERO(x) ((x)<TOLERANCE && (x)>-TOLERANCE)
22
23 #define X(i) quad[i][0] /* quadrilateral x and y */
24 #define Y(i) quad[i][1]
25
26 /*
27 * pmap_quad_rect: find mapping between quadrilateral and rectangle.
28 * The correspondence is:
29 *
30 * quad[0] --> (u0,v0)
31 * quad[1] --> (u1,v0)
32 * quad[2] --> (u1,v1)
33 * quad[3] --> (u0,v1)
34 *
35 * This method of computing the adjoint numerically is cheaper than
36 * computing it symbolically.
37 */
38
39 pmap_quad_rect(u0, v0, u1, v1, quad, QR)
40 double u0, v0, u1, v1; /* bounds of rectangle */
41 double quad[4][2]; /* vertices of quadrilateral */
42 double QR[3][3]; /* quad->rect transform (returned) */
43 {
44 int ret;
45 double du, dv;
46 double RQ[3][3]; /* rect->quad transform */
47
48 du = u1-u0;
49 dv = v1-v0;
50 if (du==0. || dv==0.) {
51 fprintf(stderr, "pmap_quad_rect: null rectangle\n");
52 return PMAP_BAD;
53 }
54
55 /* first find mapping from unit uv square to xy quadrilateral */
56 ret = pmap_square_quad(quad, RQ);
57 if (ret==PMAP_BAD) return PMAP_BAD;
58
59 /* concatenate transform from uv rectangle (u0,v0,u1,v1) to unit square */
60 RQ[0][0] /= du;
61 RQ[1][0] /= dv;
62 RQ[2][0] -= RQ[0][0]*u0 + RQ[1][0]*v0;
63 RQ[0][1] /= du;
64 RQ[1][1] /= dv;
65 RQ[2][1] -= RQ[0][1]*u0 + RQ[1][1]*v0;
66 RQ[0][2] /= du;
67 RQ[1][2] /= dv;
68 RQ[2][2] -= RQ[0][2]*u0 + RQ[1][2]*v0;
69
70 /* now RQ is transform from uv rectangle to xy quadrilateral */
71 /* QR = inverse transform, which maps xy to uv */
72 if (mx3d_adjoint(RQ, QR)==0.)
73 fprintf(stderr, "pmap_quad_rect: warning: determinant=0\n");
74 return ret;
75 }
76
77 /*
78 * pmap_square_quad: find mapping between unit square and quadrilateral.
79 * The correspondence is:
80 *
81 * (0,0) --> quad[0]
82 * (1,0) --> quad[1]
83 * (1,1) --> quad[2]
84 * (0,1) --> quad[3]
85 */
86
87 pmap_square_quad(quad, SQ)
88 register double quad[4][2]; /* vertices of quadrilateral */
89 register double SQ[3][3]; /* square->quad transform */
90 {
91 double px, py;
92
93 px = X(0)-X(1)+X(2)-X(3);
94 py = Y(0)-Y(1)+Y(2)-Y(3);
95
96 if (ZERO(px) && ZERO(py)) { /* affine */
97 SQ[0][0] = X(1)-X(0);
98 SQ[1][0] = X(2)-X(1);
99 SQ[2][0] = X(0);
100 SQ[0][1] = Y(1)-Y(0);
101 SQ[1][1] = Y(2)-Y(1);
102 SQ[2][1] = Y(0);
103 SQ[0][2] = 0.;
104 SQ[1][2] = 0.;
105 SQ[2][2] = 1.;
106 return PMAP_LINEAR;
107 }
108 else { /* perspective */
109 double dx1, dx2, dy1, dy2, del;
110
111 dx1 = X(1)-X(2);
112 dx2 = X(3)-X(2);
113 dy1 = Y(1)-Y(2);
114 dy2 = Y(3)-Y(2);
115 del = DET2(dx1,dx2, dy1,dy2);
116 if (del==0.) {
117 fprintf(stderr, "pmap_square_quad: bad mapping\n");
118 return PMAP_BAD;
119 }
120 SQ[0][2] = DET2(px,dx2, py,dy2)/del;
121 SQ[1][2] = DET2(dx1,px, dy1,py)/del;
122 SQ[2][2] = 1.;
123 SQ[0][0] = X(1)-X(0)+SQ[0][2]*X(1);
124 SQ[1][0] = X(3)-X(0)+SQ[1][2]*X(3);
125 SQ[2][0] = X(0);
126 SQ[0][1] = Y(1)-Y(0)+SQ[0][2]*Y(1);
127 SQ[1][1] = Y(3)-Y(0)+SQ[1][2]*Y(3);
128 SQ[2][1] = Y(0);
129 return PMAP_PERSP;
130 }
131 }