/* libsegl - Sebas Extended GL Library * Collection of Opengl/3D-Math helpers * * Copyright (c) 2008 by Sebastian Lohff, seba@seba-geek.de * http://www.seba-geek.de * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "geotypes.h" namespace segl { Sphere::Sphere(Punkt3D _pos, float _radius) { pos = _pos; radius = _radius; } Sphere::Sphere() { radius = 1.0f; } void Sphere::set(Punkt3D _pos, float _radius) { pos = _pos; radius = _radius; } bool Sphere::collision(const Sphere &s) const { return ((pos-s.pos)*(pos-s.pos))<((radius+s.radius)*(radius+s.radius)); } bool Sphere::collision(const Ray &r) const { return (r.dist(pos) <= radius); } bool Sphere::collision(const Box & b) const { return true; } bool Sphere::collision(const Plane &p) const { return p.dist(pos) <= radius; } bool Sphere::inSphere(Punkt3D p) const { return abs(pos-p)<=radius; } Punkt3D Sphere::getPos() const { return pos; } int Sphere::getIntersectionParam(const Ray &ray, float *param1, float *param2) { int numerg; // ax^2 + bx + c = 0 float a = ray.dir * ray.dir; float b = 2 * ray.dir * (ray.pos - pos); float c = ray.pos * ray.pos - 2 * ray.pos * pos + pos * pos - radius * radius; float p = b/a; float q = c/a; std::cout << p << " " << q << std::endl; if((p*p)/4.0f=2) return true; if(rnd>=0) { // TODO:Implement rounding // r1 = round(r1, rnd); // r2 = round(r2, rnd); // r3 = round(r3, rnd); } if(g1) return (r2 == r3); else if(g2) return (r1 == r3); else if(g3) return (r1 == r2); else return ((r1 == r2) == r3); } float Ray::dist(Punkt3D p) const { return abs(p - get( getParam(p) )); } float Ray::getParam(Punkt3D p, bool onray) const { if(onray) { if(!onRay(p)) return 0.0f; } return -((pos-p)*dir) / (dir*dir); } bool Ray::collision(const Sphere &s) const { return s.collision(*this); } bool Ray::collision(const Ray &r) const { return true; } bool Ray::collision(const Box & b) const { return true; } bool Ray::collision(const Plane &p) const { return true; } Box::Box() { max.set(1.0f, 1.0f, 1.0f); } Box::Box(Punkt3D _min, Punkt3D _max) { min = _min; max = _max; } bool Box::collision(const Sphere &s) const { return s.collision(*this); } bool Box::collision(const Ray &r) const { return r.collision(*this); } bool Box::collision(const Box & b) const { return true; } bool Box::collision(const Plane &p) const { return true; } Plane::Plane() { norm.set(0.0f, 1.0f, 0.0f); } Plane::Plane(Punkt3D _pos, Punkt3D _norm) { pos = _pos; norm = _norm; } Plane::Plane(float x, float y, float z, float a) { // TODO: Implementation (if not too lazy) norm.set(x, y, z); norm.normalize(); } bool Plane::collision(const Sphere &s) const { return s.collision(*this); } bool Plane::collision(const Ray &r) const { return r.collision(*this); } bool Plane::collision(const Box & b) const { return b.collision(*this); } bool Plane::collision(const Plane &p) const { return true; } bool Plane::onPlane(const Punkt3D &p) const { return dist(p) == 0.0f; } bool Plane::getIntersectionPoint(const Ray &r, Punkt3D *p) const { if(r.dir.calcAngle(norm) && !onPlane(r.pos)) return false; if(!p) return true; float param = (pos*norm - r.pos*norm) / (r.dir*norm); *p = r.get(param); return true; } float Plane::dist(Punkt3D p) const { return 0.0f; } } // namespace segl