-
Notifications
You must be signed in to change notification settings - Fork 0
/
Sphere.cpp
106 lines (94 loc) · 2.82 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
#include "Sphere.h"
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
Sphere::Sphere() : GeometricObject()
{
this->isAIntersectLine = false;
this->im = NULL;
}
Sphere::Sphere(Point3D center, double radius) : center(center), radius(radius)
{
this->isAIntersectLine = false;
color.red = 1.0;
color.green = 1.0;
color.blue = 0.0;
this->im = NULL;
}
Sphere::Sphere(Point3D center, double radius, ColorRGB color) : center(center), radius(radius), color(color)
{
this->im = NULL;
this->isAIntersectLine = false;
}
Sphere::Sphere(Point3D center, double radius, ColorRGB color, Ray intersectLine) : center(center), radius(radius),
color(color), intersectLine(intersectLine)
{
this->isAIntersectLine = true;
this->im = NULL;
}
Sphere::~Sphere() {}
bool Sphere::isImpact(const Ray &ray, double &minEquationRoot, Vector3D &normal, Point3D &q) const
{
double equationRoot;
Vector3D originMinusCenter = ray.origin - this->center;
double a = ray.direction * ray.direction;
double b = 2 * ray.direction * originMinusCenter;
double c = originMinusCenter * originMinusCenter - this->radius * this->radius;
double discriminant = b * b - 4.0 * a * c;
if (discriminant < 0.0)
return false;
double discriminantEvaluation = sqrt(discriminant);
double denominator = 2.0 * a;
// smaller root
equationRoot = (-b - discriminantEvaluation) / denominator;
if (equationRoot > 0.000001)
{
q = ray.origin + equationRoot * ray.direction;
// if (this->isAIntersectLine) {}
normal = (originMinusCenter + equationRoot * ray.direction) / this->radius;
minEquationRoot = equationRoot;
return true;
}
// larger root
equationRoot = (-b + discriminantEvaluation) / denominator;
if (equationRoot > 0.000001)
{
q = ray.origin + equationRoot * ray.direction;
normal = (originMinusCenter + equationRoot * ray.direction) / this->radius;
minEquationRoot = equationRoot;
return true;
}
}
void Sphere::setColor(double red, double green, double blue)
{
this->color.red = red;
this->color.green = green;
this->color.blue = blue;
}
ColorRGB Sphere::getColor(Point3D hitPoint)
{
ColorRGB c;
if (this->im != NULL)
{
return im->get_color(hitPoint);
}
c.red = this->color.red;
c.green = this->color.green;
c.blue = this->color.blue;
return c;
}
void Sphere::setHasShadow(bool shadow)
{
this->hasShadow = shadow;
}
void Sphere::setImTexture(string path)
{
char charArray[path.length() + 1];
strcpy(charArray, path.c_str());
im = new ImTexture();
m.read_ppm_file(charArray);
im->set_image(&m);
im->set_SphereMap(&sm);
}