/* $Id$ * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). * * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. * * This program 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include "triangle.hpp" #include "numeric.hpp" namespace ocl { Triangle::Triangle() { p[0]=Point(1,0,0); p[1]=Point(0,1,0); p[2]=Point(0,0,1); calcNormal(); calcBB(); } Triangle::Triangle(Point p1, Point p2, Point p3) { p[0]=p1; p[1]=p2; p[2]=p3; calcNormal(); calcBB(); } Triangle::Triangle(const Triangle &t) { p[0]=t.p[0]; p[1]=t.p[1]; p[2]=t.p[2]; calcNormal(); calcBB(); } /// calculate bounding box values void Triangle::calcBB() { bb.clear(); bb.addTriangle( *this ); } /// calculate, normalize, and set the Triangle normal void Triangle::calcNormal() { Point v1=p[0]-p[1]; Point v2=p[0]-p[2]; Point ntemp = v1.cross(v2); // the normal is in the direction of the cross product between the edge vectors ntemp.normalize(); // FIXME this might fail if norm()==0 n = Point(ntemp.x,ntemp.y,ntemp.z); } Point Triangle::upNormal() const { return (n.z < 0) ? -1.0* n : n; } bool Triangle::zslice_verts(Point& p1, Point& p2, double zcut) const { if ( (zcut <= this->bb.minpt.z) || ((zcut >= this->bb.maxpt.z)) ) return false; // no zslice // find out how many vertices are below zcut std::vector below; std::vector above; for (int m=0;m<3;++m) { if ( p[m].z <= zcut ) below.push_back(p[m]); else above.push_back(p[m]); } if ( !(below.size() == 1) && !(below.size() == 2) ) { std::cout << "triangle.cpp: zslice_verts() error while trying to z-slice\n"; std::cout << " triangle=" << *this << "\n"; std::cout << " zcut=" << zcut << "\n"; std::cout << above.size() << " above points:\n"; BOOST_FOREACH(Point p, above) { std::cout << " " << p << "\n"; } std::cout << below.size() << " below points:\n"; BOOST_FOREACH(Point p, below) { std::cout << " " << p << "\n"; } } assert( (below.size() == 1) || (below.size() == 2) ); if ( below.size() == 2 ) { assert( above.size() == 1 ); // find two new intersection points // edge is p1 + t*(p2-p1) = zcut // so t = zcut-p1 / (p2-p1) double t1 = (zcut - above[0].z) / (below[0].z - above[0].z); // div by zero?! double t2 = (zcut - above[0].z) / (below[1].z - above[0].z); p1 = above[0] + t1*(below[0] - above[0]); p2 = above[0] + t2*(below[1] - above[0]); return true; } else if ( below.size() == 1 ) { assert( above.size() == 2 ); // find intersection points and add two new triangles // t = (zcut -p1) / (p2-p1) double t1 = (zcut - above[0].z) / (below[0].z - above[0].z); double t2 = (zcut - above[1].z) / (below[0].z - above[1].z); p1 = above[0] + t1*(below[0]-above[0]); p2 = above[1] + t2*(below[0]-above[1]); return true; } else { assert(0); return false; } } void Triangle::rotate(double xr, double yr, double zr) { for (int n=0;n<3;++n) { p[n].xRotate(xr); p[n].yRotate(yr); p[n].zRotate(zr); } calcNormal(); calcBB(); } std::ostream &operator<<(std::ostream &stream, const Triangle t) { stream << "T: " << t.p[0] << " " << t.p[1] << " " << t.p[2] << "n=" << t.n ; return stream; } } // end namespace // end file triangle.cpp