-
Notifications
You must be signed in to change notification settings - Fork 0
/
vec.c
156 lines (139 loc) · 3.28 KB
/
vec.c
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "raytracer.h"
/* === vector operations === */
vec *vec_new(double x, double y, double z)
{
vec* newv = malloc(sizeof(vec));
if(newv == NULL) {
printf("vec_new: Cannot allocate\n");
exit (1);
}
newv->x = x;
newv->y = y;
newv->z = z;
return newv;
}
/* create a fresh vector (new heap allocation) with same components as argument */
vec *vec_dup(vec *v)
{
vec* newv = malloc(sizeof(vec));
if(newv == NULL) {
printf("vec_dup: Cannot allocate\n");
exit (1);
}
newv->x = v->x;
newv->y = v->y;
newv->z = v->z;
return newv;
}
/* add two vectors (allocate) */
/* (x,y,z) + (X,Y,Z) = (x+X,y+Y,z+Z) */
vec *vec_add(vec *v1, vec *v2)
{
vec* newv = malloc(sizeof(vec));
if(newv == NULL) {
printf("vec_add: Cannot allocate\n");
exit (1);
}
newv->x = v1->x+v2->x;
newv->y = v1->y+v2->y;
newv->z = v1->z+v2->z;
return newv;
}
/* subtract the second vector from the first (allocate) */
/* (x,y,z) - (X,Y,Z) = (x-X,y-Y,z-Z) */
vec *vec_sub(vec *v1, vec *v2)
{
vec* newv = malloc(sizeof(vec));
if(newv == NULL) {
printf("vec_sub: Cannot allocate\n");
exit (1);
}
newv->x = v1->x-v2->x;
newv->y = v1->y-v2->y;
newv->z = v1->z-v2->z;
return newv;
}
/* negate a vector (allocate) */
/* -(x,y,z) = (-x,-y,-z) */
vec *vec_neg(vec *v)
{
vec* newv = malloc(sizeof(vec));
if(newv == NULL) {
printf("vec_neg: Cannot allocate\n");
exit (1);
}
newv->x = -v->x;
newv->y = -v->y;
newv->z = -v->z;
return newv;
}
/* scale the components of a vector by scalar s (allocate) */
/* s(x,y,z) = (sx,sy,sz) */
vec *vec_scale(double s, vec *v)
{
vec* newv = malloc(sizeof(vec));
if(newv == NULL) {
printf("vec_scale: Cannot allocate\n");
exit (1);
}
newv->x = s*v->x;
newv->y = s*v->y;
newv->z = s*v->z;
return newv;
}
/* compute the dot product of two vectors */
/* (x,y,z) . (X,Y,Z) = xX+yY+zZ */
double vec_dot(vec *v1, vec *v2)
{
return (v1->x*v2->x+v1->y*v2->y+v1->z*v2->z);
}
/* compute the magnitude of a vector */
/* the magnitude is the square root of the sum of the squares of the components */
double vec_mag(vec *v)
{
return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
}
/* normalize the vector (allocate) */
/* to normalize a vector is to produce a vector pointing in the same direction whose magnitude is 1 */
/* - normalize a vector by scaling by 1 over its magnitude */
/* - if a vector's magnitude is zero, it can't be normalized; simply return it */
vec *vec_norm(vec *v)
{
double mag = fabs(vec_mag(v));
if (mag==0)
return v;
vec* newv = malloc(sizeof(vec));
if(newv == NULL) {
printf("vec_norm: Cannot allocate\n");
exit (1);
}
newv->x = v->x/mag;
newv->y = v->y/mag;
newv->z = v->z/mag;
return newv;
}
/* produce a string representation of a vector */
char *vec_tos(vec *v)
{
char buf[128];
int i;
for (i=0; i<127; i++)
buf[i] = '\0';
sprintf(buf, "<%.2lf, %.2lf, %.2lf>", v->x, v->y, v->z);
return strdup(buf);
}
/* print the string representation of a vector */
void vec_print(vec *v)
{
printf("<%lf, %lf, %lf>\n", v->x, v->y, v->z);
return;
}
void vec_free(vec *v)
{
free(v);
return;
}