bool et::intersect::sphereSphere(const Sphere& s1, const Sphere& s2, vec3* amount) { vec3 dv = s2.center() - s1.center(); float distance = dv.dotSelf(); float radiusSum = s1.radius() + s2.radius(); bool collised = (distance <= sqr(radiusSum)); if (amount && collised) *amount = dv.normalized() * (radiusSum - std::sqrt(distance)); return collised; }
bool et::intersect::sphereTriangle(const Sphere& s, const vec3& sphereVelocity, const triangle& t, vec3& point, vec3& normal, float& penetration, float& intersectionTime) { plane p(t); if (p.distanceToPoint(s.center()) <= s.radius()) return sphereTriangle(s, t, point, normal, penetration); vec3 triangleNormal = p.normal(); float NdotV = dot(triangleNormal, sphereVelocity); if (NdotV >= 0.0f) return false; intersectionTime = (s.radius() + p.equation.w - dot(triangleNormal, s.center())) / NdotV; vec3 movedCenter = s.center() + intersectionTime * sphereVelocity; return sphereTriangle(movedCenter, s.radius(), t, point, normal, penetration); }
inline VLXValue export_Sphere(const Sphere& sphere) { VLXValue value ( new VLXStructure("<vl::Sphere>") ); *value.getStructure() << "Center" << vlx_toValue(sphere.center()); *value.getStructure() << "Radius" << sphere.radius(); return value; }
bool Frustum::Intersects( const Sphere &sphere ) const { // Has the frustum planes been built? if (!initialized_) { ASSERT(false); return false; } // Are the frustum planes up to date? if (needs_rebuild_) { // TODO Warn them! } // For each plane, see if sphere is on negative side // If so, object is not visible for (int32 plane = 0; plane < 6; ++plane) { // Skip far plane if infinite view frustum if ((plane == FRUSTUM_PLANE_FAR) && far_distance_ == 0) { continue; } // If the distance from sphere center to plane is negative, and 'more negative' // than the radius of the sphere, sphere is outside frustum if (frustum_planes_[plane].Distance(sphere.center()) < -sphere.radius()) { // ALL corners on negative side therefore out of view return false; } } return true; }
Real Sphere::distance (const Sphere & other_sphere) const { libmesh_assert_greater ( this->radius(), 0. ); libmesh_assert_greater ( other_sphere.radius(), 0. ); const Real the_distance = (this->center() - other_sphere.center()).norm(); return the_distance - (this->radius() + other_sphere.radius()); }
bool et::intersect::sphereTriangles(const Sphere& s, const triangle* triangles, size_t triangleCount, vec3& point, vec3& normal, float& penetration) { for (size_t i = 0; i < triangleCount; ++i) { if (sphereTriangle(s.center(), s.radius(), triangles[i], point, normal, penetration)) return true; } return false; }
bool Frustum<NumericT>::intersects_with (const Sphere<3, NumericT> & s) const { for (dimension i = 0; i < 6; ++i) { NumericT d = _planes[i].distance_to_point(s.center()); if (d <= -s.radius()) return false; } return true; }
bool cull(const Sphere& sphere) const { // null spheres are always visible if (sphere.isNull()) return false; for(unsigned i=0; i<planes().size(); ++i) { if ( plane(i).distance(sphere.center()) > sphere.radius() ) return true; } return false; }
/** Returns true if a sphere contains the specified sphere. */ bool includes(const Sphere& other) const { if (isNull()) return false; else if (other.isNull()) return true; else { real distance = (center() - other.center()).length(); return radius() >= distance + other.radius(); } }
void createDistanceConstraints(SphereTree &i_stree, const std::vector<DistanceGeometry *>& i_shapes, std::vector<DistanceConstraint *>& o_consts) { // delete old constraints for (unsigned int i=0; i<o_consts.size(); i++){ // TODO : delete o_consts[i]; } o_consts.clear(); int nconsts=0; double ds = 0.005; // AR //double ds = 0.0; for (unsigned int i=0; i<i_shapes.size(); i++){ std::vector<hrp::Vector3> spheres; Sphere *s = dynamic_cast<Sphere *>(i_shapes[i]); CappedCylinder *cp = dynamic_cast<CappedCylinder *>(i_shapes[i]); if (s){ i_stree.collectSpheres(s->center(), s->radius(), DI, spheres); #if 1 for (unsigned int j=0; j<spheres.size(); j++){ Sphere *o = new Sphere(i_stree.link(), spheres[j], i_stree.radius()); DistancePair *dp = new SphereSpherePair(s, o); DistanceConstraint *dc = new DistanceConstraint(dp); dc->securityDistance(ds); dc->influenceDistance(DI); dc->xi(0.5*0.005); o_consts.push_back(dc); } #endif }else if (cp){ i_stree.collectSpheres(cp->point(), Vector3(cp->point()+cp->vector()), cp->radius(), DI, spheres); #if 1 for (unsigned int j=0; j<spheres.size(); j++){ Sphere *o = new Sphere(i_stree.link(), spheres[j], i_stree.radius()); DistancePair *dp = new CappedCylinderSpherePair(cp, o); DistanceConstraint *dc = new DistanceConstraint(dp); dc->securityDistance(ds); dc->influenceDistance(DI); dc->xi(0.5*0.005); o_consts.push_back(dc); } #endif } nconsts += spheres.size(); } }
size_t findBin(Vector3<FloatType> pos) { Vector3<FloatType> origin = boundingSphere.center() - boundingSphere.getRadius(); FloatType divisionWidth = (2 * boundingSphere.getRadius()) / (divisions + 1); Vector3<FloatType> normalizedPos = pos - origin; size_t x = floor(normalizedPos.getX() / divisionWidth); size_t y = floor(normalizedPos.getY() / divisionWidth); size_t z = floor(normalizedPos.getZ() / divisionWidth); size_t index = z + (divisions +1)*y + (divisions+1)*(divisions+1)*x; if (index >= size) { return size - 1; } return index; }
bool et::intersect::raySphere(const ray3d& r, const Sphere& s, vec3* ip1, vec3* ip2) { vec3 dv = r.origin - s.center(); float b = dot(r.direction, dv); if (b > 0.0) return false; float d = sqr(b) - dv.dotSelf() + sqr(s.radius()); if (d < 0.0f) return false; d = std::sqrt(d); if (ip1) *ip1 = r.origin - (b + d) * r.direction; if (ip2) *ip2 = r.origin + (d - b) * r.direction; return true; }
bool et::intersect::sphereAABB(const Sphere& s, const AABB& b) { return sphereBox(s.center(), s.radius(), b.center, b.dimension); }
Sphere::Sphere (const Sphere & other_sphere) : Surface() { this->create_from_center_radius (other_sphere.center(), other_sphere.radius()); }
bool et::intersect::sphereOBB(const Sphere& s, const OBB& b) { return sphereBox(b.center + b.transform.transposed() * (s.center() - b.center), s.radius(), b.center, b.dimension); }
bool et::intersect::sphereTriangle(const Sphere& s, const triangle& t, vec3& point, vec3& normal, float& penetration) { return sphereTriangle(s.center(), s.radius(), t, point, normal, penetration); }
int main(int argc, char* argv[]) { Vector viewPoint(0, 0, 0); Vector viewDirection(0, 0, 1); Vector viewUp(0, -1, 0); double frontPlaneDist = 2; double backPlaneDist = 1000; double viewPlaneDist = 90; double viewPlaneWidth = 160; double viewPlaneHeight = 90; int imageWidth = atoi(argv[1]); int imageHeight = atoi(argv[2]); Vector viewParallel = viewUp^viewDirection; viewDirection.normalize(); viewUp.normalize(); viewParallel.normalize(); Image image(imageWidth, imageHeight); Color c; //Color only /*for (int ix = 0; ix < imageWidth; ix++) { for (int iy = 0; iy < imageHeight; iy++) { Vector x0 = viewPoint; Vector x1 = viewPoint + viewDirection*viewPlaneDist + viewUp*imageToViewPlane(iy, imageHeight, viewPlaneHeight)s + viewParallel*imageToViewPlane(ix, imageWidth, viewPlaneWidth); Line ray = Line(x0, x1, false); Intersection i = findFirstIntersection(ray, frontPlaneDist, backPlaneDist); if (i.valid()) { c = i.geometry().color(); image.setPixel(ix, iy, c); } } }*/ Light l = Light(Vector(0,70,150), Color(1,1,1), Color(1, 1, 1), Color(1,1,1), 1); for (int ix = 0; ix < imageWidth; ix++) { for (int iy = 0; iy < imageHeight; iy++) { Vector x0 = viewPoint; Vector x1 = viewPoint + viewDirection*viewPlaneDist + viewUp*imageToViewPlane(iy, imageHeight, viewPlaneHeight) + viewParallel*imageToViewPlane(ix, imageWidth, viewPlaneWidth); Line ray = Line(x0, x1, false); Intersection i = findFirstIntersection(ray, frontPlaneDist, backPlaneDist); if (i.valid()) { Sphere* s = (Sphere*)i.sphere(); Material m = i.geometry().material(); Vector L = l.position(); Vector C = viewPoint; Vector V = i.vec(); Vector S = s->center(); Vector N = V - S; N.normalize(); Vector T = L - V; T.normalize(); Vector E = C - V; E.normalize(); Vector R = N*(N*T) * 2 - T; R.normalize(); //printf("%f %f, %f\n", S.x(), S.y(), S.z()); c = m.ambient() * l.ambient(); if (N*T > 0) { c += m.diffuse() * l.diffuse() * (N*T); } if (E*R > 0) { c += m.specular() * l.specular() * pow(E*R, m.shininess()); } c *= l.intensity(); image.setPixel(ix, iy, c); } } } image.store("scene.ppm"); for(int i=0; i<geometryCount; i++) { delete scene[i]; } return 0; }
#define CATCH_CONFIG_RUNNER #include <catch.hpp> #include "shape.hpp" #include "sphere.hpp" #include "box.hpp" TEST_CASE("Sphere","[testing_sphere]") { std::cout << " First test" << std::endl; Sphere sp1; glm::vec3 ur{}; Color white{0.0, 0.0, 0.0}; REQUIRE(sp1.radius() == (0.0)); REQUIRE(sp1.center() == ur); REQUIRE(sp1.color() == white); REQUIRE(sp1.name() == "no name" ); glm::vec3 c{3.0, 3.0, 3.0}; Sphere sp2{c, 2.5}; REQUIRE(sp2.center() == c ); REQUIRE(sp2.center() == glm::vec3(3.0, 3.0, 3.0)); REQUIRE(sp2.radius() == (2.5)); REQUIRE(sp2.area() == Approx(78.5398)); REQUIRE(sp2.volume() == Approx(65.4498)); REQUIRE(sp2.color() == white); REQUIRE(sp2.name() == "no name"); glm::vec3 d{5.0, 5.0, 5.0}; Color pink{128, 76, 51}; Sphere sp3{d, 3.0, pink, "Sphere 3"}; REQUIRE(sp3.center() == glm::vec3(5.0, 5.0, 5.0));
Sphere::Sphere(Sphere const& sphere) : Sphere::Shape( sphere.material(), sphere.name(), sphere.type() ), m_center{ sphere.center() }, m_radius{ sphere.radius() } {}
int main() { K k(3); std::vector<Point> points(6, k.origin()); points[0][0] = 0; points[0][1] = 0; points[0][2] = 0; points[1][0] = 0; points[1][1] = 2; points[1][2] = 0; points[2][0] = 0; points[2][1] = 0; points[2][2] = 5; points[3][0] = 1; points[3][1] = 1; points[3][2] = 1; points[4][0] = 0; points[4][1] = 1; points[4][2] = 0; points[5][0] = 1; points[5][1] = 0; points[5][2] = 0; // Edges { PointContainer vertices(2); vertices[0] = &points[0]; vertices[1] = &points[2]; std::cout << "{0, 2}:" << std::endl; Sphere s = k.circumsphere(vertices); std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl; std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl; std::cout << std::endl; vertices[0] = &points[0]; vertices[1] = &points[3]; std::cout << "{0, 3}:" << std::endl; s = k.circumsphere(vertices); std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl; std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl; std::cout << std::endl; } // Triangles { PointContainer vertices(3); vertices[0] = &points[0]; vertices[1] = &points[3]; vertices[2] = &points[1]; std::cout << "{0, 3, 1}:" << std::endl;; Sphere s = k.circumsphere(vertices); std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl; std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl; std::cout << std::endl; vertices[0] = &points[0]; vertices[1] = &points[4]; vertices[2] = &points[5]; std::cout << "{0, 4, 5}:" << std::endl; s = k.circumsphere(vertices); std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl; std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl; std::cout << std::endl; } // Tetrahedron { PointContainer vertices(4); vertices[0] = &points[3]; vertices[1] = &points[1]; vertices[2] = &points[2]; vertices[3] = &points[0]; std::cout << "{3, 1, 2, 0}:" << std::endl; Sphere s = k.circumsphere(vertices); std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl; std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl; std::cout << s.center().squared_distance(points[0]) << std::endl; std::cout << std::endl; } { PointContainer vertices(3); vertices[0] = &points[3]; vertices[1] = &points[1]; vertices[2] = &points[2]; std::cout << "{3, 1, 2}:" << std::endl; Sphere s = k.circumsphere(vertices); std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl; std::cout << "Side of: " << k.side_of_circumsphere(vertices, points[0]) << std::endl; std::cout << "Distance: " << points[0].squared_distance(s.center()) << std::endl; std::cout << s.center().squared_distance(points[0]) << std::endl; std::cout << std::endl; } }
float Plane::distanceToSphere( const Sphere& sphere ) const { return distanceToPoint( sphere.center() ) - sphere.radius(); }