aboutsummaryrefslogtreecommitdiff
path: root/src/libgeometry/transform.c
blob: a59248725cb84a65cd94786adc0ced4005340665 (plain)
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
/*
 * The following routines transform points and planes from one space
 * to another.  Points and planes are represented by their
 * homogeneous coordinates, stored in variables of type Point3.
 */
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <geometry.h>
/*
 * Transform point p.
 */
Point3 xformpoint(Point3 p, Space *to, Space *from){
	Point3 q, r;
	register double *m;
	if(from){
		m=&from->t[0][0];
		q.x=*m++*p.x; q.x+=*m++*p.y; q.x+=*m++*p.z; q.x+=*m++*p.w;
		q.y=*m++*p.x; q.y+=*m++*p.y; q.y+=*m++*p.z; q.y+=*m++*p.w;
		q.z=*m++*p.x; q.z+=*m++*p.y; q.z+=*m++*p.z; q.z+=*m++*p.w;
		q.w=*m++*p.x; q.w+=*m++*p.y; q.w+=*m++*p.z; q.w+=*m  *p.w;
	}
	else
		q=p;
	if(to){
		m=&to->tinv[0][0];
		r.x=*m++*q.x; r.x+=*m++*q.y; r.x+=*m++*q.z; r.x+=*m++*q.w;
		r.y=*m++*q.x; r.y+=*m++*q.y; r.y+=*m++*q.z; r.y+=*m++*q.w;
		r.z=*m++*q.x; r.z+=*m++*q.y; r.z+=*m++*q.z; r.z+=*m++*q.w;
		r.w=*m++*q.x; r.w+=*m++*q.y; r.w+=*m++*q.z; r.w+=*m  *q.w;
	}
	else
		r=q;
	return r;
}
/*
 * Transform point p with perspective division.
 */
Point3 xformpointd(Point3 p, Space *to, Space *from){
	p=xformpoint(p, to, from);
	if(p.w!=0){
		p.x/=p.w;
		p.y/=p.w;
		p.z/=p.w;
		p.w=1;
	}
	return p;
}
/*
 * Transform plane p -- same as xformpoint, except multiply on the
 * other side by the inverse matrix.
 */
Point3 xformplane(Point3 p, Space *to, Space *from){
	Point3 q, r;
	register double *m;
	if(from){
		m=&from->tinv[0][0];
		q.x =*m++*p.x; q.y =*m++*p.x; q.z =*m++*p.x; q.w =*m++*p.x;
		q.x+=*m++*p.y; q.y+=*m++*p.y; q.z+=*m++*p.y; q.w+=*m++*p.y;
		q.x+=*m++*p.z; q.y+=*m++*p.z; q.z+=*m++*p.z; q.w+=*m++*p.z;
		q.x+=*m++*p.w; q.y+=*m++*p.w; q.z+=*m++*p.w; q.w+=*m  *p.w;
	}
	else
		q=p;
	if(to){
		m=&to->t[0][0];
		r.x =*m++*q.x; r.y =*m++*q.x; r.z =*m++*q.x; r.w =*m++*q.x;
		r.x+=*m++*q.y; r.y+=*m++*q.y; r.z+=*m++*q.y; r.w+=*m++*q.y;
		r.x+=*m++*q.z; r.y+=*m++*q.z; r.z+=*m++*q.z; r.w+=*m++*q.z;
		r.x+=*m++*q.w; r.y+=*m++*q.w; r.z+=*m++*q.w; r.w+=*m  *q.w;
	}
	else
		r=q;
	return r;
}