2015-10-15 18:21:32 +00:00
|
|
|
#include "Sphere.h"
|
|
|
|
|
|
|
|
#include "InfiniteRay.h"
|
2016-07-23 20:58:32 +00:00
|
|
|
#include "PackStream.h"
|
|
|
|
#include <cmath>
|
2015-10-15 18:21:32 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
Sphere::Sphere(const Vector3 ¢er, double radius) : center(center), radius(radius) {
|
2015-10-15 18:21:32 +00:00
|
|
|
radius2 = radius * radius;
|
|
|
|
}
|
|
|
|
|
2015-11-10 00:12:14 +00:00
|
|
|
int Sphere::checkRayIntersection(const InfiniteRay &ray) const {
|
|
|
|
Vector3 L = ray.getOrigin().sub(center);
|
|
|
|
double b = 2.0 * ray.getDirection().dotProduct(L);
|
|
|
|
double c = L.dotProduct(L) - radius2;
|
|
|
|
|
|
|
|
double discr = b * b - 4.0 * c;
|
|
|
|
if (discr < 0) {
|
|
|
|
return 0;
|
|
|
|
} else if (discr == 0) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int Sphere::findRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection,
|
2015-11-18 16:22:33 +00:00
|
|
|
Vector3 *second_intersection) const {
|
2015-10-15 18:21:32 +00:00
|
|
|
Vector3 L = ray.getOrigin().sub(center);
|
|
|
|
double b = 2.0 * ray.getDirection().dotProduct(L);
|
|
|
|
double c = L.dotProduct(L) - radius2;
|
|
|
|
|
|
|
|
double discr = b * b - 4.0 * c;
|
2015-11-09 21:30:46 +00:00
|
|
|
if (discr < 0) {
|
2015-10-15 18:21:32 +00:00
|
|
|
return 0;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else if (discr == 0) {
|
2015-10-15 18:21:32 +00:00
|
|
|
*first_intersection = ray.getPointAtCursor(-0.5 * b);
|
|
|
|
return 1;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2015-10-15 18:21:32 +00:00
|
|
|
double x0 = (b > 0.0) ? -0.5 * (b + sqrt(discr)) : -0.5 * (b - sqrt(discr));
|
|
|
|
double x1 = c / x0;
|
2015-11-09 21:30:46 +00:00
|
|
|
if (x0 > x1) {
|
2015-10-15 18:21:32 +00:00
|
|
|
*first_intersection = ray.getPointAtCursor(x1);
|
|
|
|
*second_intersection = ray.getPointAtCursor(x0);
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2015-10-15 18:21:32 +00:00
|
|
|
*first_intersection = ray.getPointAtCursor(x0);
|
|
|
|
*second_intersection = ray.getPointAtCursor(x1);
|
|
|
|
}
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Sphere::save(PackStream *stream) const {
|
2015-10-15 18:21:32 +00:00
|
|
|
center.save(stream);
|
|
|
|
stream->write(&radius);
|
|
|
|
stream->write(&radius2);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Sphere::load(PackStream *stream) {
|
2015-10-15 18:21:32 +00:00
|
|
|
center.load(stream);
|
|
|
|
stream->read(&radius);
|
|
|
|
stream->read(&radius2);
|
|
|
|
}
|