| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -2,6 +2,7 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <algorithm/glue_algorithm.hpp> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "Eigen/Core" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "internal_primitive_desc.hpp" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static inline auto manually_projection(const raw_vector3d_t                    &point, | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -30,18 +31,20 @@ namespace internal | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void polyline::build_as_axis(const polyline_descriptor_t                                         &desc, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             const raw_vector3d_t                                                &profile_ref_normal, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             Eigen::Transform<double, 3, Eigen::AffineCompact, Eigen::DontAlign> &axis_to_world, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             aabb_t<>                                                            &aabb) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             aabb_t<>                                                            &aabb, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             const raw_vector3d_t                                                &anchor_point) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    auto &matrix_handle = axis_to_world.matrix(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(desc.reference_normal, matrix_handle.col(1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(1).normalize(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(profile_ref_normal, matrix_handle.col(2)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(profile_ref_normal, matrix_handle.col(0)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(0).normalize(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(desc.reference_normal, matrix_handle.col(2)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(2).normalize(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(0) = matrix_handle.col(1).cross(matrix_handle.col(2)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(desc.points[0], matrix_handle.col(3)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(1) = matrix_handle.col(2).cross(matrix_handle.col(0)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // vec3d_conversion(desc.points[0], matrix_handle.col(3));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(anchor_point, matrix_handle.col(3)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    aabb_t<2> profile_aabb; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    build_as_profile(desc, matrix_handle.col(2), matrix_handle.col(0), matrix_handle.col(3), profile_aabb); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    build_as_profile(desc, matrix_handle.col(0), matrix_handle.col(1), matrix_handle.col(3), profile_aabb); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const auto &profile_aabb_min = profile_aabb.min(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const auto &profile_aabb_max = profile_aabb.max(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    aabb                         = { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -54,18 +57,20 @@ void polyline::build_as_axis(const polyline_descriptor_t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void polyline::build_as_axis(polyline_descriptor_t                                              &&desc, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             const raw_vector3d_t                                                &profile_ref_normal, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             Eigen::Transform<double, 3, Eigen::AffineCompact, Eigen::DontAlign> &axis_to_world, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             aabb_t<>                                                            &aabb) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             aabb_t<>                                                            &aabb, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             const raw_vector3d_t                                                &anchor_point) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    auto &matrix_handle = axis_to_world.matrix(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(std::move(desc.reference_normal), matrix_handle.col(1)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(1).normalize(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(profile_ref_normal, matrix_handle.col(2)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(profile_ref_normal, matrix_handle.col(0)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(0).normalize(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(std::move(desc.reference_normal), matrix_handle.col(2)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(2).normalize(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(0) = matrix_handle.col(1).cross(matrix_handle.col(2)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(desc.points[0], matrix_handle.col(3)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    matrix_handle.col(1) = matrix_handle.col(2).cross(matrix_handle.col(0)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // vec3d_conversion(desc.points[0], matrix_handle.col(3));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    vec3d_conversion(anchor_point, matrix_handle.col(3)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    aabb_t<2> profile_aabb; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    build_as_profile(std::move(desc), matrix_handle.col(2), matrix_handle.col(0), matrix_handle.col(3), profile_aabb); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    build_as_profile(std::move(desc), matrix_handle.col(0), matrix_handle.col(1), matrix_handle.col(3), profile_aabb); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const auto &profile_aabb_min = profile_aabb.min(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const auto &profile_aabb_max = profile_aabb.max(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    aabb                         = { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -105,6 +110,10 @@ void polyline::build_as_profile(const polyline_descriptor_t             &desc, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                  }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // i.e. iff close curve, deduce loop to simple segements by copying the first vertex to the end
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Eigen::Vector3d proj_x_dir_tmp  = proj_x_dir; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Eigen::Vector3d proj_y_dir_tmp  = proj_y_dir; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Eigen::Vector3d proj_origin_tmp = proj_origin; // for debug
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this->vertices.resize(this->start_indices.back() + 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this->start_indices.pop_back(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    circle_start_indices.shrink_to_fit(); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -136,26 +145,27 @@ void polyline::build_as_profile(const polyline_descriptor_t             &desc, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto &bulge       = desc.bulges[index]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto &theta       = this->thetas[index]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto &a           = this->vertices[start_index]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto &b           = this->vertices[start_index + 3]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto       &c           = this->vertices[start_index + 1]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto       &d           = this->vertices[start_index + 2]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto  half_vec_ab = 0.5 * (a + b); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto                 &a             = this->vertices[start_index]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto                 &b             = this->vertices[start_index + 3]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto                       &c             = this->vertices[start_index + 1]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto                       &d             = this->vertices[start_index + 2]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto                  center_vec_ab = 0.5 * (a + b); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto                  half_vec_ab   = b - center_vec_ab; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Eigen::Matrix<double, 2, 1> temp          = center_vec_ab; // for debug
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (theta == PI) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            c = std::move(half_vec_ab); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            c = std::move(center_vec_ab); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // NOTE: bulge = tan(theta/4), so we can directly calculate tan(theta/2)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // and no more operations are needed for identifying the circle center
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // since all direction info is already included in the sign & magnitude of bulge
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const auto inv_tan_half_theta = (1 - bulge * bulge) / (2 * bulge); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            c                             = half_vec_ab + inv_tan_half_theta * Eigen::Vector2d{half_vec_ab[1], -half_vec_ab[0]}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            c = center_vec_ab + inv_tan_half_theta * Eigen::Vector2d{half_vec_ab[1], -half_vec_ab[0]}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto vec_ca = a - c; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (bulge > 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            d = c + Eigen::Vector2d{vec_ca[1], -vec_ca[0]}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        else | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            d = c + Eigen::Vector2d{-vec_ca[1], vec_ca[0]}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        aabb.extend(c); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        aabb.extend(d); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -222,19 +232,21 @@ void polyline::build_as_profile(polyline_descriptor_t                  &&desc, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto &bulge       = desc.bulges[index]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto &theta       = this->thetas[index]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto &a           = this->vertices[start_index]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto &b           = this->vertices[start_index + 3]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto       &c           = this->vertices[start_index + 1]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto       &d           = this->vertices[start_index + 2]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto  half_vec_ab = 0.5 * (a + b); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto                 &a             = this->vertices[start_index]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto                 &b             = this->vertices[start_index + 3]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto                       &c             = this->vertices[start_index + 1]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto                       &d             = this->vertices[start_index + 2]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto                  center_vec_ab = 0.5 * (a + b); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto                  half_vec_ab   = b - center_vec_ab; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Eigen::Matrix<double, 2, 1> temp          = center_vec_ab; // for debug
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (theta == PI) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            c = std::move(half_vec_ab); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            c = std::move(center_vec_ab); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // NOTE: bulge = tan(theta/4), so we can directly calculate tan(theta/2)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // and no more operations are needed for identifying the circle center
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // since all direction info is already included in the sign & magnitude of bulge
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const auto inv_tan_half_theta = (1 - bulge * bulge) / (2 * bulge); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            c                             = half_vec_ab + inv_tan_half_theta * Eigen::Vector2d{half_vec_ab[1], -half_vec_ab[0]}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            c = center_vec_ab + inv_tan_half_theta * Eigen::Vector2d{half_vec_ab[1], -half_vec_ab[0]}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto vec_ca = a - c; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (bulge > 0) | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -274,11 +286,11 @@ void polyline::build_as_profile(polyline_descriptor_t                  &&desc, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (this->thetas[n] <= EPSILON) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // HINT: assume the plane normal (ref_normal) to be {0, 0, 1}, then the normal should be this
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto temp = (*(iter + 1) - *iter).normalized(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return {temp.y(), -temp.x()}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return Eigen::Vector2d{-temp.y(), temp.x()}.normalized(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto alpha = std::cos(t * this->thetas[n]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto beta  = std::sin(t * this->thetas[n]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return (alpha + beta) * *(iter + 1) - alpha * *iter - beta * *(iter + 2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return ((alpha + beta) * *(iter + 1) - alpha * *iter - beta * *(iter + 2)).normalized(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -329,7 +341,8 @@ void polyline::build_as_profile(polyline_descriptor_t                  &&desc, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto p_vec_norm    = p_vec.norm(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto r             = base_vec1.norm(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto dis_on_plane  = p_vec_norm - r; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto closest_point = p_vec / p_vec_norm * r + *(iter + 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto       closest_point = *iter; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (p_vec_norm >= EPSILON) { closest_point = p_vec / p_vec_norm * r + *(iter + 1); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            {closest_point.x(), closest_point.y(), 0}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            phi / theta, | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -338,6 +351,7 @@ void polyline::build_as_profile(polyline_descriptor_t                  &&desc, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<comparable_closest_param_t> closest_params(this->thetas.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const Eigen::Vector3d                   pTmp = p; // for debugging
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    algorithm::transform(counting_iterator<size_t>(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         counting_iterator<size_t>(this->thetas.size()), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         closest_params.begin(), | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -368,10 +382,18 @@ void polyline::build_as_profile(polyline_descriptor_t                  &&desc, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                     dist | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                 }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto back = this->vertices.back(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (*vertices.begin() != back) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            closest_params.emplace_back(comparable_closest_param_t{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                {back.x(), back.y(), 0}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                static_cast<double>(thetas.size()), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::sqrt((p.topRows<2>() - back).squaredNorm() + p[2] * p[2]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const auto iter_ = algorithm::min_element(closest_params.begin(), closest_params.end()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            line_closest_param_t{std::move(iter->point), iter->t, false}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            iter->dist * iter->dist_sign | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            line_closest_param_t{std::move(iter_->point), iter_->t, false}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            iter_->dist * iter_->dist_sign | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |