-
Notifications
You must be signed in to change notification settings - Fork 1
/
Sphere.cpp
222 lines (156 loc) · 5.64 KB
/
Sphere.cpp
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// Sphere.cpp: implementation of the CSphere class.
//
//////////////////////////////////////////////////////////////////////
# include "Sphere.h"
# include "IntersectionInfo.h"
# include <Math.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSphere::CSphere()
{
}
CSphere::~CSphere()
{
}
/*********************************************************************
NAME : CSphere
DESCRIPTION: Parameterized constructor
PARAMETER : pos : The position of the sphere in space.
col : the color of the sphere
radius : the radius of the sphere
RETURN : NONE
EXCEPTION : NONE.
*********************************************************************/
CSphere::CSphere(CPoint3D pos, CColor col, float radius) : CShape (pos, col)
{
m_fRadius = radius;
}
/*********************************************************************
NAME : CSphere
DESCRIPTION: Copy constructor
PARAMETER : sphere1 : the object to be copied
RETURN : NONE
EXCEPTION : NONE.
*********************************************************************/
CSphere::CSphere(CSphere &sphere1)
{
this->m_fRadius = sphere1.m_fRadius;
this->objColor = sphere1.objColor;
this->m_ptPosition = sphere1.m_ptPosition;
}
/*********************************************************************
NAME : SetRadius
DESCRIPTION: Sets the radius of the sphere
PARAMETER : radius : the new radius of the sphere
RETURN : void
EXCEPTION : NONE.
*********************************************************************/
void CSphere::SetRadius(float radius)
{
m_fRadius = radius;
}
/*********************************************************************
NAME : GetIntersection
DESCRIPTION: Calculates the intersection of the given ray with the sphere.
If an intersection occurs the return value contains the
homogenous coordinates of the point of intersection. If not,
then the 'w' of the homogenous coordinates returned is zero
PARAMETER : ray : the ray to test for.
RETURN : 3D homogenous point
EXCEPTION : NONE.
*********************************************************************/
CIntersectionInfo CSphere::GetIntersection (CRay ray)
{
CPoint3D ptNoIntersection(0.0f,0.0f,0.0f,0.0f); // no intersection by default
CPoint3D ptOfIntersection;
CIntersectionInfo hitInfo;
float B;
float C;
float B2_4C;
float omega;
float fX, fY, fZ;
// Default case:
hitInfo.SetPointOfIntersection(ptNoIntersection);
/******************************************************************************
STRATEGY:
To find the point of intersection, we will have to solve a quadratic equation.
The explanation of how this equation came about will soon be documented, for now
the equation is solved in teh program.
A quad eqn is of teh form : omega = ( -B +/- sqrt (B^2 - 4AC) ) / 2 A
In this case, A is 1 because the direction of the ray is normalized.
1. Calculate 'B'.
2. Calculate 'C'
3. Calculate the discriminator (ie B2 - 4AC)
4. Make sure we don't have unreal roots
5. Calculate Omega
6. Make sure the point of intersection is in front of the ray.
7. using omega, find the final point of intersection.
8. Set values into the hitInfo object.
9. Return the hitInfo object.
******************************************************************************/
// 1.
B = 2.0f * ( ray.Direction().XComponent() * (ray.Origin().GetX() - m_ptPosition.GetX())
+ ray.Direction().YComponent() * (ray.Origin().GetY() - m_ptPosition.GetY())
+ ray.Direction().ZComponent() * (ray.Origin().GetZ() - m_ptPosition.GetZ()));
// 2.
C = (ray.Origin().GetX() - m_ptPosition.GetX()) * (ray.Origin().GetX() - m_ptPosition.GetX())
+ (ray.Origin().GetY() - m_ptPosition.GetY()) * (ray.Origin().GetY() - m_ptPosition.GetY())
+ (ray.Origin().GetZ() - m_ptPosition.GetZ()) * (ray.Origin().GetZ() - m_ptPosition.GetZ())
- (m_fRadius * m_fRadius);
// 3.
B2_4C = B * B - 4 * C;
// 4.
if (B2_4C < 0)
{
// no real roots for quadratic equation.
return hitInfo;
}
// 5.
omega = (-B - (float)sqrt((double)B2_4C)) / 2;
// 6.
if(omega < 0)
{
// intersection is behind the origin, no use.
return hitInfo;
}
// 7.
fX = ray.Origin().GetX() + ray.Direction().XComponent() * omega;
fY = ray.Origin().GetY() + ray.Direction().YComponent() * omega;
fZ = ray.Origin().GetZ() + ray.Direction().ZComponent() * omega;
ptOfIntersection.SetPoint(fX,fY,fZ);
// 8.
hitInfo.SetPointOfIntersection (ptOfIntersection);
hitInfo.SetColor (objColor);
hitInfo.SetNormal (GetNormalAt(ptOfIntersection));
hitInfo.SetTexCoords (GetTexCoords (ptOfIntersection));
// 9.
return hitInfo;
}
/*********************************************************************
NAME : GetNormalAt
DESCRIPTION: Gets the normal at the specified point
PARAMETER : pt : the point
RETURN : CVector
EXCEPTION : NONE.
*********************************************************************/
CVector CSphere::GetNormalAt(CPoint3D pt)
{
CVector vecNormal (pt - this->m_ptPosition);
vecNormal.Normalize();
return vecNormal;
}
/*********************************************************************
NAME : ShadePoint
DESCRIPTION: This functin returns the color that should be displayed
for this object given the hit details.
PARAMETER : objHitInfo : detailed information about the hit.
RETURN : NONE
EXCEPTION : NONE.
*********************************************************************/
CColor CSphere::ShadePoint(CIntersectionInfo objHitInfo)
{
if (m_pShader == 0)
return this->objColor;
return m_pShader->ShadePoint(objHitInfo);
}