int main() { MagneticField * field = new ConstMagneticField; { // going back and forth gtp2 should be identical to gpt1.... GlobalPoint gp1(1,0,0); GlobalVector gv1(1,1,-1); GlobalTrajectoryParameters gtp1(gp1,gv1,1,field); double bz = field->inTesla(gp1).z() * 2.99792458e-3; GlobalPoint np(0.504471, -0.498494, 0.497014); GlobalTrajectoryParameters gtpN = ClosestApproachInRPhi::newTrajectory(np,gtp1,bz); GlobalTrajectoryParameters gtp2 = ClosestApproachInRPhi::newTrajectory(gp1,gtpN,bz); std::cout << gtp1 << std::endl; std::cout << gtpN << std::endl; std::cout << gtp2 << std::endl; std::cout << std::endl; } { std::cout <<"opposite sign, same direction, same origin: the two circles are tangent to each other at gp1\n" << std::endl; GlobalPoint gp1(0,0,0); GlobalVector gv1(1,1,1); GlobalTrajectoryParameters gtp1(gp1,gv1,1,field); GlobalPoint gp2(0,0,0); GlobalVector gv2(1,1,-1); GlobalTrajectoryParameters gtp2(gp2,gv2,-1,field); compute(gtp1,gtp2); std::cout << std::endl; } { std::cout <<" not crossing: the pcas are on the line connecting the two centers\n" <<"the momenta at the respective pcas shall be parallel as they are perpendicular to the same line\n" <<"(the one connecting the two centers)\n" << std::endl; GlobalPoint gp1(-1,0,0); GlobalVector gv1(1,1,1); GlobalTrajectoryParameters gtp1(gp1,gv1,-1,field); GlobalPoint gp2(1,0,0); GlobalVector gv2(1,1,-1); GlobalTrajectoryParameters gtp2(gp2,gv2,1,field); compute(gtp1,gtp2); std::cout << std::endl; } { std::cout <<"crossing (only opposite changes w.r.t. previous)\n" << std::endl; GlobalPoint gp1(-1,0,0); GlobalVector gv1(1,1,1); GlobalTrajectoryParameters gtp1(gp1,gv1,1,field); GlobalPoint gp2(1,0,0); GlobalVector gv2(1,1,-1); GlobalTrajectoryParameters gtp2(gp2,gv2,-1,field); compute(gtp1,gtp2); std::cout << std::endl; } { std::cout <<"crossing\n" << std::endl; GlobalPoint gp1(-1,0,0); GlobalVector gv1(1,1,1); GlobalTrajectoryParameters gtp1(gp1,gv1,-1,field); GlobalPoint gp2(1,0,0); GlobalVector gv2(-1,1,-1); GlobalTrajectoryParameters gtp2(gp2,gv2,1,field); compute(gtp1,gtp2); std::cout << std::endl; } return 0; }
void TessellateTri( std::vector< bspVertex_t >& outVerts, std::vector< triangle_t >& outIndices, float amount, float normalOffsetScale, const bspVertex_t& a, const bspVertex_t& b, const bspVertex_t& c ) { auto LPassedC = [ &c ]( const glm::vec3& point, const glm::vec3& sig ) -> bool { return ( glm::sign( c.position - point ) != sig ); }; float step = 1.0f / amount; // Use these as a basis for when either the a or b traversal vectors // have passed vertex c glm::vec3 aSig = glm::sign( c.position - a.position ); glm::vec3 bSig = glm::sign( c.position - b.position ); std::unique_ptr< baryCoordSystem_t > triCoordSys( new baryCoordSystem_t( a.position, b.position, c.position ) ); bspVertex_t bToC( ( c - b ) * step ); bspVertex_t aToC( ( c - a ) * step ); bspVertex_t aToBStep( ( b - a ) * step ); std::vector< triangle_t > curStrip; // Points which walk along the edges bspVertex_t a2( a ); bspVertex_t b2( b ); while ( true ) { if ( glm::any( glm::isnan( a2.position ) ) || glm::any( glm::isnan( b2.position ) ) ) break; // If either of these are set to true, then we'll have // triangles which exist outside of the parent tri. if ( LPassedC( a2.position, aSig ) || LPassedC( b2.position, bSig ) ) break; if ( a2.position == c.position || b2.position == c.position ) break; // Path trace the edges of our triangle defined by vertices a2 and b2 bspVertex_t aToB( b2 - a2 ); float walk = 0.0f; float walkLength = 0.0f; float walkStep = glm::length( aToBStep.position ) / glm::length( aToB.position ); float endLength = glm::length( aToB.position ); while ( walkLength < endLength ) { bspVertex_t gv1( a2 + aToB * walk ); bspVertex_t gv2( gv1 + aToBStep ); bspVertex_t gv3( gv1 + aToC ); bspVertex_t gv4( gv3 + aToBStep ); gv1.position += gv1.normal * normalOffsetScale; gv2.position += gv2.normal * normalOffsetScale; gv3.position += gv3.normal * normalOffsetScale; gv4.position += gv4.normal * normalOffsetScale; size_t numVertices; triangle_t t1; // There should be a reasonable workaround for this; maybe scale // the vertices or something like that. if ( !triCoordSys->IsInTri( gv3.position ) || !triCoordSys->IsInTri( gv2.position ) ) goto end_iteration; numVertices = outVerts.size(); gv1.color = glm::u8vec4( 255 ); gv2.color = glm::u8vec4( 255 ); gv3.color = glm::u8vec4( 255 ); { auto v1Iter = std::find( outVerts.begin(), outVerts.end(), gv1 ); if ( v1Iter == outVerts.end() ) { outVerts.push_back( gv1 ); t1.indices[ 0 ] = numVertices++; } else { t1.indices[ 0 ] = v1Iter - outVerts.begin(); } auto v2Iter = std::find( outVerts.begin(), outVerts.end(), gv2 ); if ( v2Iter == outVerts.end() ) { outVerts.push_back( gv2 ); t1.indices[ 1 ] = numVertices++; } else { t1.indices[ 1 ] = v2Iter - outVerts.begin(); } auto v3Iter = std::find( outVerts.begin(), outVerts.end(), gv3 ); if ( v3Iter == outVerts.end() ) { outVerts.push_back( gv3 ); t1.indices[ 2 ] = numVertices++; } else { t1.indices[ 2 ] = v3Iter - outVerts.begin(); } } curStrip.push_back( t1 ); // Attempt a second triangle, providing v4 // is within the bounds if ( !triCoordSys->IsInTri( gv4.position ) ) goto end_iteration; { auto v4Iter = std::find( outVerts.begin(), outVerts.end(), gv4 ); triangle_t t2 = { { t1.indices[ 2 ], t1.indices[ 1 ], 0 } }; if ( v4Iter == outVerts.end() ) { outVerts.push_back( gv4 ); t2.indices[ 2 ] = numVertices; } else { t2.indices[ 2 ] = v4Iter - outVerts.begin(); } curStrip.push_back( t2 ); } end_iteration: walk += walkStep; walkLength = glm::length( aToB.position * walk ); } outIndices.insert( outIndices.end(), curStrip.begin(), curStrip.end() ); curStrip.clear(); a2 += aToC; b2 += bToC; } }