-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcylinder.c
131 lines (109 loc) · 3.79 KB
/
cylinder.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
#include "objects.h"
#include "operations.h"
#include "cylinder.h"
#include "polygon.h"
#include <math.h>
#include <stdio.h>
OBJECT createCylinder(double radius, POINT anchor, VECTOR axis, double d1, double d2, COLOR color, long double kd, long double ka,
long double kn, long double ks, long double o1, long double o2){
CYLINDER cylinder;
cylinder.radius = radius;
cylinder.anchor = anchor; // ANCLA
cylinder.axis = normalizeVector(axis); // EJE
cylinder.d1 = d1; // TAPA 1
cylinder.d2 = d2; // TAPA 2
cylinder.G = getG(cylinder.axis);
VECTOR temp = cruxProduct(cylinder.G, cylinder.axis);
double d = getD(temp, cylinder.anchor);
double magnitude = getMagnitude(temp);
temp = normalizeVector(temp);
d = d / magnitude;
cylinder.equation.a = temp.x;
cylinder.equation.b = temp.y;
cylinder.equation.c = temp.z;
cylinder.equation.d = d;
OBJECT newObject;
newObject.id = 'C';
newObject.cylinder = cylinder;
newObject.color = color;
newObject.ka = ka;
newObject.kd = kd;
newObject.ks = ks;
newObject.kn = kn;
newObject.o1 = o1;
newObject.o2 = o2;
return newObject;
}
bool verifyFinitePoint(POINT intersectionPoint, double d1, double d2, POINT o, VECTOR q){
double d = (intersectionPoint.x - o.x)*q.x + (intersectionPoint.y - o.y)*q.y + (intersectionPoint.z - o.z)*q.z;
if(d1 <= d && d <= d2){
return true;
}
return false;
}
INTERSECTION findIntersection_cylinder(VECTOR d, POINT e, POINT o, double radius, VECTOR q, double d1, double d2){
// d es direction, e es ojo, o es el ancla, q es el eje. Se puso así para que la formula no quede enorme
INTERSECTION intersection;
long double var1,var2,var3,var4,var5,var6;
var1 = (pow(q.x,2)*d.x)+(q.x*d.y*q.y)+(q.x*d.z*q.z)-d.x;
var2 = (pow(q.y,2)*d.y)+(d.x*q.x*q.y)+(q.y*d.z*q.z)-d.y;
var3 = (pow(q.z,2)*d.z)+(d.x*q.x*q.z)+(d.y*q.y*q.z)-d.z;
var4 = (e.x-o.x);
var5 = (e.y-o.y);
var6 = (e.z-o.z);
double a = pow(var1,2)+pow(var2,2)+pow(var3,2);
double b = (2*var1*var4*(pow(q.x,2)-1))+(2*var1*q.x*((q.y*var5)+(q.z*var6)))
+(2*var2*var5*(pow(q.y,2)-1))+(2*var2*q.y*((q.x*var4)+(q.z*var6)))
+(2*var3*var6*(pow(q.z,2)-1))+(2*var3*q.z*((q.x*var4)+(q.y*var5)));
double c = pow(((pow(q.x,2)-1)*var4),2)+pow((q.x*((q.y*var5)+(q.z*var6))),2)
+pow(((pow(q.y,2)-1)*var5),2)+pow((q.y*((q.x*var4)+(q.z*var6))),2)
+pow(((pow(q.z,2)-1)*var6),2)+pow((q.z*((q.x*var4)+(q.y*var5))),2)
+(2*var4*q.x*(pow(q.x,2)-1)*((q.y*var5)+(q.z*var6)))
+(2*var5*q.y*(pow(q.y,2)-1)*((q.x*var4)+(q.z*var6)))
+(2*var6*q.z*(pow(q.z,2)-1)*((q.x*var4)+(q.y*var5)))-pow(radius,2);
double discriminante = pow(b, 2) - 4*a*c;
if(discriminante < EPSILON){ // No hay interseccion con el cilindro INFINITO
intersection.tmin = 0;
intersection.tmax = 0;
intersection.flag = 0;
}
else{
if(discriminante > EPSILON){ // Hay dos intersecciones
double t1 = (-b + sqrt(discriminante))/(2.0*a);
double t2 = (-b - sqrt(discriminante))/(2.0*a);
if(t1 < t2){
intersection.tmin = t1;
intersection.tmax = t2;
}
else{
intersection.tmin = t2;
intersection.tmax = t1;
}
intersection.flag = 1;
}
else{ // Hay una interseccion
double temp = (-b + sqrt(discriminante))/(2.0*a);
if(temp != EPSILON){
intersection.tmin = temp;
}
else{
intersection.tmin = (-b - sqrt(discriminante))/(2.0*a);
}
intersection.tmax = 0;
intersection.flag = 1;
}
if(!verifyFinitePoint(getIntersectionPoint(pointToVector(e), d, intersection.tmin), d1, d2, o, q)){ // No hay intersección con el FINITO
if(verifyFinitePoint(getIntersectionPoint(pointToVector(e), d, intersection.tmax), d1, d2, o, q)){
intersection.tmin = intersection.tmax;
intersection.tmax = 0;
intersection.flag = 1;
}
else{
intersection.tmin = 0;
intersection.tmax = 0;
intersection.flag = 0;
}
}
}
return intersection;
}