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

# User Rev Content
1 greg 2.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     }