#include "CreateHelix.hh" ////////////////////////////////////////////////////////////////////! /* Main function to create the helix. This calls all the previous and returns a G4TessellatedSolid */ // Create a triangulated helix using G4TessellatedSolid G4TessellatedSolid* CreateHelix(G4String name, TVector3 center, double size, double runningangle, double length, int steps, double extrusion) { // Create a new G4TessellatedSolid G4TessellatedSolid* helix = new G4TessellatedSolid(name); // Calculate number of turns double turns = AngleToTurns(runningangle, length, center.x()); // Create base starting from 'center' and 'size'; triangulate it and add it to the helix std::vector base = CreateBase(center, size); // Tilt to metch the running angle base = Tilt(base, center, runningangle); // If no extrusion just cap it, otherwise use the AddExtrusion function if(extrusion == 0) { std::vector> triang_base = TriangulateBase(base); MyADD(helix,triang_base); } else{ std::vector> triang_base_extrusion = AddExtrusion(base, extrusion); MyADD(helix,triang_base_extrusion); } std::vector first=base; std::vector second; // Create the side: duplicate and move the base; triangulate the side; add to helix and repeat. for(int i=0; i> triang_side = TriangulateSide(first,second); MyADD(helix,triang_side); first = second; } // The last vertex loop is use to cap the helix (NB it needs to be flipped) std::vector cap = first; cap = FlipLoop(cap); // If no extrusion just cap it, otherwise use the AddExtrusion function if(extrusion==0){ std::vector> triang_cap = TriangulateBase(cap); MyADD(helix,triang_cap); } else{ std::vector> triang_cap_extrusion = AddExtrusion(cap, extrusion); MyADD(helix,triang_cap_extrusion); } // Close the solid to ensure correct surface normals helix->SetSolidClosed(true); return helix; } ////////////////////////////////////////////////////////////////////! /* Auxiliary functions to create the helix shape */ // From the angle to the number of turns double AngleToTurns(double angle, double length, double R){ double turns = tan(angle)*length/(2*M_PI*R); return turns; } // Given the center and the size of the fiber creates a squared base // Change this to move from *squared* helix to other shape. std::vector CreateBase(TVector3 center, double size){ std::vector base = { center + TVector3(-size*0.5, -size*0.5, 0), center + TVector3(size*0.5, -size*0.5, 0), center + TVector3(size*0.5, size*0.5, 0), center + TVector3(-size*0.5, size*0.5, 0),}; return base; } // Evaluate the path using the length t. // Change this to move from *helix* to *other extrusion shape* TVector3 Path(double t, double turns, TVector3 center, double length){ double R = center.x(); double x,y,z; x = R * cos(t/length* 2*M_PI *turns); y = R * sin(t/length* 2*M_PI *turns); z = t; TVector3 offset = TVector3(x,y,z); return offset; } // Function to flip the closing cap (to fix normals) std::vector FlipLoop(std::vector cap){ std::vector fliploop; fliploop.push_back(cap[1]); fliploop.push_back(cap[0]); fliploop.push_back(cap[3]); fliploop.push_back(cap[2]); return fliploop; } // Function to create the triangulation for the endcaps std::vector> TriangulateBase(std::vectorv){ std::vector> faces; faces.push_back(std::make_tuple(v[3],v[1],v[0])); faces.push_back(std::make_tuple(v[3],v[2],v[1])); return faces; } // Function to create the triangulation given two verteces loops to be bridged std::vector> TriangulateSide(std::vectorv, std::vectoru){ std::vector> faces; for(int i = 0; i Tilt(std::vectorv, TVector3 center, double angle){ double x,y,z; std::vector u; for(int i = 0; i> triang){ TVector3 a,b,c; for(auto i : triang){ a = std::get<0>(i); b = std::get<1>(i); c = std::get<2>(i); G4ThreeVector va(a.x(), a.y(), a.z()); G4ThreeVector vb(b.x(), b.y(), b.z()); G4ThreeVector vc(c.x(), c.y(), c.z()); helix->AddFacet(new G4TriangularFacet(va, vb, vc, ABSOLUTE)); } } // Given a lopp create a second loop along the path. These two are going to be bridged with triangulation std::vector Transform(std::vectorv, double turns, int steps, TVector3 center, double length){ std::vector u; double angle_step = turns/steps*2*M_PI; double length_step = length/steps; for(int i = 0; i> AddExtrusion(std::vector base, double extrusion){ std::vector> faces; std::vector extrusion_loop; TVector3 direction =((base[2]-base[0])).Cross(base[1]-base[0]); for(int i = 0; i> cap = TriangulateBase(extrusion_loop); base = FlipLoop(base); extrusion_loop = FlipLoop(extrusion_loop); faces = TriangulateSide(base, extrusion_loop); faces.insert(faces.end(), cap.begin(), cap.end()); return faces; }