|
|
@ -112,7 +112,7 @@ double SurfaceAreaCalculator::calculate(Func&& func, int gauss_order) const |
|
|
|
// 检查区间中点是否有效
|
|
|
|
double mid_v = (a + b) / 2.0; |
|
|
|
if (IsPointInsideself(u, mid_v, self.outerEdges, self.innerEdges, self.Umin, self.Umax, self.Vmin, self.Vmax)) { |
|
|
|
v_integral += gauss_integrate_1D(a, b, v_integrand, gauss_order); |
|
|
|
v_integral += integrate_1D(a, b, v_integrand, gauss_order); |
|
|
|
} else { |
|
|
|
std::cout << "uv out of domain: (" << u << "," << mid_v << ")" << std::endl; |
|
|
|
} |
|
|
@ -133,9 +133,7 @@ double SurfaceAreaCalculator::calculate(Func&& func, int gauss_order) const |
|
|
|
|
|
|
|
if (!v_intersections.empty()) { // 确保该u区间有有效区域
|
|
|
|
|
|
|
|
double integralp = gauss_integrate_1D(a, b, u_integrand, gauss_order); |
|
|
|
integral += integralp; |
|
|
|
std::cout << "integral " << i << ": " << integralp << std::endl; |
|
|
|
integral += integrate_1D(a, b, u_integrand, gauss_order, is_u_near_singularity(mid_u)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -208,10 +206,10 @@ bool is_point_inside_domain(double u, double v) |
|
|
|
uint32_t vertex_idx2 = m_uv_plane.chains.index_group[element_idx + 1]; |
|
|
|
auto v1 = m_uv_plane.chain_vertices[vertex_idx1], v2 = m_uv_plane.chain_vertices[vertex_idx2]; |
|
|
|
if ((v1.x() <= u && v2.x() > u) || (v2.x() < u && v1.x() >= u)) { |
|
|
|
|
|
|
|
double v_intersected = v1.y() + (v2.y() - v1.y()) * (u_val - v1.x()) / (v2.x() - v1.x()); |
|
|
|
if (v_interdected - v >= 1e-6) { intersection_count++; } |
|
|
|
else if (std::abs(v_intersected - v) < 1e-6) { |
|
|
|
if (v_interdected - v >= 1e-6) { |
|
|
|
intersection_count++; |
|
|
|
} else if (std::abs(v_intersected - v) < 1e-6) { |
|
|
|
auto curve_evaluator = m_surface.fetch_curve_constraint_evaluator(u); |
|
|
|
auto solver_evaluator = m_surface.fetch_solver_evaluator(); |
|
|
|
auto target_function = [&](double v) -> equation_intermediate_t { |
|
|
@ -219,9 +217,7 @@ bool is_point_inside_domain(double u, double v) |
|
|
|
return solver_evaluator(std::move(temp_res)); |
|
|
|
}; |
|
|
|
double v_solution = newton_method(target_function, v_initial); |
|
|
|
if (std::abs(v_solution - v) > 0) { |
|
|
|
intersection_count++; |
|
|
|
} |
|
|
|
if (std::abs(v_solution - v) > 0) { intersection_count++; } |
|
|
|
} |
|
|
|
} |
|
|
|
/*
|
|
|
@ -232,6 +228,19 @@ bool is_point_inside_domain(double u, double v) |
|
|
|
return intersection_count % 2 == 1; // in domain
|
|
|
|
} |
|
|
|
|
|
|
|
bool is_u_near_singularity(double u, double tol = 1e-6) |
|
|
|
{ |
|
|
|
for (auto idx : m_uv_plane.singularity_vertices) { |
|
|
|
double singular_u = m_uv_plane.chain_vertices[idx].x(); |
|
|
|
if (std::abs(u - singular_u) < tol) { return true; } |
|
|
|
} |
|
|
|
// 可扩展:判断是否靠近极点、极性顶点等
|
|
|
|
for (auto idx : m_uv_plane.polar_vertices) { |
|
|
|
double polar_u = m_uv_plane.chain_vertices[idx].x(); |
|
|
|
if (std::abs(u - polar_u) < tol) { return true; } |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
void SurfaceAreaCalculator::sort_and_unique_with_tol(std::vector<double>& vec, double epsilon) |
|
|
|
{ |
|
|
|