paysages3d/src/basics/Sphere.cpp

63 lines
1.7 KiB
C++
Raw Normal View History

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
Sphere::Sphere(const Vector3 &center, double radius) : center(center), radius(radius) {
2015-10-15 18:21:32 +00:00
radius2 = radius * radius;
}
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;
if (discr < 0) {
2015-10-15 18:21:32 +00:00
return 0;
} else if (discr == 0) {
2015-10-15 18:21:32 +00:00
*first_intersection = ray.getPointAtCursor(-0.5 * b);
return 1;
} 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;
if (x0 > x1) {
2015-10-15 18:21:32 +00:00
*first_intersection = ray.getPointAtCursor(x1);
*second_intersection = ray.getPointAtCursor(x0);
} else {
2015-10-15 18:21:32 +00:00
*first_intersection = ray.getPointAtCursor(x0);
*second_intersection = ray.getPointAtCursor(x1);
}
return 2;
}
}
void Sphere::save(PackStream *stream) const {
2015-10-15 18:21:32 +00:00
center.save(stream);
stream->write(&radius);
stream->write(&radius2);
}
void Sphere::load(PackStream *stream) {
2015-10-15 18:21:32 +00:00
center.load(stream);
stream->read(&radius);
stream->read(&radius2);
}