/*-------------------------------------------------------------------------* * Coord * * * * Compute the two coordinates (x1,x2) corresponding to a point in the * * spherical triangle. This is the inverse of "Chart". * * * *-------------------------------------------------------------------------*/ Vec2 SphericalTriangle::Coord( const Vec3 &P1 ) const { Vec3 P = Unit( P1 ); // Compute the new C vertex, which lies on the arc defined by B-P // and the arc defined by A-C. Vec3 C_new = Unit( ( B() ^ P ) ^ ( C() ^ A() ) ); // Adjust the sign of C_new. Make sure it's on the arc between A and C. if( C_new * ( A() + C() ) < 0.0 ) C_new = -C_new; // Compute x1, the area of the sub-triangle over the original area. float cos_beta = CosDihedralAngle( A(), B(), C_new ); float cos_gamma = CosDihedralAngle( A(), C_new , B() ); float sub_area = Alpha() + acos( cos_beta ) + acos( cos_gamma ) - Pi; float x1 = sub_area / SolidAngle(); // Now compute the second coordinate using the new C vertex. float z = P * B(); float x2 = ( 1.0 - z ) / ( 1.0 - C_new * B() ); if( x1 < 0.0 ) x1 = 0.0; if( x1 > 1.0 ) x1 = 1.0; if( x2 < 0.0 ) x2 = 0.0; if( x2 > 1.0 ) x2 = 1.0; return Vec2( x1, x2 ); }
/*-------------------------------------------------------------------------* * Init * * * * Construct the spherical triange from three vertices. Assume that the * * sphere is centered at the origin. The vectors A, B, and C need not * * be normalized. * * * *-------------------------------------------------------------------------*/ void SphericalTriangle::Init( const Vector3d &A0, const Vector3d &B0, const Vector3d &C0 ) { // Normalize the three vectors -- these are the vertices. A_ = Unit( A0 ) ; B_ = Unit( B0 ) ; C_ = Unit( C0 ) ; // Compute and save the cosines of the edge lengths. cos_a = B_ * C_; cos_b = A_ * C_; cos_c = A_ * B_; // Compute and save the edge lengths. a_ = ArcCos( cos_a ); b_ = ArcCos( cos_b ); c_ = ArcCos( cos_c ); // Compute the cosines of the internal (i.e. dihedral) angles. cos_alpha = CosDihedralAngle( C_, A_, B_ ); cos_beta = CosDihedralAngle( A_, B_, C_ ); cos_gamma = CosDihedralAngle( A_, C_, B_ ); // Compute the (dihedral) angles. alpha = ArcCos( cos_alpha ); beta = ArcCos( cos_beta ); gamma = ArcCos( cos_gamma ); // Compute the solid angle of the spherical triangle. area = alpha + beta + gamma - M_PI ; // Compute the orientation of the triangle. double mix = A_ * ( B_ ^ C_ ) ; orient = (mix > 0) ? 1 : ((mix < 0) ? -1 : 0) ; // Initialize three variables that are used for sampling the triangle. U = Unit( C_ / A_ ); // In plane of AC orthogonal to A. sin_alpha = sin( alpha ); product = sin_alpha * cos_c; }