double VectorType::angleBetweenVectors(VectorType secondVector) { //cos(theta) = (u . v) / (|u|*|v| double theta = acos(dotProduct(secondVector) / (vectorLength() * secondVector.vectorLength()) ); return theta; }
double Common::intersectFace(RayType inputRay, FaceType inputFace) { //cout <<"Attempting a face intersection" << endl; //find the location of the intersection between a ray and a triangle face. //return the distance to the intersection. //return -1 if there is no intersection. //determine plane equation. //Let the vector e1 be defined along the edge from p0 to p1 //Let the vector e2 be defined along the edge from p0 to p2 //Let the vector n be defined by the cross product of e1 and e2 //That's annoying, now these vector names are 1 based, and points are 0 based. //WTF? Consistency? Nah. double denominator = (inputFace.A * inputRay.direction.x) + (inputFace.B * inputRay.direction.y) + (inputFace.C * inputRay.direction.z); //cout << "den:" << denominator << endl; double numerator = 0 - ((inputFace.A * inputRay.origin.x) + (inputFace.B * inputRay.origin.y) + (inputFace.C * inputRay.origin.z) + inputFace.D); if(thresholdEquals(denominator,0)) { //if the denominator is zero, the ray grazes the plane, never intersects. //cout << "Demonimator is 0." << endl; return -1; } else { double t = numerator / denominator; if(thresholdEquals(t,0)) { //cout << "Intersect at t=0" << endl; //if t is 0, the ray intersects at the ray's origin. That doesn't count. return -1; } else if (t < 0) { //cout << "Negative T" << endl; //object is behind the eye. No intersection. return -1; } else { //cout << "Plane intersection found. Will determine if it is a triangle intersection." << endl; //We have to check if the intersection point is actually inside the triangle. //Calculate barycentric coordinates. // The area of an arbitrary triangle can also be //computed as half of the length of the cross //product of the vectors describing any two of //its sides: //wait, N is a normal vector. Already have that. PointType intersectionPoint; //px = (x0 + t⋅xd) //py = (y0 + t⋅yd) //pz = (z0 + t⋅zd) intersectionPoint.x = inputRay.origin.x + t * inputRay.direction.x; intersectionPoint.y = inputRay.origin.y + t * inputRay.direction.y; intersectionPoint.z = inputRay.origin.z + t * inputRay.direction.z; VectorType n = inputFace.e1.crossProduct(inputFace.e2);//.normalize(); double totalArea = n.vectorLength() / 2; VectorType centerV1 = vectorFromHereToPoint(intersectionPoint, inputFace.v1); VectorType centerV2 = vectorFromHereToPoint(intersectionPoint, inputFace.v2); VectorType centerV3 = vectorFromHereToPoint(intersectionPoint, inputFace.v3); double areaA = centerV1 .crossProduct(centerV2).vectorLength()/2; double areaB = centerV1 .crossProduct(centerV3).vectorLength()/2; double areaC = centerV2 .crossProduct(centerV3).vectorLength()/2; double alpha = areaA / totalArea; double beta = areaB / totalArea; double gamma = areaC / totalArea; //cout <<"sumArea:" << (areaA + areaB + areaC) << endl; //cout <<"sumGreek:" << (alpha + beta + gamma) << endl; //cout <<"totalArea:" << totalArea << endl; //I know that the point is outside the traingle if any of alpha,beta, or gamma //is < 0 or > 1 if(alpha > 1 || beta > 1 || gamma > 1 || alpha < 0 || beta < 0 || gamma < 0) { //cout << "outside triangle" << endl; return -1; } //if (alpha + beta + gamma == 1) { // point is in triangle if(thresholdEquals((alpha+ beta + gamma),1)) { //cout <<"Triangle intersection found." << endl; return t; } } } //I don't think we should get here. But if there's a problem, assume no intersect. return -1; }