This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/geo/Triangle3.h
2018-10-25 11:50:12 +02:00

217 lines
4.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* © Copyright 2014 Urheberrechtshinweis
* Alle Rechte vorbehalten / All Rights Reserved
*
* Programmcode ist urheberrechtlich geschuetzt.
* Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner.
* Keine Verwendung ohne explizite Genehmigung.
* (vgl. § 106 ff UrhG / § 97 UrhG)
*/
#ifndef TRIANGLE3_H
#define TRIANGLE3_H
#include "Point3.h"
#include "Ray3.h"
struct Triangle3 {
Point3 p1;
Point3 p2;
Point3 p3;
public:
/** empty ctor */
Triangle3() : p1(), p2(), p3() {;}
/** ctor */
Triangle3(Point3 p1, Point3 p2, Point3 p3) : p1(p1), p2(p2), p3(p3) {;}
// Point3 cross(Point3 b, Point3 c) const {
// return Point3(
// b.y*c.z - c.y*b.z,
// b.z*c.x - c.z*b.x,
// b.x*c.y - c.x*b.y
// );
// }
// float dot(Point3 b, Point3 c) const {
// return b.x*c.x + b.y*c.y + b.z*c.z;
// }
Triangle3 operator - (const Point3 o) const {
return Triangle3(p1-o, p2-o, p3-o);
}
Triangle3& operator += (const Point3 o) {
p1 += o;
p2 += o;
p3 += o;
return *this;
}
Triangle3& operator -= (const Point3 o) {
p1 -= o;
p2 -= o;
p3 -= o;
return *this;
}
/** scale using 3 individual components */
Triangle3& operator *= (const Point3 o) {
p1 *= o;
p2 *= o;
p3 *= o;
return *this;
}
/** switch between CW<->CCW */
void reverse() {
std::swap(p2, p3);
}
void rotate_deg(const Point3 rot) {
p1 = p1.rot(rot.x/180.0f*M_PI, rot.y/180.0f*M_PI, rot.z/180.0f*M_PI);
p2 = p2.rot(rot.x/180.0f*M_PI, rot.y/180.0f*M_PI, rot.z/180.0f*M_PI);
p3 = p3.rot(rot.x/180.0f*M_PI, rot.y/180.0f*M_PI, rot.z/180.0f*M_PI);
}
// void ensureCCW() {
// Point3 norm = cross(p3-p1, p2-p1);
// if (norm.z < 0) {
// reverse();
// }
// }
Point3 getNormal() const {
return cross( p2-p1, p3-p1 ).normalized();
}
// http://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/
bool intersects(const Ray3& ray, Point3& pos) const {
const Point3 e1 = p2-p1;
const Point3 e2 = p3-p1;
const Point3 h = cross(ray.dir, e2);
const double a = dot(e1, h);
if (a > -0.00001 && a < 0.00001) {return false;}
const double f = 1/a;
const Point3 s = ray.start - p1;
const double u = f * dot(s,h);
if (u < 0.0 || u > 1.0) {return false;}
const Point3 q = cross(s, e1);
const double v = f * dot(ray.dir, q);
if (v < 0.0 || u + v > 1.0) {return false;}
const double t = f * dot(e2,q);
if (t > 0.00001) {
pos = ray.start + (ray.dir * t);
return true;
}
return false;
}
/** add some slight delta to prevent rounding issues */
bool intersectsDelta(const Ray3& ray, const double delta, Point3& pos) const {
const Point3 e1 = p2-p1;
const Point3 e2 = p3-p1;
// make delta an absolute value (independent of the triangle's size)
// larger triangle -> smaller delta, as u,v are [0:1]
//double deltaU = delta/e2.length();
//double deltaV = delta/e1.length();
const double deltaU = delta;
const double deltaV = delta;
const Point3 h = cross(ray.dir, e2);
const double a = dot(e1, h);
if (a > -0.00001 && a < 0.00001) {return false;}
const double f = 1/a;
const Point3 s = ray.start - p1;
const double u = f * dot(s,h);
if (u < 0.0-deltaU || u > 1.0+deltaU) {return false;}
const Point3 q = cross(s, e1);
const double v = f * dot(ray.dir, q);
if (v < 0.0-deltaV || u + v > 1.0+deltaV) {return false;}
const double t = f * dot(e2,q);
if (t > 0.00001) {
pos = ray.start + (ray.dir * t);
return true;
}
return true;
}
/** perform some sanity checks */
bool isValid() const {
if (p1 == p2) {return false;}
if (p1 == p3) {return false;}
if (p2 == p3) {return false;}
return true;
}
/*
int rayIntersectsTriangle(float *p, float *d,
float *v0, float *v1, float *v2) {
float e1[3],e2[3],h[3],s[3],q[3];
float a,f,u,v;
//crossProduct(h,d,e2);
a = innerProduct(e1,h);
if (a > -0.00001 && a < 0.00001)
return(false);
f = 1/a;
vector(s,p,v0);
u = f * (innerProduct(s,h));
if (u < 0.0 || u > 1.0)
return(false);
crossProduct(q,s,e1);
v = f * innerProduct(d,q);
if (v < 0.0 || u + v > 1.0)
return(false);
// at this stage we can compute t to find out where
// the intersection point is on the line
t = f * innerProduct(e2,q);
if (t > 0.00001) // ray intersection
return(true);
else // this means that there is a line intersection
// but not a ray intersection
return (false);
}
*/
};
#endif // TRIANGLE3_H