@ccpc/math 0.1.0 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +226 -0
- package/package.json +19 -37
- package/types/algorithm/bool_operate/bool2d/bool2d.d.ts +22 -0
- package/types/algorithm/bool_operate/bool2d/difference.d.ts +9 -0
- package/types/algorithm/bool_operate/bool2d/intersect.d.ts +9 -0
- package/types/algorithm/bool_operate/bool2d/split.d.ts +3 -0
- package/types/algorithm/bool_operate/bool2d/union.d.ts +9 -0
- package/types/algorithm/bool_operate/bool2d/utils.d.ts +40 -0
- package/types/algorithm/bool_operate/bool_operate_clipper.d.ts +18 -0
- package/types/algorithm/bool_operate/polycurve_polygon_bool.d.ts +13 -0
- package/types/algorithm/bool_operate_2d.d.ts +67 -0
- package/types/algorithm/calc_d.d.ts +85 -0
- package/types/algorithm/calc_offset.d.ts +70 -0
- package/types/algorithm/calc_overlap.d.ts +56 -0
- package/types/algorithm/calc_project.d.ts +29 -0
- package/types/algorithm/calc_x.d.ts +215 -0
- package/types/algorithm/calculate_util/geometry_subdevide_infos.d.ts +73 -0
- package/types/algorithm/calculate_util/iterative_method.d.ts +30 -0
- package/types/algorithm/discrete/discrete_curve.d.ts +31 -0
- package/types/algorithm/discrete/discrete_refiner.d.ts +35 -0
- package/types/algorithm/discrete/discrete_surface.d.ts +74 -0
- package/types/algorithm/discrete/discrete_topology.d.ts +32 -0
- package/types/algorithm/discrete/discrete_util.d.ts +96 -0
- package/types/algorithm/discrete/grid_discrete_data.d.ts +58 -0
- package/types/algorithm/discrete/libtess.d.ts +12 -0
- package/types/algorithm/discrete/uniform_grid_discrete.d.ts +3 -0
- package/types/algorithm/distance/base_calc_distance/curves_distance_util.d.ts +20 -0
- package/types/algorithm/distance/base_calc_distance/define_of_calculate_distance.d.ts +12 -0
- package/types/algorithm/distance/curve2ds_distance/arc2s_distance.d.ts +17 -0
- package/types/algorithm/distance/curve2ds_distance/line2d_to_arc2d_distance.d.ts +17 -0
- package/types/algorithm/distance/curve2ds_distance/line2s_distance.d.ts +15 -0
- package/types/algorithm/distance/curve2s_distance.d.ts +15 -0
- package/types/algorithm/distance/curve3ds_distance/line3d_to_line3d_distance_paramed.d.ts +12 -0
- package/types/algorithm/distance/curve3s_distance.d.ts +31 -0
- package/types/algorithm/distance/pt_to_curve2_signed_distance.d.ts +17 -0
- package/types/algorithm/distance/pt_to_curve3_distance.d.ts +25 -0
- package/types/algorithm/distance/pt_to_curve_distance_info.d.ts +12 -0
- package/types/algorithm/distance/pt_to_surface_distance.d.ts +17 -0
- package/types/algorithm/distance/pts_to_curves_distance.d.ts +13 -0
- package/types/algorithm/distance/pts_to_pts_distance.d.ts +7 -0
- package/types/algorithm/geometry_merge.d.ts +22 -0
- package/types/algorithm/index.d.ts +32 -0
- package/types/algorithm/intersect/box_cut_line.d.ts +6 -0
- package/types/algorithm/intersect/curve_self_x.d.ts +13 -0
- package/types/algorithm/intersect/curve_surface_x.d.ts +34 -0
- package/types/algorithm/intersect/curve_surface_x_util.d.ts +32 -0
- package/types/algorithm/intersect/curves_x/circulars_x.d.ts +35 -0
- package/types/algorithm/intersect/curves_x/linear_circular_x.d.ts +40 -0
- package/types/algorithm/intersect/curves_x/lines_x.d.ts +17 -0
- package/types/algorithm/intersect/curves_x/lines_x_util.d.ts +4 -0
- package/types/algorithm/intersect/curves_x.d.ts +26 -0
- package/types/algorithm/intersect/curves_x_util.d.ts +35 -0
- package/types/algorithm/intersect/intersect_info_util.d.ts +9 -0
- package/types/algorithm/intersect/surface_self_x.d.ts +8 -0
- package/types/algorithm/intersect/surfaces_x.d.ts +53 -0
- package/types/algorithm/intersect/surfaces_x_complex.d.ts +29 -0
- package/types/algorithm/intersect/surfaces_x_special.d.ts +16 -0
- package/types/algorithm/intersect/surfaces_x_util.d.ts +41 -0
- package/types/algorithm/intersect/x_info.d.ts +65 -0
- package/types/algorithm/loop_property/loop-area.d.ts +49 -0
- package/types/algorithm/loop_property/loop-centroid.d.ts +40 -0
- package/types/algorithm/merge_geometry/halfplane.d.ts +24 -0
- package/types/algorithm/merge_geometry/merge_curve.d.ts +14 -0
- package/types/algorithm/merge_geometry/merge_point.d.ts +18 -0
- package/types/algorithm/mesh/clip_mesh.d.ts +27 -0
- package/types/algorithm/mesh/extrude_clip.d.ts +236 -0
- package/types/algorithm/mesh/mesh_assist.d.ts +21 -0
- package/types/algorithm/mesh/mesh_contour.d.ts +26 -0
- package/types/algorithm/mesh/mesh_util.d.ts +115 -0
- package/types/algorithm/offset/loop2d_offset.d.ts +22 -0
- package/types/algorithm/offset/polygon_offset.d.ts +27 -0
- package/types/algorithm/overlap/curve_surface_coincide.d.ts +6 -0
- package/types/algorithm/overlap/curves_colinear.d.ts +38 -0
- package/types/algorithm/overlap/curves_merge.d.ts +74 -0
- package/types/algorithm/overlap/curves_overlap.d.ts +34 -0
- package/types/algorithm/overlap/i_overlap.d.ts +9 -0
- package/types/algorithm/overlap/surfaces_coplaner.d.ts +5 -0
- package/types/algorithm/pattern/blocks2Geometry.d.ts +50 -0
- package/types/algorithm/pattern/math.d.ts +42 -0
- package/types/algorithm/pattern/pattern.d.ts +43 -0
- package/types/algorithm/pattern/pattern_util.d.ts +53 -0
- package/types/algorithm/pattern/pave.d.ts +33 -0
- package/types/algorithm/pj/curves_oj.d.ts +19 -0
- package/types/algorithm/pj/curves_pj.d.ts +19 -0
- package/types/algorithm/pj/loops_pj.d.ts +13 -0
- package/types/algorithm/pj/pj_type.d.ts +46 -0
- package/types/algorithm/pj/pt_loop_pj.d.ts +24 -0
- package/types/algorithm/pj/pt_polygon_pj.d.ts +18 -0
- package/types/algorithm/pj/pt_polygon_position_judger.d.ts +11 -0
- package/types/algorithm/position_judge.d.ts +72 -0
- package/types/algorithm/project/curve3d_to_plane_project.d.ts +11 -0
- package/types/algorithm/project/curve_curve_project.d.ts +9 -0
- package/types/algorithm/search_graph/iloops_polygonex.d.ts +28 -0
- package/types/algorithm/search_graph/loop_tree_node.d.ts +30 -0
- package/types/algorithm/search_graph/loops_to_loop_tree_search_graph.d.ts +25 -0
- package/types/algorithm/search_graph/polygon_polygonex.d.ts +13 -0
- package/types/algorithm/search_graph/search_loop2d.d.ts +20 -0
- package/types/algorithm/search_graph/search_polyline.d.ts +11 -0
- package/types/algorithm/search_graph.d.ts +45 -0
- package/types/algorithm/topology_edit.d.ts +10 -0
- package/types/base/box.d.ts +100 -0
- package/types/base/box2.d.ts +17 -0
- package/types/base/box3.d.ts +20 -0
- package/types/base/coord.d.ts +10 -0
- package/types/base/coord2.d.ts +92 -0
- package/types/base/coord3.d.ts +139 -0
- package/types/base/discrete_param.d.ts +28 -0
- package/types/base/euler.d.ts +102 -0
- package/types/base/geo_element.d.ts +54 -0
- package/types/base/interval.d.ts +122 -0
- package/types/base/ivector.d.ts +126 -0
- package/types/base/matrix.d.ts +108 -0
- package/types/base/matrix3.d.ts +118 -0
- package/types/base/matrix4.d.ts +166 -0
- package/types/base/matrix_util.d.ts +5 -0
- package/types/base/period_inverval.d.ts +127 -0
- package/types/base/quaternion.d.ts +39 -0
- package/types/base/tangent_cone.d.ts +11 -0
- package/types/base/tilt_box.d.ts +11 -0
- package/types/base/tol.d.ts +120 -0
- package/types/base/vec.d.ts +46 -0
- package/types/base/vec2.d.ts +146 -0
- package/types/base/vec3.d.ts +158 -0
- package/types/brep-src/algorithm/alg_const.d.ts +23 -0
- package/types/brep-src/algorithm/alg_types.d.ts +47 -0
- package/types/brep-src/algorithm/algorithm_util/base_define.d.ts +7 -0
- package/types/brep-src/algorithm/algorithm_util/body_base_util.d.ts +4 -0
- package/types/brep-src/algorithm/algorithm_util/curve_solid_analysis.d.ts +28 -0
- package/types/brep-src/algorithm/algorithm_util/face_face_analysis.d.ts +39 -0
- package/types/brep-src/algorithm/algorithm_util/search_wire.d.ts +8 -0
- package/types/brep-src/algorithm/body_builder/basic_body_builder.d.ts +15 -0
- package/types/brep-src/algorithm/body_builder/extrude_body.d.ts +23 -0
- package/types/brep-src/algorithm/body_builder/sweep_body.d.ts +37 -0
- package/types/brep-src/algorithm/body_builder.d.ts +36 -0
- package/types/brep-src/algorithm/body_util.d.ts +21 -0
- package/types/brep-src/algorithm/bool_sk/brep_converter.d.ts +11 -0
- package/types/brep-src/algorithm/brep_calc_project.d.ts +50 -0
- package/types/brep-src/algorithm/brep_calc_x.d.ts +34 -0
- package/types/brep-src/algorithm/brep_pj.d.ts +47 -0
- package/types/brep-src/algorithm/index.d.ts +5 -0
- package/types/brep-src/algorithm/intersect/curve_face_overlap.d.ts +10 -0
- package/types/brep-src/algorithm/intersect/face_face_intersect.d.ts +22 -0
- package/types/brep-src/algorithm/intersect/face_faces_intersect.d.ts +15 -0
- package/types/brep-src/algorithm/intersect/line_face_intersect.d.ts +16 -0
- package/types/brep-src/algorithm/podition_judge/body_pj.d.ts +25 -0
- package/types/brep-src/algorithm/podition_judge/extrude_pj.d.ts +28 -0
- package/types/brep-src/algorithm/podition_judge/pt_body_pj.d.ts +32 -0
- package/types/brep-src/algorithm/project/body_project.d.ts +8 -0
- package/types/brep-src/algorithm/project/face_project.d.ts +20 -0
- package/types/brep-src/algorithm/project/face_surface_project.d.ts +8 -0
- package/types/brep-src/algorithm/project/space_project.d.ts +26 -0
- package/types/brep-src/algorithm/project/space_project_simple.d.ts +10 -0
- package/types/brep-src/algorithm/project/view_project.d.ts +25 -0
- package/types/brep-src/algorithm/shell_builder/create_shell_from_curves.d.ts +38 -0
- package/types/brep-src/algorithm/shell_builder.d.ts +25 -0
- package/types/brep-src/algorithm/shell_edit/add_edges/add_edges.d.ts +14 -0
- package/types/brep-src/algorithm/shell_edit/add_edges/add_edges_core.d.ts +11 -0
- package/types/brep-src/algorithm/shell_edit/copy_faces.d.ts +20 -0
- package/types/brep-src/algorithm/shell_edit/delete_faces_edges/delete_edge.d.ts +9 -0
- package/types/brep-src/algorithm/shell_edit/delete_faces_edges/delete_faces_edges.d.ts +17 -0
- package/types/brep-src/algorithm/shell_edit/faces_boolean/faces_boolean.d.ts +19 -0
- package/types/brep-src/algorithm/shell_edit/faces_boolean/faces_shells_boolean.d.ts +13 -0
- package/types/brep-src/algorithm/shell_edit/faces_boolean/octree.d.ts +11 -0
- package/types/brep-src/algorithm/shell_edit/isolate_faces.d.ts +21 -0
- package/types/brep-src/algorithm/shell_edit/merge_connect_faces.d.ts +14 -0
- package/types/brep-src/algorithm/shell_edit/merge_edges.d.ts +8 -0
- package/types/brep-src/algorithm/shell_edit/move_operators/move_edges.d.ts +31 -0
- package/types/brep-src/algorithm/shell_edit/move_operators/move_faces.d.ts +14 -0
- package/types/brep-src/algorithm/shell_edit/operator/dispose_topo.d.ts +2 -0
- package/types/brep-src/algorithm/shell_edit/operator/merge_connect_edge.d.ts +3 -0
- package/types/brep-src/algorithm/shell_edit/operator/merge_connect_face.d.ts +2 -0
- package/types/brep-src/algorithm/shell_edit/operator/merge_overlap_edge.d.ts +3 -0
- package/types/brep-src/algorithm/shell_edit/operator/merge_shell.d.ts +11 -0
- package/types/brep-src/algorithm/shell_edit/operator/merge_vertex.d.ts +2 -0
- package/types/brep-src/algorithm/shell_edit/operator/split_edge.d.ts +4 -0
- package/types/brep-src/algorithm/shell_edit/operator/split_shell.d.ts +6 -0
- package/types/brep-src/algorithm/shell_edit/pull_push_face/pull_push_face.d.ts +18 -0
- package/types/brep-src/algorithm/shell_edit/pull_push_face/pull_push_face_core.d.ts +6 -0
- package/types/brep-src/algorithm/shell_edit/pull_push_face/pull_push_face_preview.d.ts +16 -0
- package/types/brep-src/algorithm/shell_edit/pull_push_face/pull_push_face_preview_core.d.ts +24 -0
- package/types/brep-src/algorithm/shell_edit/roundinng/2d_rounding.d.ts +22 -0
- package/types/brep-src/algorithm/shell_edit/shell_modeling_base.d.ts +10 -0
- package/types/brep-src/algorithm/shell_edit/shell_modeling_result.d.ts +21 -0
- package/types/brep-src/algorithm/shell_edit/smooth/detect_loop_util.d.ts +27 -0
- package/types/brep-src/algorithm/shell_edit/smooth/shell_modeling_util.d.ts +24 -0
- package/types/brep-src/algorithm/shell_edit/smooth/smooth_util.d.ts +22 -0
- package/types/brep-src/algorithm/shell_edit/split_edge.d.ts +10 -0
- package/types/brep-src/algorithm/shell_edit.d.ts +119 -0
- package/types/brep-src/algorithm/shell_valid/base_brep_topo_error.d.ts +176 -0
- package/types/brep-src/algorithm/shell_valid/diagnose_shell.d.ts +14 -0
- package/types/brep-src/brep/brep_body.d.ts +19 -0
- package/types/brep-src/brep/coedge3d.d.ts +83 -0
- package/types/brep-src/brep/edge.d.ts +96 -0
- package/types/brep-src/brep/face.d.ts +150 -0
- package/types/brep-src/brep/shell.d.ts +166 -0
- package/types/brep-src/brep/topo_object.d.ts +40 -0
- package/types/brep-src/brep/vertex.d.ts +48 -0
- package/types/brep-src/brep/wire.d.ts +66 -0
- package/types/brep-src/continuous/continuous_edge.d.ts +17 -0
- package/types/brep-src/continuous/continuous_face.d.ts +10 -0
- package/types/brep-src/continuous/continuous_util.d.ts +60 -0
- package/types/brep-src/continuous/continuous_uv.d.ts +24 -0
- package/types/brep-src/continuous/index.d.ts +4 -0
- package/types/brep-src/index.d.ts +14 -0
- package/types/brep-src/type_define/i_types.d.ts +46 -0
- package/types/brep-src/util/util.d.ts +23 -0
- package/types/conversion/units_conversion.d.ts +14 -0
- package/types/geometry/arc2d.d.ts +249 -0
- package/types/geometry/arc3d.d.ts +204 -0
- package/types/geometry/circle3d.d.ts +92 -0
- package/types/geometry/circular_surface.d.ts +52 -0
- package/types/geometry/coord_based_surface.d.ts +25 -0
- package/types/geometry/curve.d.ts +228 -0
- package/types/geometry/curve2.d.ts +62 -0
- package/types/geometry/curve3d.d.ts +66 -0
- package/types/geometry/cylinder.d.ts +73 -0
- package/types/geometry/discrete_arrow.d.ts +3 -0
- package/types/geometry/extend_curve2.d.ts +75 -0
- package/types/geometry/geometry2d.d.ts +35 -0
- package/types/geometry/geometry3d.d.ts +36 -0
- package/types/geometry/intersect_curve3.d.ts +90 -0
- package/types/geometry/ln2.d.ts +168 -0
- package/types/geometry/ln3.d.ts +152 -0
- package/types/geometry/nurbs_curve2.d.ts +106 -0
- package/types/geometry/nurbs_curve3.d.ts +191 -0
- package/types/geometry/offset_curve2.d.ts +63 -0
- package/types/geometry/offset_curve3.d.ts +97 -0
- package/types/geometry/offset_parameter_mapper.d.ts +72 -0
- package/types/geometry/plane.d.ts +109 -0
- package/types/geometry/polyline.d.ts +12 -0
- package/types/geometry/smooth_poly2.d.ts +78 -0
- package/types/geometry/smooth_poly3.d.ts +85 -0
- package/types/geometry/surface.d.ts +173 -0
- package/types/index.d.ts +78 -0
- package/types/io/obj_parser.d.ts +4 -0
- package/types/io/svgparser.d.ts +22 -0
- package/types/loader/loader.d.ts +23 -0
- package/types/loader/register_geo.d.ts +7 -0
- package/types/math/gauss_integration.d.ts +13 -0
- package/types/math/inv_bilinear.d.ts +33 -0
- package/types/solve_equations/cubic_equation.d.ts +7 -0
- package/types/solve_equations/linear_system.d.ts +6 -0
- package/types/solve_equations/nonlinear_system.d.ts +11 -0
- package/types/solve_equations/plurality.d.ts +9 -0
- package/types/solve_equations/polynomial_equation.d.ts +6 -0
- package/types/solve_equations/quadratic_equation.d.ts +6 -0
- package/types/solve_equations/quartic_equation.d.ts +6 -0
- package/types/solve_equations/solve_equation_util.d.ts +50 -0
- package/types/test_util/loop_generator.d.ts +21 -0
- package/types/topology/evolution_map.d.ts +90 -0
- package/types/topology/loop.d.ts +50 -0
- package/types/topology/polycurve.d.ts +109 -0
- package/types/topology/polygon.d.ts +118 -0
- package/types/topology/trimmed_surface.d.ts +136 -0
- package/types/type_define/const.d.ts +18 -0
- package/types/type_define/i_element.d.ts +9 -0
- package/types/type_define/i_element_type.d.ts +34 -0
- package/types/type_define/i_geometry.d.ts +191 -0
- package/types/type_define/i_types.d.ts +280 -0
- package/types/util/array_util.d.ts +8 -0
- package/types/util/assert.d.ts +21 -0
- package/types/util/clipper2_util.d.ts +5 -0
- package/types/util/clipper_format_converter.d.ts +21 -0
- package/types/util/clipper_util.d.ts +10 -0
- package/types/util/curve_util.d.ts +72 -0
- package/types/util/geom_util.d.ts +23 -0
- package/types/util/log.d.ts +19 -0
- package/types/util/math_error.d.ts +37 -0
- package/types/util/surface_util.d.ts +13 -0
- package/types/util/util.d.ts +18 -0
- package/types/util/uv_util.d.ts +68 -0
- package/types/verb/export_verb.d.ts +2 -0
- package/types/wasm/a2d.d.ts +19 -0
- package/types/wasm/bx2.d.ts +16 -0
- package/types/wasm/c2d.d.ts +29 -0
- package/types/wasm/elli.d.ts +19 -0
- package/types/wasm/grapher2d.d.ts +39 -0
- package/types/wasm/grapherutil.d.ts +9 -0
- package/types/wasm/l2d.d.ts +14 -0
- package/types/wasm/loader.d.ts +8 -0
- package/types/wasm/pt.d.ts +19 -0
- package/types/wasm/wasm-geom.d.ts +296 -0
- package/types/wasm/wasminstance.d.ts +19 -0
- package/types/wasm/wrapper.d.ts +82 -0
- package/README.md +0 -21
- package/dist/constants/geom_type.d.ts +0 -13
- package/dist/constants/geom_type.d.ts.map +0 -1
- package/dist/constants/geom_type.js +0 -17
- package/dist/constants/math_const.d.ts +0 -9
- package/dist/constants/math_const.d.ts.map +0 -1
- package/dist/constants/math_const.js +0 -12
- package/dist/core/box2.d.ts +0 -71
- package/dist/core/box2.d.ts.map +0 -1
- package/dist/core/box2.js +0 -243
- package/dist/core/coord2d.d.ts +0 -62
- package/dist/core/coord2d.d.ts.map +0 -1
- package/dist/core/coord2d.js +0 -155
- package/dist/core/geom_base.d.ts +0 -19
- package/dist/core/geom_base.d.ts.map +0 -1
- package/dist/core/geom_base.js +0 -18
- package/dist/core/mat3.d.ts +0 -101
- package/dist/core/mat3.d.ts.map +0 -1
- package/dist/core/mat3.js +0 -290
- package/dist/core/vec2.d.ts +0 -138
- package/dist/core/vec2.d.ts.map +0 -1
- package/dist/core/vec2.js +0 -297
- package/dist/curves/arc2.d.ts +0 -49
- package/dist/curves/arc2.d.ts.map +0 -1
- package/dist/curves/arc2.js +0 -265
- package/dist/curves/bspline2.d.ts +0 -150
- package/dist/curves/bspline2.d.ts.map +0 -1
- package/dist/curves/bspline2.js +0 -793
- package/dist/curves/circle2.d.ts +0 -42
- package/dist/curves/circle2.d.ts.map +0 -1
- package/dist/curves/circle2.js +0 -135
- package/dist/curves/circle_curve2.d.ts +0 -38
- package/dist/curves/circle_curve2.d.ts.map +0 -1
- package/dist/curves/circle_curve2.js +0 -112
- package/dist/curves/curve2.d.ts +0 -214
- package/dist/curves/curve2.d.ts.map +0 -1
- package/dist/curves/curve2.js +0 -238
- package/dist/curves/ellipse2.d.ts +0 -42
- package/dist/curves/ellipse2.d.ts.map +0 -1
- package/dist/curves/ellipse2.js +0 -125
- package/dist/curves/ellipse_arc2.d.ts +0 -49
- package/dist/curves/ellipse_arc2.d.ts.map +0 -1
- package/dist/curves/ellipse_arc2.js +0 -184
- package/dist/curves/ellipse_curve2.d.ts +0 -56
- package/dist/curves/ellipse_curve2.d.ts.map +0 -1
- package/dist/curves/ellipse_curve2.js +0 -262
- package/dist/curves/interval.d.ts +0 -112
- package/dist/curves/interval.d.ts.map +0 -1
- package/dist/curves/interval.js +0 -200
- package/dist/curves/line2.d.ts +0 -64
- package/dist/curves/line2.d.ts.map +0 -1
- package/dist/curves/line2.js +0 -193
- package/dist/curves/period_interval.d.ts +0 -129
- package/dist/curves/period_interval.d.ts.map +0 -1
- package/dist/curves/period_interval.js +0 -240
- package/dist/discretize/discretize_defaults.d.ts +0 -12
- package/dist/discretize/discretize_defaults.d.ts.map +0 -1
- package/dist/discretize/discretize_defaults.js +0 -12
- package/dist/discretize/discretize_engine.d.ts +0 -33
- package/dist/discretize/discretize_engine.d.ts.map +0 -1
- package/dist/discretize/discretize_engine.js +0 -347
- package/dist/discretize/discretize_errors.d.ts +0 -15
- package/dist/discretize/discretize_errors.d.ts.map +0 -1
- package/dist/discretize/discretize_errors.js +0 -30
- package/dist/discretize/discretize_options.d.ts +0 -18
- package/dist/discretize/discretize_options.d.ts.map +0 -1
- package/dist/discretize/discretize_options.js +0 -19
- package/dist/discretize/discretize_types.d.ts +0 -36
- package/dist/discretize/discretize_types.d.ts.map +0 -1
- package/dist/discretize/discretize_types.js +0 -1
- package/dist/discretize/internal/curve_guards.d.ts +0 -35
- package/dist/discretize/internal/curve_guards.d.ts.map +0 -1
- package/dist/discretize/internal/curve_guards.js +0 -62
- package/dist/discretize/internal/postprocess.d.ts +0 -5
- package/dist/discretize/internal/postprocess.d.ts.map +0 -1
- package/dist/discretize/internal/postprocess.js +0 -109
- package/dist/discretize/internal/sampling_utils.d.ts +0 -8
- package/dist/discretize/internal/sampling_utils.d.ts.map +0 -1
- package/dist/discretize/internal/sampling_utils.js +0 -36
- package/dist/discretize/register_builtin_strategies.d.ts +0 -3
- package/dist/discretize/register_builtin_strategies.d.ts.map +0 -1
- package/dist/discretize/register_builtin_strategies.js +0 -10
- package/dist/discretize/strategies/bspline_strategy.d.ts +0 -4
- package/dist/discretize/strategies/bspline_strategy.d.ts.map +0 -1
- package/dist/discretize/strategies/bspline_strategy.js +0 -115
- package/dist/discretize/strategies/circle_strategy.d.ts +0 -7
- package/dist/discretize/strategies/circle_strategy.d.ts.map +0 -1
- package/dist/discretize/strategies/circle_strategy.js +0 -55
- package/dist/discretize/strategies/ellipse_strategy.d.ts +0 -7
- package/dist/discretize/strategies/ellipse_strategy.d.ts.map +0 -1
- package/dist/discretize/strategies/ellipse_strategy.js +0 -86
- package/dist/discretize/strategies/line_strategy.d.ts +0 -4
- package/dist/discretize/strategies/line_strategy.d.ts.map +0 -1
- package/dist/discretize/strategies/line_strategy.js +0 -40
- package/dist/discretize/strategy_registry.d.ts +0 -9
- package/dist/discretize/strategy_registry.d.ts.map +0 -1
- package/dist/discretize/strategy_registry.js +0 -34
- package/dist/index.d.ts +0 -30
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -24
- package/dist/intersections/analytic_x_algorithm.d.ts +0 -10
- package/dist/intersections/analytic_x_algorithm.d.ts.map +0 -1
- package/dist/intersections/analytic_x_algorithm.js +0 -83
- package/dist/intersections/curve_x_engine.d.ts +0 -9
- package/dist/intersections/curve_x_engine.d.ts.map +0 -1
- package/dist/intersections/curve_x_engine.js +0 -27
- package/dist/intersections/index.d.ts +0 -5
- package/dist/intersections/index.d.ts.map +0 -1
- package/dist/intersections/index.js +0 -11
- package/dist/intersections/internal/certification.d.ts +0 -34
- package/dist/intersections/internal/certification.d.ts.map +0 -1
- package/dist/intersections/internal/certification.js +0 -238
- package/dist/intersections/internal/interval_clipping.d.ts +0 -29
- package/dist/intersections/internal/interval_clipping.d.ts.map +0 -1
- package/dist/intersections/internal/interval_clipping.js +0 -123
- package/dist/intersections/internal/kind.d.ts +0 -4
- package/dist/intersections/internal/kind.d.ts.map +0 -1
- package/dist/intersections/internal/kind.js +0 -16
- package/dist/intersections/internal/pair.d.ts +0 -9
- package/dist/intersections/internal/pair.d.ts.map +0 -1
- package/dist/intersections/internal/pair.js +0 -14
- package/dist/intersections/internal/result.d.ts +0 -20
- package/dist/intersections/internal/result.d.ts.map +0 -1
- package/dist/intersections/internal/result.js +0 -125
- package/dist/intersections/internal/sampling.d.ts +0 -15
- package/dist/intersections/internal/sampling.d.ts.map +0 -1
- package/dist/intersections/internal/sampling.js +0 -131
- package/dist/intersections/internal/segment.d.ts +0 -32
- package/dist/intersections/internal/segment.d.ts.map +0 -1
- package/dist/intersections/internal/segment.js +0 -137
- package/dist/intersections/internal/tolerance.d.ts +0 -10
- package/dist/intersections/internal/tolerance.d.ts.map +0 -1
- package/dist/intersections/internal/tolerance.js +0 -20
- package/dist/intersections/intersector.d.ts +0 -6
- package/dist/intersections/intersector.d.ts.map +0 -1
- package/dist/intersections/intersector.js +0 -1
- package/dist/intersections/numeric_x_algorithm.d.ts +0 -10
- package/dist/intersections/numeric_x_algorithm.d.ts.map +0 -1
- package/dist/intersections/numeric_x_algorithm.js +0 -73
- package/dist/intersections/solvers/bspline_self_solver.d.ts +0 -7
- package/dist/intersections/solvers/bspline_self_solver.d.ts.map +0 -1
- package/dist/intersections/solvers/bspline_self_solver.js +0 -308
- package/dist/intersections/solvers/line_line_pair_solver.d.ts +0 -7
- package/dist/intersections/solvers/line_line_pair_solver.d.ts.map +0 -1
- package/dist/intersections/solvers/line_line_pair_solver.js +0 -35
- package/dist/intersections/solvers/pair_solvers.d.ts +0 -94
- package/dist/intersections/solvers/pair_solvers.d.ts.map +0 -1
- package/dist/intersections/solvers/pair_solvers.js +0 -1078
- package/dist/intersections/solvers/polyline_pair_intersector.d.ts +0 -51
- package/dist/intersections/solvers/polyline_pair_intersector.d.ts.map +0 -1
- package/dist/intersections/solvers/polyline_pair_intersector.js +0 -731
- package/dist/intersections/types.d.ts +0 -11
- package/dist/intersections/types.d.ts.map +0 -1
- package/dist/intersections/types.js +0 -1
- package/dist/serialize/dump_types.d.ts +0 -101
- package/dist/serialize/dump_types.d.ts.map +0 -1
- package/dist/serialize/dump_types.js +0 -5
- package/dist/serialize/geom_mgr.d.ts +0 -24
- package/dist/serialize/geom_mgr.d.ts.map +0 -1
- package/dist/serialize/geom_mgr.js +0 -30
- package/dist/types/type_define.d.ts +0 -29
- package/dist/types/type_define.d.ts.map +0 -1
- package/dist/types/type_define.js +0 -10
- package/dist/types/type_guard.d.ts +0 -46
- package/dist/types/type_guard.d.ts.map +0 -1
- package/dist/types/type_guard.js +0 -5
- package/dist/utils/math_error.d.ts +0 -16
- package/dist/utils/math_error.d.ts.map +0 -1
- package/dist/utils/math_error.js +0 -35
- package/dist/utils/math_utils.d.ts +0 -9
- package/dist/utils/math_utils.d.ts.map +0 -1
- package/dist/utils/math_utils.js +0 -25
- package/dist/utils/precision.d.ts +0 -29
- package/dist/utils/precision.d.ts.map +0 -1
- package/dist/utils/precision.js +0 -44
|
@@ -1,1078 +0,0 @@
|
|
|
1
|
-
import { Vec2 } from '../../core/vec2';
|
|
2
|
-
import { Interval } from '../../curves/interval';
|
|
3
|
-
import { MathError } from '../../utils/math_error';
|
|
4
|
-
import { Precision } from '../../utils/precision';
|
|
5
|
-
import { collectIntervalClipSeeds } from '../internal/interval_clipping';
|
|
6
|
-
import { curvePointTolerance } from '../internal/tolerance';
|
|
7
|
-
import { LineLinePairSolver } from './line_line_pair_solver';
|
|
8
|
-
import { PolylinePairIntersector } from './polyline_pair_intersector';
|
|
9
|
-
function solveQuadratic(a, b, c) {
|
|
10
|
-
const eps = Precision.CURVE_NEWTON_EPS;
|
|
11
|
-
if (Math.abs(a) <= eps) {
|
|
12
|
-
if (Math.abs(b) <= eps)
|
|
13
|
-
return [];
|
|
14
|
-
return [-c / b];
|
|
15
|
-
}
|
|
16
|
-
const disc = b * b - 4 * a * c;
|
|
17
|
-
if (disc < -eps)
|
|
18
|
-
return [];
|
|
19
|
-
if (Math.abs(disc) <= eps)
|
|
20
|
-
return [-b / (2 * a)];
|
|
21
|
-
const sqrtDisc = Math.sqrt(Math.max(0, disc));
|
|
22
|
-
const q = -0.5 * (b + Math.sign(b || 1) * sqrtDisc);
|
|
23
|
-
const r1 = q / a;
|
|
24
|
-
const r2 = c / q;
|
|
25
|
-
return r1 <= r2 ? [r1, r2] : [r2, r1];
|
|
26
|
-
}
|
|
27
|
-
function assertLine(curve) {
|
|
28
|
-
MathError.assert(curve.isLine(), `Expected Line2, got ${curve.getType()}`);
|
|
29
|
-
return curve;
|
|
30
|
-
}
|
|
31
|
-
function assertCircle(curve) {
|
|
32
|
-
MathError.assert(curve.isCircle(), `Expected Circle2, got ${curve.getType()}`);
|
|
33
|
-
return curve;
|
|
34
|
-
}
|
|
35
|
-
function assertArc(curve) {
|
|
36
|
-
MathError.assert(curve.isArc(), `Expected Arc2, got ${curve.getType()}`);
|
|
37
|
-
return curve;
|
|
38
|
-
}
|
|
39
|
-
function assertEllipse(curve) {
|
|
40
|
-
MathError.assert(curve.isEllipse(), `Expected Ellipse2, got ${curve.getType()}`);
|
|
41
|
-
return curve;
|
|
42
|
-
}
|
|
43
|
-
function assertEllipseArc(curve) {
|
|
44
|
-
MathError.assert(curve.isEllipseArc(), `Expected EllipseArc2, got ${curve.getType()}`);
|
|
45
|
-
return curve;
|
|
46
|
-
}
|
|
47
|
-
function assertBSpline(curve) {
|
|
48
|
-
MathError.assert(curve.isBSpline(), `Expected BSpline2, got ${curve.getType()}`);
|
|
49
|
-
return curve;
|
|
50
|
-
}
|
|
51
|
-
function tryParamOnCurve(curve, point) {
|
|
52
|
-
const tol = curvePointTolerance(curve);
|
|
53
|
-
const cp = safeClosestPoint(curve, point, tol);
|
|
54
|
-
if (!cp)
|
|
55
|
-
return undefined;
|
|
56
|
-
if (cp.distance > tol * 16)
|
|
57
|
-
return undefined;
|
|
58
|
-
return curve.getRange().clamp(cp.param);
|
|
59
|
-
}
|
|
60
|
-
function safeClosestPoint(curve, point, tol) {
|
|
61
|
-
try {
|
|
62
|
-
return curve.closestPoint(point, tol);
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
PolylinePairIntersector.recordAnalyticClosestFallback();
|
|
66
|
-
return sampleClosestPoint(curve, point, 64);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function sampleClosestPoint(curve, point, sampleCount) {
|
|
70
|
-
const range = curve.getRange();
|
|
71
|
-
let bestParam = range.start;
|
|
72
|
-
let bestPoint = curve.pointAt(bestParam);
|
|
73
|
-
let bestDist = bestPoint.distanceTo(point);
|
|
74
|
-
const total = Math.max(8, sampleCount);
|
|
75
|
-
for (let i = 1; i <= total; i++) {
|
|
76
|
-
const t = i / total;
|
|
77
|
-
const u = range.start + (range.end - range.start) * t;
|
|
78
|
-
const q = curve.pointAt(u);
|
|
79
|
-
const d = q.distanceTo(point);
|
|
80
|
-
if (d < bestDist) {
|
|
81
|
-
bestDist = d;
|
|
82
|
-
bestParam = u;
|
|
83
|
-
bestPoint = q;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// Local Newton refinement around the best sampled parameter.
|
|
87
|
-
let u = bestParam;
|
|
88
|
-
for (let i = 0; i < 12; i++) {
|
|
89
|
-
const p = curve.pointAt(u);
|
|
90
|
-
const d1 = curve.derivativeAt(u, 1);
|
|
91
|
-
const d2 = curve.derivativeAt(u, 2);
|
|
92
|
-
const cp = p.subtracted(point);
|
|
93
|
-
const f = cp.dot(d1);
|
|
94
|
-
const fp = d1.dot(d1) + cp.dot(d2);
|
|
95
|
-
if (!Number.isFinite(f) || !Number.isFinite(fp) || Math.abs(fp) <= Precision.CURVE_NEWTON_EPS)
|
|
96
|
-
break;
|
|
97
|
-
const next = range.clamp(u - f / fp);
|
|
98
|
-
if (Math.abs(next - u) <= Precision.CURVE_PARAM_EPS * 4) {
|
|
99
|
-
u = next;
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
u = next;
|
|
103
|
-
}
|
|
104
|
-
bestParam = u;
|
|
105
|
-
bestPoint = curve.pointAt(bestParam);
|
|
106
|
-
bestDist = bestPoint.distanceTo(point);
|
|
107
|
-
return {
|
|
108
|
-
point: bestPoint,
|
|
109
|
-
param: bestParam,
|
|
110
|
-
distance: bestDist,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function tryBuildPointInfo(c1, c2, point) {
|
|
114
|
-
const u1 = tryParamOnCurve(c1, point);
|
|
115
|
-
const u2 = tryParamOnCurve(c2, point);
|
|
116
|
-
if (u1 === undefined || u2 === undefined)
|
|
117
|
-
return undefined;
|
|
118
|
-
return {
|
|
119
|
-
point,
|
|
120
|
-
u1,
|
|
121
|
-
u2,
|
|
122
|
-
isOverlap: false,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
function pushUniqueResult(items, candidate) {
|
|
126
|
-
if (!candidate)
|
|
127
|
-
return;
|
|
128
|
-
for (const item of items) {
|
|
129
|
-
if (Math.abs(item.u1 - candidate.u1) <= Precision.CURVE_PARAM_EPS * 8 &&
|
|
130
|
-
Math.abs(item.u2 - candidate.u2) <= Precision.CURVE_PARAM_EPS * 8 &&
|
|
131
|
-
item.isOverlap === candidate.isOverlap) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
items.push(candidate);
|
|
136
|
-
}
|
|
137
|
-
function collectUniqueResults(candidates) {
|
|
138
|
-
const out = [];
|
|
139
|
-
for (const hit of candidates) {
|
|
140
|
-
pushUniqueResult(out, hit);
|
|
141
|
-
}
|
|
142
|
-
return out;
|
|
143
|
-
}
|
|
144
|
-
function lineCircleParamIntersections(line, center, radius) {
|
|
145
|
-
const p0 = line.start;
|
|
146
|
-
const p1 = line.end;
|
|
147
|
-
const v = p1.subtracted(p0);
|
|
148
|
-
const len = v.len();
|
|
149
|
-
if (len <= Precision.CURVE_LENGTH_EPS)
|
|
150
|
-
return [];
|
|
151
|
-
const d = v.scaled(1 / len);
|
|
152
|
-
const f = p0.subtracted(center);
|
|
153
|
-
const b = 2 * d.dot(f);
|
|
154
|
-
const c = f.lenSq() - radius * radius;
|
|
155
|
-
const roots = solveQuadratic(1, b, c);
|
|
156
|
-
const ret = [];
|
|
157
|
-
for (const s of roots) {
|
|
158
|
-
if (s < -Precision.CURVE_LENGTH_EPS || s > len + Precision.CURVE_LENGTH_EPS)
|
|
159
|
-
continue;
|
|
160
|
-
const uLine = Math.min(len, Math.max(0, s));
|
|
161
|
-
const point = p0.added(d.scaled(uLine));
|
|
162
|
-
ret.push({ point, uLine });
|
|
163
|
-
}
|
|
164
|
-
return ret;
|
|
165
|
-
}
|
|
166
|
-
function lineEllipseParamIntersections(line, ellipse) {
|
|
167
|
-
const p0 = line.start;
|
|
168
|
-
const p1 = line.end;
|
|
169
|
-
const v = p1.subtracted(p0);
|
|
170
|
-
const len = v.len();
|
|
171
|
-
if (len <= Precision.CURVE_LENGTH_EPS)
|
|
172
|
-
return [];
|
|
173
|
-
const d = v.scaled(1 / len);
|
|
174
|
-
const c = Math.cos(ellipse.rotation);
|
|
175
|
-
const s = Math.sin(ellipse.rotation);
|
|
176
|
-
const rel0 = p0.subtracted(ellipse.center);
|
|
177
|
-
const x0 = c * rel0.x + s * rel0.y;
|
|
178
|
-
const y0 = -s * rel0.x + c * rel0.y;
|
|
179
|
-
const dx = c * d.x + s * d.y;
|
|
180
|
-
const dy = -s * d.x + c * d.y;
|
|
181
|
-
const invRx2 = 1 / (ellipse.rx * ellipse.rx);
|
|
182
|
-
const invRy2 = 1 / (ellipse.ry * ellipse.ry);
|
|
183
|
-
const a = dx * dx * invRx2 + dy * dy * invRy2;
|
|
184
|
-
const b = 2 * (x0 * dx * invRx2 + y0 * dy * invRy2);
|
|
185
|
-
const cc = x0 * x0 * invRx2 + y0 * y0 * invRy2 - 1;
|
|
186
|
-
const roots = solveQuadratic(a, b, cc);
|
|
187
|
-
const ret = [];
|
|
188
|
-
for (const sLine of roots) {
|
|
189
|
-
if (sLine < -Precision.CURVE_LENGTH_EPS || sLine > len + Precision.CURVE_LENGTH_EPS)
|
|
190
|
-
continue;
|
|
191
|
-
const uLine = Math.min(len, Math.max(0, sLine));
|
|
192
|
-
const point = p0.added(d.scaled(uLine));
|
|
193
|
-
ret.push({ point, uLine });
|
|
194
|
-
}
|
|
195
|
-
return ret;
|
|
196
|
-
}
|
|
197
|
-
function clamp01(x) {
|
|
198
|
-
return Math.max(0, Math.min(1, x));
|
|
199
|
-
}
|
|
200
|
-
function linePointDistance(line, point) {
|
|
201
|
-
const dir = line.tangentAt(line.getRange().start);
|
|
202
|
-
const v = point.subtracted(line.start);
|
|
203
|
-
return Math.abs(v.cross(dir));
|
|
204
|
-
}
|
|
205
|
-
function splitByBreaks(curve) {
|
|
206
|
-
const range = curve.getRange();
|
|
207
|
-
const breaks = [range.start, ...curve.getContinuityBreakParams(Precision.CURVE_PARAM_EPS), range.end];
|
|
208
|
-
breaks.sort((a, b) => a - b);
|
|
209
|
-
const ret = [];
|
|
210
|
-
for (let i = 0; i < breaks.length - 1; i++) {
|
|
211
|
-
const u0 = breaks[i];
|
|
212
|
-
const u1 = breaks[i + 1];
|
|
213
|
-
if (u1 - u0 <= Precision.CURVE_PARAM_EPS * 4)
|
|
214
|
-
continue;
|
|
215
|
-
ret.push({ u0, u1 });
|
|
216
|
-
}
|
|
217
|
-
return ret;
|
|
218
|
-
}
|
|
219
|
-
function solveLineBSplineRoots(line, bspline) {
|
|
220
|
-
const lineStart = line.start;
|
|
221
|
-
const lineEnd = line.end;
|
|
222
|
-
const lineDir = lineEnd.subtracted(lineStart);
|
|
223
|
-
const lineLen = lineDir.len();
|
|
224
|
-
if (lineLen <= Precision.CURVE_LENGTH_EPS)
|
|
225
|
-
return [];
|
|
226
|
-
const lineUnit = lineDir.scaled(1 / lineLen);
|
|
227
|
-
// Signed distance to line support.
|
|
228
|
-
const f = (u) => bspline.pointAt(u).subtracted(lineStart).cross(lineUnit);
|
|
229
|
-
const df = (u) => bspline.derivativeAt(u, 1).cross(lineUnit);
|
|
230
|
-
const pointTol = curvePointTolerance(bspline) * 4;
|
|
231
|
-
const paramTol = Precision.CURVE_PARAM_EPS * 32;
|
|
232
|
-
const roots = [];
|
|
233
|
-
const intervals = splitByBreaks(bspline);
|
|
234
|
-
const tryPushRoot = (u) => {
|
|
235
|
-
const uu = bspline.getRange().clamp(u);
|
|
236
|
-
for (const r of roots) {
|
|
237
|
-
if (Math.abs(r - uu) <= paramTol)
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
roots.push(uu);
|
|
241
|
-
};
|
|
242
|
-
for (const seg of intervals) {
|
|
243
|
-
const rootsOnSeg = solveScalarRootsOnInterval(f, df, seg.u0, seg.u1, {
|
|
244
|
-
valueTol: pointTol,
|
|
245
|
-
paramTol,
|
|
246
|
-
sampleCount: 64,
|
|
247
|
-
});
|
|
248
|
-
for (const u of rootsOnSeg) {
|
|
249
|
-
if (Math.abs(f(u)) <= pointTol * 2)
|
|
250
|
-
tryPushRoot(u);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
roots.sort((a, b) => a - b);
|
|
254
|
-
const hits = [];
|
|
255
|
-
for (const uSpline of roots) {
|
|
256
|
-
const p = bspline.pointAt(uSpline);
|
|
257
|
-
const uLine = p.subtracted(lineStart).dot(lineUnit);
|
|
258
|
-
if (uLine < -pointTol || uLine > lineLen + pointTol)
|
|
259
|
-
continue;
|
|
260
|
-
if (linePointDistance(line, p) > pointTol * 3)
|
|
261
|
-
continue;
|
|
262
|
-
hits.push({
|
|
263
|
-
point: p,
|
|
264
|
-
u1: clamp01(uLine / lineLen) * lineLen,
|
|
265
|
-
u2: uSpline,
|
|
266
|
-
isOverlap: false,
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
return hits;
|
|
270
|
-
}
|
|
271
|
-
function solveScalarRootsOnInterval(f, df, u0, u1, options) {
|
|
272
|
-
const roots = [];
|
|
273
|
-
const samples = Math.max(8, options.sampleCount);
|
|
274
|
-
const du = (u1 - u0) / samples;
|
|
275
|
-
const pushRoot = (u) => {
|
|
276
|
-
const uu = Math.max(u0, Math.min(u1, u));
|
|
277
|
-
for (const r of roots) {
|
|
278
|
-
if (Math.abs(r - uu) <= options.paramTol)
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
roots.push(uu);
|
|
282
|
-
};
|
|
283
|
-
const refineBracket = (a0, b0, fn, dfn) => {
|
|
284
|
-
let a = a0;
|
|
285
|
-
let b = b0;
|
|
286
|
-
let fa = fn(a);
|
|
287
|
-
let fb = fn(b);
|
|
288
|
-
let u = 0.5 * (a + b);
|
|
289
|
-
let fu = fn(u);
|
|
290
|
-
for (let it = 0; it < 32; it++) {
|
|
291
|
-
if (Math.abs(fu) <= options.valueTol || (b - a) <= options.paramTol)
|
|
292
|
-
return u;
|
|
293
|
-
const slope = dfn(u);
|
|
294
|
-
let next = Number.NaN;
|
|
295
|
-
if (Number.isFinite(slope) && Math.abs(slope) > Precision.CURVE_NEWTON_EPS) {
|
|
296
|
-
next = u - fu / slope;
|
|
297
|
-
}
|
|
298
|
-
if (!Number.isFinite(next) || next <= a || next >= b) {
|
|
299
|
-
next = 0.5 * (a + b);
|
|
300
|
-
}
|
|
301
|
-
const fnext = fn(next);
|
|
302
|
-
if (fa === 0 || fnext === 0 || fa * fnext <= 0) {
|
|
303
|
-
b = next;
|
|
304
|
-
fb = fnext;
|
|
305
|
-
}
|
|
306
|
-
else {
|
|
307
|
-
a = next;
|
|
308
|
-
fa = fnext;
|
|
309
|
-
}
|
|
310
|
-
if (Math.abs(fa) < Math.abs(fb)) {
|
|
311
|
-
u = a;
|
|
312
|
-
fu = fa;
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
u = b;
|
|
316
|
-
fu = fb;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
return u;
|
|
320
|
-
};
|
|
321
|
-
let prevU = u0;
|
|
322
|
-
let prevF = f(prevU);
|
|
323
|
-
let prevDf = df(prevU);
|
|
324
|
-
if (Math.abs(prevF) <= options.valueTol)
|
|
325
|
-
pushRoot(prevU);
|
|
326
|
-
for (let i = 1; i <= samples; i++) {
|
|
327
|
-
const curU = i === samples ? u1 : (u0 + du * i);
|
|
328
|
-
const curF = f(curU);
|
|
329
|
-
const curDf = df(curU);
|
|
330
|
-
if (Math.abs(curF) <= options.valueTol) {
|
|
331
|
-
pushRoot(curU);
|
|
332
|
-
}
|
|
333
|
-
if (prevF === 0 || curF === 0 || prevF * curF < 0) {
|
|
334
|
-
pushRoot(refineBracket(prevU, curU, f, df));
|
|
335
|
-
}
|
|
336
|
-
// Handle tangency: derivative changes sign but f does not.
|
|
337
|
-
if (prevDf === 0 || curDf === 0 || prevDf * curDf < 0) {
|
|
338
|
-
const uCritical = refineBracket(prevU, curU, df, () => 0);
|
|
339
|
-
if (Math.abs(f(uCritical)) <= options.valueTol * 2) {
|
|
340
|
-
pushRoot(uCritical);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
prevU = curU;
|
|
344
|
-
prevF = curF;
|
|
345
|
-
prevDf = curDf;
|
|
346
|
-
}
|
|
347
|
-
roots.sort((a, b) => a - b);
|
|
348
|
-
return roots;
|
|
349
|
-
}
|
|
350
|
-
function probeImplicitInterval(f, u0, u1, baseSampleCount, valueTol) {
|
|
351
|
-
const probes = 24;
|
|
352
|
-
let signChanges = 0;
|
|
353
|
-
let nearZeroCount = 0;
|
|
354
|
-
let prev = f(u0);
|
|
355
|
-
for (let i = 1; i <= probes; i++) {
|
|
356
|
-
const t = i / probes;
|
|
357
|
-
const u = u0 + (u1 - u0) * t;
|
|
358
|
-
const cur = f(u);
|
|
359
|
-
if (Math.abs(cur) <= valueTol * 2) {
|
|
360
|
-
nearZeroCount++;
|
|
361
|
-
}
|
|
362
|
-
if (prev === 0 || cur === 0 || prev * cur < 0) {
|
|
363
|
-
signChanges++;
|
|
364
|
-
}
|
|
365
|
-
prev = cur;
|
|
366
|
-
}
|
|
367
|
-
const suggested = baseSampleCount + signChanges * 24 + nearZeroCount * 6;
|
|
368
|
-
return {
|
|
369
|
-
signChanges,
|
|
370
|
-
nearZeroCount,
|
|
371
|
-
sampleCount: Math.max(baseSampleCount, Math.min(320, suggested)),
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
function solveImplicitBSplineRoots(target, bspline, implicit, valueTolScale = 1) {
|
|
375
|
-
const pointTol = Math.max(curvePointTolerance(target), curvePointTolerance(bspline));
|
|
376
|
-
const paramTol = Precision.CURVE_PARAM_EPS * 32;
|
|
377
|
-
const valueTol = Math.max(pointTol * pointTol * 4, pointTol * valueTolScale * 4);
|
|
378
|
-
const targetProjectTol = pointTol * 8;
|
|
379
|
-
const range = bspline.getRange();
|
|
380
|
-
const intervals = splitByBreaks(bspline);
|
|
381
|
-
if (intervals.length === 0) {
|
|
382
|
-
intervals.push({ u0: range.start, u1: range.end });
|
|
383
|
-
}
|
|
384
|
-
const f = (u) => {
|
|
385
|
-
const p = bspline.pointAt(u);
|
|
386
|
-
return implicit(p).value;
|
|
387
|
-
};
|
|
388
|
-
const df = (u) => {
|
|
389
|
-
const p = bspline.pointAt(u);
|
|
390
|
-
const d1 = bspline.derivativeAt(u, 1);
|
|
391
|
-
const evalv = implicit(p);
|
|
392
|
-
return evalv.grad.dot(d1);
|
|
393
|
-
};
|
|
394
|
-
const allRoots = [];
|
|
395
|
-
const pushRootUnique = (roots, u) => {
|
|
396
|
-
let duplicate = false;
|
|
397
|
-
for (const r of roots) {
|
|
398
|
-
if (Math.abs(r - u) <= paramTol) {
|
|
399
|
-
duplicate = true;
|
|
400
|
-
break;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (!duplicate)
|
|
404
|
-
roots.push(u);
|
|
405
|
-
};
|
|
406
|
-
for (const seg of intervals) {
|
|
407
|
-
const probe = probeImplicitInterval(f, seg.u0, seg.u1, 96, valueTol);
|
|
408
|
-
const roots = solveScalarRootsOnInterval(f, df, seg.u0, seg.u1, {
|
|
409
|
-
valueTol,
|
|
410
|
-
paramTol,
|
|
411
|
-
sampleCount: probe.sampleCount,
|
|
412
|
-
});
|
|
413
|
-
for (const u of roots)
|
|
414
|
-
pushRootUnique(allRoots, u);
|
|
415
|
-
// Second pass for oscillatory / near-tangent intervals:
|
|
416
|
-
// increase sampling density and merge extra roots.
|
|
417
|
-
if (probe.signChanges >= 2 || probe.nearZeroCount >= 2) {
|
|
418
|
-
const denseRoots = solveScalarRootsOnInterval(f, df, seg.u0, seg.u1, {
|
|
419
|
-
valueTol,
|
|
420
|
-
paramTol,
|
|
421
|
-
sampleCount: Math.min(640, probe.sampleCount * 2),
|
|
422
|
-
});
|
|
423
|
-
for (const u of denseRoots)
|
|
424
|
-
pushRootUnique(allRoots, u);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
// Global dense isolation for missed tangent / close multi-roots.
|
|
428
|
-
const globalDenseRoots = isolateRootsByDenseSampling(f, df, range.start, range.end, valueTol, paramTol);
|
|
429
|
-
for (const u of globalDenseRoots) {
|
|
430
|
-
pushRootUnique(allRoots, u);
|
|
431
|
-
}
|
|
432
|
-
allRoots.sort((a, b) => a - b);
|
|
433
|
-
const out = [];
|
|
434
|
-
for (const uSpline of allRoots) {
|
|
435
|
-
const p = bspline.pointAt(uSpline);
|
|
436
|
-
const ev = implicit(p);
|
|
437
|
-
if (Math.abs(ev.value) > valueTol * 4)
|
|
438
|
-
continue;
|
|
439
|
-
const cpTarget = safeClosestPoint(target, p, targetProjectTol);
|
|
440
|
-
if (!cpTarget || cpTarget.distance > targetProjectTol * 2)
|
|
441
|
-
continue;
|
|
442
|
-
out.push({
|
|
443
|
-
point: p,
|
|
444
|
-
u1: target.getRange().clamp(cpTarget.param),
|
|
445
|
-
u2: uSpline,
|
|
446
|
-
isOverlap: false,
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
return out;
|
|
450
|
-
}
|
|
451
|
-
function isolateRootsByDenseSampling(f, df, u0, u1, valueTol, paramTol) {
|
|
452
|
-
const samples = 2048;
|
|
453
|
-
const us = new Array(samples + 1);
|
|
454
|
-
const fs = new Array(samples + 1);
|
|
455
|
-
for (let i = 0; i <= samples; i++) {
|
|
456
|
-
const t = i / samples;
|
|
457
|
-
const u = u0 + (u1 - u0) * t;
|
|
458
|
-
us[i] = u;
|
|
459
|
-
fs[i] = f(u);
|
|
460
|
-
}
|
|
461
|
-
const roots = [];
|
|
462
|
-
const pushRoot = (u) => {
|
|
463
|
-
for (const r of roots) {
|
|
464
|
-
if (Math.abs(r - u) <= paramTol)
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
roots.push(u);
|
|
468
|
-
};
|
|
469
|
-
const bisect = (a0, b0) => {
|
|
470
|
-
let a = a0;
|
|
471
|
-
let b = b0;
|
|
472
|
-
let fa = f(a);
|
|
473
|
-
let fb = f(b);
|
|
474
|
-
if (Math.abs(fa) <= valueTol)
|
|
475
|
-
return a;
|
|
476
|
-
if (Math.abs(fb) <= valueTol)
|
|
477
|
-
return b;
|
|
478
|
-
if (fa * fb > 0)
|
|
479
|
-
return 0.5 * (a + b);
|
|
480
|
-
for (let it = 0; it < 48; it++) {
|
|
481
|
-
const m = 0.5 * (a + b);
|
|
482
|
-
const fm = f(m);
|
|
483
|
-
if (Math.abs(fm) <= valueTol || (b - a) <= paramTol)
|
|
484
|
-
return m;
|
|
485
|
-
if (fa * fm <= 0) {
|
|
486
|
-
b = m;
|
|
487
|
-
fb = fm;
|
|
488
|
-
}
|
|
489
|
-
else {
|
|
490
|
-
a = m;
|
|
491
|
-
fa = fm;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
return 0.5 * (a + b);
|
|
495
|
-
};
|
|
496
|
-
const refineLocal = (a0, b0, seed) => {
|
|
497
|
-
let a = a0;
|
|
498
|
-
let b = b0;
|
|
499
|
-
let u = Math.max(a, Math.min(b, seed));
|
|
500
|
-
let fu = f(u);
|
|
501
|
-
for (let it = 0; it < 32; it++) {
|
|
502
|
-
if (Math.abs(fu) <= valueTol || (b - a) <= paramTol)
|
|
503
|
-
return u;
|
|
504
|
-
const slope = df(u);
|
|
505
|
-
let next = Number.NaN;
|
|
506
|
-
if (Number.isFinite(slope) && Math.abs(slope) > Precision.CURVE_NEWTON_EPS) {
|
|
507
|
-
next = u - fu / slope;
|
|
508
|
-
}
|
|
509
|
-
if (!Number.isFinite(next) || next <= a || next >= b) {
|
|
510
|
-
next = 0.5 * (a + b);
|
|
511
|
-
}
|
|
512
|
-
const fn = f(next);
|
|
513
|
-
if (f(a) * fn <= 0) {
|
|
514
|
-
b = next;
|
|
515
|
-
}
|
|
516
|
-
else {
|
|
517
|
-
a = next;
|
|
518
|
-
}
|
|
519
|
-
u = next;
|
|
520
|
-
fu = fn;
|
|
521
|
-
}
|
|
522
|
-
return u;
|
|
523
|
-
};
|
|
524
|
-
for (let i = 1; i <= samples; i++) {
|
|
525
|
-
const a = us[i - 1];
|
|
526
|
-
const b = us[i];
|
|
527
|
-
const fa = fs[i - 1];
|
|
528
|
-
const fb = fs[i];
|
|
529
|
-
if (Math.abs(fa) <= valueTol)
|
|
530
|
-
pushRoot(a);
|
|
531
|
-
if (Math.abs(fb) <= valueTol)
|
|
532
|
-
pushRoot(b);
|
|
533
|
-
if (fa === 0 || fb === 0 || fa * fb < 0) {
|
|
534
|
-
pushRoot(bisect(a, b));
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
// same-sign tangent / near-touch roots
|
|
538
|
-
for (let i = 1; i < samples; i++) {
|
|
539
|
-
const f0 = fs[i - 1];
|
|
540
|
-
const f1 = fs[i];
|
|
541
|
-
const f2 = fs[i + 1];
|
|
542
|
-
if (Math.sign(f0) === Math.sign(f2) && Math.abs(f1) <= Math.min(Math.abs(f0), Math.abs(f2)) && Math.abs(f1) <= valueTol * 4) {
|
|
543
|
-
const a = us[i - 1];
|
|
544
|
-
const b = us[i + 1];
|
|
545
|
-
pushRoot(refineLocal(a, b, us[i]));
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
roots.sort((a, b) => a - b);
|
|
549
|
-
return roots;
|
|
550
|
-
}
|
|
551
|
-
function normalizeClosedParam(curve, u) {
|
|
552
|
-
const range = curve.getRange();
|
|
553
|
-
const clamped = range.clamp(u);
|
|
554
|
-
if (!curve.isClosed())
|
|
555
|
-
return clamped;
|
|
556
|
-
const len = range.length();
|
|
557
|
-
if (len <= Precision.CURVE_PARAM_EPS)
|
|
558
|
-
return clamped;
|
|
559
|
-
if (Math.abs(clamped - range.end) <= Precision.CURVE_PARAM_EPS * 16)
|
|
560
|
-
return range.start;
|
|
561
|
-
return clamped;
|
|
562
|
-
}
|
|
563
|
-
function solveParametricImplicitRoots(paramCurve, target, implicit, valueTolScale = 1) {
|
|
564
|
-
const pointTol = Math.max(curvePointTolerance(paramCurve), curvePointTolerance(target));
|
|
565
|
-
const paramTol = Precision.CURVE_PARAM_EPS * 32;
|
|
566
|
-
const valueTol = Math.max(pointTol * pointTol * 4, pointTol * valueTolScale * 4);
|
|
567
|
-
const targetProjectTol = Math.max(pointTol * 128, valueTolScale * 1e-5, Precision.CURVE_LENGTH_EPS * 32);
|
|
568
|
-
const range = paramCurve.getRange();
|
|
569
|
-
const f = (u) => {
|
|
570
|
-
const p = paramCurve.pointAt(u);
|
|
571
|
-
return implicit(p).value;
|
|
572
|
-
};
|
|
573
|
-
const df = (u) => {
|
|
574
|
-
const p = paramCurve.pointAt(u);
|
|
575
|
-
const d1 = paramCurve.derivativeAt(u, 1);
|
|
576
|
-
const evalv = implicit(p);
|
|
577
|
-
return evalv.grad.dot(d1);
|
|
578
|
-
};
|
|
579
|
-
const roots = isolateRootsByDenseSampling(f, df, range.start, range.end, valueTol, paramTol);
|
|
580
|
-
const out = [];
|
|
581
|
-
for (const uCircle of roots) {
|
|
582
|
-
const uu = normalizeClosedParam(paramCurve, uCircle);
|
|
583
|
-
const p = paramCurve.pointAt(uu);
|
|
584
|
-
const ev = implicit(p);
|
|
585
|
-
if (Math.abs(ev.value) > valueTol * 8)
|
|
586
|
-
continue;
|
|
587
|
-
const cpTarget = safeClosestPoint(target, p, targetProjectTol);
|
|
588
|
-
if (!cpTarget || cpTarget.distance > targetProjectTol * 4)
|
|
589
|
-
continue;
|
|
590
|
-
pushUniqueResult(out, {
|
|
591
|
-
point: p,
|
|
592
|
-
u1: uu,
|
|
593
|
-
u2: normalizeClosedParam(target, cpTarget.param),
|
|
594
|
-
isOverlap: false,
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
return out;
|
|
598
|
-
}
|
|
599
|
-
function swapPairResults(items) {
|
|
600
|
-
return items.map((item) => ({
|
|
601
|
-
point: item.point,
|
|
602
|
-
u1: item.u2,
|
|
603
|
-
u2: item.u1,
|
|
604
|
-
isOverlap: item.isOverlap,
|
|
605
|
-
range1: item.range2,
|
|
606
|
-
range2: item.range1,
|
|
607
|
-
}));
|
|
608
|
-
}
|
|
609
|
-
function solveMutualParametricImplicitRoots(c1, c2, implicitOfC1, implicitOfC2, scale1, scale2) {
|
|
610
|
-
const forward = solveParametricImplicitRoots(c1, c2, implicitOfC2, scale2);
|
|
611
|
-
const reverse = swapPairResults(solveParametricImplicitRoots(c2, c1, implicitOfC1, scale1));
|
|
612
|
-
return collectUniqueResults([...forward, ...reverse]);
|
|
613
|
-
}
|
|
614
|
-
function intersectImplicitBSplinePair(target, bspline, implicit, valueTolScale = 1) {
|
|
615
|
-
return collectUniqueResults(solveImplicitBSplineRoots(target, bspline, implicit, valueTolScale));
|
|
616
|
-
}
|
|
617
|
-
function refineCurvePairNewton(c1, c2, u1Seed, u2Seed, pointTol) {
|
|
618
|
-
const r1 = c1.getRange();
|
|
619
|
-
const r2 = c2.getRange();
|
|
620
|
-
let u1 = r1.clamp(u1Seed);
|
|
621
|
-
let u2 = r2.clamp(u2Seed);
|
|
622
|
-
let best = measurePair(c1, c2, u1, u2);
|
|
623
|
-
for (let i = 0; i < 24; i++) {
|
|
624
|
-
const p1 = c1.pointAt(u1);
|
|
625
|
-
const p2 = c2.pointAt(u2);
|
|
626
|
-
const diff = p1.subtracted(p2);
|
|
627
|
-
if (diff.len() <= pointTol)
|
|
628
|
-
return measurePair(c1, c2, u1, u2);
|
|
629
|
-
const t1 = c1.derivativeAt(u1, 1);
|
|
630
|
-
const t2 = c2.derivativeAt(u2, 1);
|
|
631
|
-
const det = t1.cross(t2);
|
|
632
|
-
if (Math.abs(det) <= Precision.CURVE_NEWTON_EPS)
|
|
633
|
-
break;
|
|
634
|
-
const bx = -diff.x;
|
|
635
|
-
const by = -diff.y;
|
|
636
|
-
let du = (bx * (-t2.y) - by * (-t2.x)) / det;
|
|
637
|
-
let dv = (t1.x * by - t1.y * bx) / det;
|
|
638
|
-
if (!Number.isFinite(du) || !Number.isFinite(dv))
|
|
639
|
-
break;
|
|
640
|
-
const nextU1 = r1.clamp(u1 + du);
|
|
641
|
-
const nextU2 = r2.clamp(u2 + dv);
|
|
642
|
-
const cand = measurePair(c1, c2, nextU1, nextU2);
|
|
643
|
-
if (cand.residual < best.residual)
|
|
644
|
-
best = cand;
|
|
645
|
-
const delta = Math.abs(nextU1 - u1) + Math.abs(nextU2 - u2);
|
|
646
|
-
u1 = nextU1;
|
|
647
|
-
u2 = nextU2;
|
|
648
|
-
if (delta <= Precision.CURVE_PARAM_EPS * 8)
|
|
649
|
-
break;
|
|
650
|
-
}
|
|
651
|
-
if (best.residual > pointTol * 4)
|
|
652
|
-
return undefined;
|
|
653
|
-
return best;
|
|
654
|
-
}
|
|
655
|
-
function measurePair(c1, c2, u1, u2) {
|
|
656
|
-
const p1 = c1.pointAt(u1);
|
|
657
|
-
const p2 = c2.pointAt(u2);
|
|
658
|
-
return {
|
|
659
|
-
u1,
|
|
660
|
-
u2,
|
|
661
|
-
point: p1.added(p2).scale(0.5),
|
|
662
|
-
residual: p1.distanceTo(p2),
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
function seedFromClosestPass(c1, c2, pointTol) {
|
|
666
|
-
const seeds = [];
|
|
667
|
-
const push = (u1, u2) => {
|
|
668
|
-
for (const s of seeds) {
|
|
669
|
-
if (Math.abs(s.u1 - u1) <= Precision.CURVE_PARAM_EPS * 16 && Math.abs(s.u2 - u2) <= Precision.CURVE_PARAM_EPS * 16) {
|
|
670
|
-
return;
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
seeds.push({ u1, u2 });
|
|
674
|
-
};
|
|
675
|
-
const r1 = c1.getRange();
|
|
676
|
-
const r2 = c2.getRange();
|
|
677
|
-
const samples = 80;
|
|
678
|
-
for (let i = 0; i <= samples; i++) {
|
|
679
|
-
const u1 = r1.start + (r1.end - r1.start) * (i / samples);
|
|
680
|
-
const p1 = c1.pointAt(u1);
|
|
681
|
-
const cp2 = safeClosestPoint(c2, p1, pointTol * 2);
|
|
682
|
-
if (!cp2 || cp2.distance > pointTol * 2)
|
|
683
|
-
continue;
|
|
684
|
-
push(u1, r2.clamp(cp2.param));
|
|
685
|
-
}
|
|
686
|
-
for (let i = 0; i <= samples; i++) {
|
|
687
|
-
const u2 = r2.start + (r2.end - r2.start) * (i / samples);
|
|
688
|
-
const p2 = c2.pointAt(u2);
|
|
689
|
-
const cp1 = safeClosestPoint(c1, p2, pointTol * 2);
|
|
690
|
-
if (!cp1 || cp1.distance > pointTol * 2)
|
|
691
|
-
continue;
|
|
692
|
-
push(r1.clamp(cp1.param), u2);
|
|
693
|
-
}
|
|
694
|
-
return seeds;
|
|
695
|
-
}
|
|
696
|
-
function solveBSplineBSplineRoots(c1, c2) {
|
|
697
|
-
const pointTol = Math.max(curvePointTolerance(c1), curvePointTolerance(c2));
|
|
698
|
-
const clip = collectIntervalClipSeeds(c1, c2, {
|
|
699
|
-
pointTol,
|
|
700
|
-
seedParamTol: Precision.CURVE_PARAM_EPS * 16,
|
|
701
|
-
maxDepth: 16,
|
|
702
|
-
maxNodes: 12000,
|
|
703
|
-
pointSeedLimit: 2048,
|
|
704
|
-
overlapSeedLimit: 128,
|
|
705
|
-
});
|
|
706
|
-
const seeds = [];
|
|
707
|
-
const pushSeed = (u1, u2) => {
|
|
708
|
-
for (const s of seeds) {
|
|
709
|
-
if (Math.abs(s.u1 - u1) <= Precision.CURVE_PARAM_EPS * 16 && Math.abs(s.u2 - u2) <= Precision.CURVE_PARAM_EPS * 16) {
|
|
710
|
-
return;
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
seeds.push({ u1, u2 });
|
|
714
|
-
};
|
|
715
|
-
for (const s of clip.pointSeeds) {
|
|
716
|
-
pushSeed(s.u1, s.u2);
|
|
717
|
-
}
|
|
718
|
-
for (const o of clip.overlapSeeds) {
|
|
719
|
-
pushSeed(0.5 * (o.range1.start + o.range1.end), 0.5 * (o.range2.start + o.range2.end));
|
|
720
|
-
}
|
|
721
|
-
if (seeds.length < 8) {
|
|
722
|
-
for (const s of seedFromClosestPass(c1, c2, pointTol)) {
|
|
723
|
-
pushSeed(s.u1, s.u2);
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
const out = [];
|
|
727
|
-
for (const seed of seeds) {
|
|
728
|
-
const refined = refineCurvePairNewton(c1, c2, seed.u1, seed.u2, pointTol);
|
|
729
|
-
if (!refined)
|
|
730
|
-
continue;
|
|
731
|
-
pushUniqueResult(out, {
|
|
732
|
-
point: refined.point,
|
|
733
|
-
u1: refined.u1,
|
|
734
|
-
u2: refined.u2,
|
|
735
|
-
isOverlap: false,
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
return out;
|
|
739
|
-
}
|
|
740
|
-
function circleImplicit(circle) {
|
|
741
|
-
return (p) => {
|
|
742
|
-
const dx = p.x - circle.center.x;
|
|
743
|
-
const dy = p.y - circle.center.y;
|
|
744
|
-
return {
|
|
745
|
-
value: dx * dx + dy * dy - circle.radius * circle.radius,
|
|
746
|
-
grad: new Vec2(2 * dx, 2 * dy),
|
|
747
|
-
};
|
|
748
|
-
};
|
|
749
|
-
}
|
|
750
|
-
function ellipseImplicit(ellipse) {
|
|
751
|
-
const c = Math.cos(ellipse.rotation);
|
|
752
|
-
const s = Math.sin(ellipse.rotation);
|
|
753
|
-
const invRx2 = 1 / (ellipse.rx * ellipse.rx);
|
|
754
|
-
const invRy2 = 1 / (ellipse.ry * ellipse.ry);
|
|
755
|
-
return (p) => {
|
|
756
|
-
const dx = p.x - ellipse.center.x;
|
|
757
|
-
const dy = p.y - ellipse.center.y;
|
|
758
|
-
const x = c * dx + s * dy;
|
|
759
|
-
const y = -s * dx + c * dy;
|
|
760
|
-
const value = x * x * invRx2 + y * y * invRy2 - 1;
|
|
761
|
-
// grad_world = R * [2x/rx^2, 2y/ry^2]
|
|
762
|
-
const gxLocal = 2 * x * invRx2;
|
|
763
|
-
const gyLocal = 2 * y * invRy2;
|
|
764
|
-
const gx = c * gxLocal - s * gyLocal;
|
|
765
|
-
const gy = s * gxLocal + c * gyLocal;
|
|
766
|
-
return {
|
|
767
|
-
value,
|
|
768
|
-
grad: new Vec2(gx, gy),
|
|
769
|
-
};
|
|
770
|
-
};
|
|
771
|
-
}
|
|
772
|
-
function circleCircleIntersections(c1Center, c1Radius, c2Center, c2Radius) {
|
|
773
|
-
const delta = c2Center.subtracted(c1Center);
|
|
774
|
-
const d = delta.len();
|
|
775
|
-
const eps = Precision.CURVE_LENGTH_EPS;
|
|
776
|
-
if (d <= eps && Math.abs(c1Radius - c2Radius) <= eps) {
|
|
777
|
-
return { kind: 'overlap' };
|
|
778
|
-
}
|
|
779
|
-
if (d <= eps)
|
|
780
|
-
return { kind: 'none' };
|
|
781
|
-
if (d > c1Radius + c2Radius + eps)
|
|
782
|
-
return { kind: 'none' };
|
|
783
|
-
if (d < Math.abs(c1Radius - c2Radius) - eps)
|
|
784
|
-
return { kind: 'none' };
|
|
785
|
-
const a = (c1Radius * c1Radius - c2Radius * c2Radius + d * d) / (2 * d);
|
|
786
|
-
const h2 = c1Radius * c1Radius - a * a;
|
|
787
|
-
if (h2 < -eps)
|
|
788
|
-
return { kind: 'none' };
|
|
789
|
-
const base = c1Center.added(delta.scaled(a / d));
|
|
790
|
-
if (Math.abs(h2) <= eps)
|
|
791
|
-
return { kind: 'points', points: [base] };
|
|
792
|
-
const h = Math.sqrt(Math.max(0, h2));
|
|
793
|
-
const offset = new Vec2(-delta.y / d, delta.x / d).scale(h);
|
|
794
|
-
return {
|
|
795
|
-
kind: 'points',
|
|
796
|
-
points: [base.added(offset), base.subtracted(offset)],
|
|
797
|
-
};
|
|
798
|
-
}
|
|
799
|
-
function isSameSupportCircle(a, b) {
|
|
800
|
-
return a.center.distanceTo(b.center) <= Precision.CURVE_LENGTH_EPS &&
|
|
801
|
-
Math.abs(a.radius - b.radius) <= Precision.CURVE_LENGTH_EPS;
|
|
802
|
-
}
|
|
803
|
-
function createOverlapInfo(c1, c2, point, range1, range2) {
|
|
804
|
-
const u1 = tryParamOnCurve(c1, point);
|
|
805
|
-
const u2 = tryParamOnCurve(c2, point);
|
|
806
|
-
if (u1 === undefined || u2 === undefined)
|
|
807
|
-
return undefined;
|
|
808
|
-
return {
|
|
809
|
-
point,
|
|
810
|
-
u1,
|
|
811
|
-
u2,
|
|
812
|
-
isOverlap: true,
|
|
813
|
-
range1,
|
|
814
|
-
range2,
|
|
815
|
-
};
|
|
816
|
-
}
|
|
817
|
-
function sampleRangeContains(curve, other, sampleCount) {
|
|
818
|
-
const range = curve.getRange();
|
|
819
|
-
let hit = 0;
|
|
820
|
-
let representative;
|
|
821
|
-
for (let i = 0; i <= sampleCount; i++) {
|
|
822
|
-
const t = i / sampleCount;
|
|
823
|
-
const u = range.start + (range.end - range.start) * t;
|
|
824
|
-
const p = curve.pointAt(u);
|
|
825
|
-
const uOther = tryParamOnCurve(other, p);
|
|
826
|
-
if (uOther === undefined)
|
|
827
|
-
continue;
|
|
828
|
-
hit++;
|
|
829
|
-
representative = p;
|
|
830
|
-
}
|
|
831
|
-
return { hit, representative };
|
|
832
|
-
}
|
|
833
|
-
function estimateOverlapRange(base, other, sampleCount) {
|
|
834
|
-
const range = base.getRange();
|
|
835
|
-
let start;
|
|
836
|
-
let end;
|
|
837
|
-
for (let i = 0; i <= sampleCount; i++) {
|
|
838
|
-
const t = i / sampleCount;
|
|
839
|
-
const u = range.start + (range.end - range.start) * t;
|
|
840
|
-
const p = base.pointAt(u);
|
|
841
|
-
if (tryParamOnCurve(other, p) === undefined)
|
|
842
|
-
continue;
|
|
843
|
-
if (start === undefined)
|
|
844
|
-
start = u;
|
|
845
|
-
end = u;
|
|
846
|
-
}
|
|
847
|
-
if (start === undefined || end === undefined)
|
|
848
|
-
return undefined;
|
|
849
|
-
if (Math.abs(end - start) <= Precision.CURVE_PARAM_EPS * 8)
|
|
850
|
-
return undefined;
|
|
851
|
-
return new Interval(start, end);
|
|
852
|
-
}
|
|
853
|
-
function buildLineCandidatesResults(line, target, candidates) {
|
|
854
|
-
const out = [];
|
|
855
|
-
for (const c of candidates) {
|
|
856
|
-
const uTarget = tryParamOnCurve(target, c.point);
|
|
857
|
-
if (uTarget === undefined)
|
|
858
|
-
continue;
|
|
859
|
-
pushUniqueResult(out, {
|
|
860
|
-
point: c.point,
|
|
861
|
-
u1: c.uLine,
|
|
862
|
-
u2: uTarget,
|
|
863
|
-
isOverlap: false,
|
|
864
|
-
});
|
|
865
|
-
}
|
|
866
|
-
return out;
|
|
867
|
-
}
|
|
868
|
-
class ParametricImplicitPairSolver {
|
|
869
|
-
intersect(c1, c2) {
|
|
870
|
-
const param = this.asParam(c1);
|
|
871
|
-
const target = this.asTarget(c2);
|
|
872
|
-
return collectUniqueResults(solveParametricImplicitRoots(param, target, this.makeImplicit(target), this.valueTolScale(target)));
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
export class LineCirclePairSolver {
|
|
876
|
-
intersect(c1, c2) {
|
|
877
|
-
const line = assertLine(c1);
|
|
878
|
-
const circle = assertCircle(c2);
|
|
879
|
-
return buildLineCandidatesResults(line, circle, lineCircleParamIntersections(line, circle.center, circle.radius));
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
export class LineArcPairSolver {
|
|
883
|
-
intersect(c1, c2) {
|
|
884
|
-
const line = assertLine(c1);
|
|
885
|
-
const arc = assertArc(c2);
|
|
886
|
-
return buildLineCandidatesResults(line, arc, lineCircleParamIntersections(line, arc.center, arc.radius));
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
export class LineEllipsePairSolver {
|
|
890
|
-
intersect(c1, c2) {
|
|
891
|
-
const line = assertLine(c1);
|
|
892
|
-
const ellipse = assertEllipse(c2);
|
|
893
|
-
return buildLineCandidatesResults(line, ellipse, lineEllipseParamIntersections(line, ellipse));
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
export class LineEllipseArcPairSolver {
|
|
897
|
-
intersect(c1, c2) {
|
|
898
|
-
const line = assertLine(c1);
|
|
899
|
-
const ellipseArc = assertEllipseArc(c2);
|
|
900
|
-
return buildLineCandidatesResults(line, ellipseArc, lineEllipseParamIntersections(line, ellipseArc));
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
export class LineBSplinePairSolver {
|
|
904
|
-
intersect(c1, c2) {
|
|
905
|
-
const line = assertLine(c1);
|
|
906
|
-
const bspline = assertBSpline(c2);
|
|
907
|
-
return collectUniqueResults(solveLineBSplineRoots(line, bspline));
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
export class CircleCirclePairSolver {
|
|
911
|
-
intersect(c1, c2) {
|
|
912
|
-
const circle1 = assertCircle(c1);
|
|
913
|
-
const circle2 = assertCircle(c2);
|
|
914
|
-
const hit = circleCircleIntersections(circle1.center, circle1.radius, circle2.center, circle2.radius);
|
|
915
|
-
if (hit.kind === 'none')
|
|
916
|
-
return [];
|
|
917
|
-
if (hit.kind === 'overlap') {
|
|
918
|
-
const p = circle1.pointAt(circle1.getRange().start);
|
|
919
|
-
const overlap = createOverlapInfo(circle1, circle2, p, circle1.getRange(), circle2.getRange());
|
|
920
|
-
return overlap ? [overlap] : [];
|
|
921
|
-
}
|
|
922
|
-
const out = [];
|
|
923
|
-
for (const p of hit.points) {
|
|
924
|
-
pushUniqueResult(out, tryBuildPointInfo(circle1, circle2, p));
|
|
925
|
-
}
|
|
926
|
-
return out;
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
export class CircleArcPairSolver {
|
|
930
|
-
intersect(c1, c2) {
|
|
931
|
-
const circle = assertCircle(c1);
|
|
932
|
-
const arc = assertArc(c2);
|
|
933
|
-
if (isSameSupportCircle(circle, arc)) {
|
|
934
|
-
const p = arc.pointAt(arc.getRange().start);
|
|
935
|
-
const uStart = tryParamOnCurve(circle, arc.pointAt(arc.getRange().start));
|
|
936
|
-
const uEnd = tryParamOnCurve(circle, arc.pointAt(arc.getRange().end));
|
|
937
|
-
const range1 = (uStart !== undefined && uEnd !== undefined)
|
|
938
|
-
? new Interval(uStart, uEnd)
|
|
939
|
-
: undefined;
|
|
940
|
-
const overlap = createOverlapInfo(circle, arc, p, range1, arc.getRange());
|
|
941
|
-
return overlap ? [overlap] : [];
|
|
942
|
-
}
|
|
943
|
-
const hit = circleCircleIntersections(circle.center, circle.radius, arc.center, arc.radius);
|
|
944
|
-
if (hit.kind !== 'points')
|
|
945
|
-
return [];
|
|
946
|
-
const out = [];
|
|
947
|
-
for (const p of hit.points) {
|
|
948
|
-
const uArc = tryParamOnCurve(arc, p);
|
|
949
|
-
if (uArc === undefined)
|
|
950
|
-
continue;
|
|
951
|
-
pushUniqueResult(out, tryBuildPointInfo(circle, arc, p));
|
|
952
|
-
}
|
|
953
|
-
return out;
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
export class CircleEllipsePairSolver extends ParametricImplicitPairSolver {
|
|
957
|
-
asParam(curve) { return assertCircle(curve); }
|
|
958
|
-
asTarget(curve) { return assertEllipse(curve); }
|
|
959
|
-
makeImplicit(target) { return ellipseImplicit(target); }
|
|
960
|
-
valueTolScale(target) { return Math.max(target.rx, target.ry); }
|
|
961
|
-
}
|
|
962
|
-
export class CircleEllipseArcPairSolver extends ParametricImplicitPairSolver {
|
|
963
|
-
asParam(curve) { return assertCircle(curve); }
|
|
964
|
-
asTarget(curve) { return assertEllipseArc(curve); }
|
|
965
|
-
makeImplicit(target) { return ellipseImplicit(target); }
|
|
966
|
-
valueTolScale(target) { return Math.max(target.rx, target.ry); }
|
|
967
|
-
}
|
|
968
|
-
export class CircleBSplinePairSolver {
|
|
969
|
-
intersect(c1, c2) {
|
|
970
|
-
const circle = assertCircle(c1);
|
|
971
|
-
const bspline = assertBSpline(c2);
|
|
972
|
-
return intersectImplicitBSplinePair(circle, bspline, circleImplicit(circle), circle.radius);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
export class ArcArcPairSolver {
|
|
976
|
-
intersect(c1, c2) {
|
|
977
|
-
const arc1 = assertArc(c1);
|
|
978
|
-
const arc2 = assertArc(c2);
|
|
979
|
-
if (isSameSupportCircle(arc1, arc2)) {
|
|
980
|
-
const sample1 = sampleRangeContains(arc1, arc2, 64);
|
|
981
|
-
const sample2 = sampleRangeContains(arc2, arc1, 64);
|
|
982
|
-
const sharedCount = Math.max(sample1.hit, sample2.hit);
|
|
983
|
-
if (sharedCount >= 3) {
|
|
984
|
-
const p = sample1.representative ?? sample2.representative ?? arc1.pointAt(arc1.getRange().start);
|
|
985
|
-
const range1 = estimateOverlapRange(arc1, arc2, 128);
|
|
986
|
-
const range2 = estimateOverlapRange(arc2, arc1, 128);
|
|
987
|
-
const overlap = createOverlapInfo(arc1, arc2, p, range1, range2);
|
|
988
|
-
if (overlap)
|
|
989
|
-
return [overlap];
|
|
990
|
-
}
|
|
991
|
-
const out = [];
|
|
992
|
-
const endpoints = [
|
|
993
|
-
arc1.pointAt(arc1.getRange().start),
|
|
994
|
-
arc1.pointAt(arc1.getRange().end),
|
|
995
|
-
arc2.pointAt(arc2.getRange().start),
|
|
996
|
-
arc2.pointAt(arc2.getRange().end),
|
|
997
|
-
];
|
|
998
|
-
for (const p of endpoints) {
|
|
999
|
-
if (tryParamOnCurve(arc1, p) === undefined || tryParamOnCurve(arc2, p) === undefined)
|
|
1000
|
-
continue;
|
|
1001
|
-
pushUniqueResult(out, tryBuildPointInfo(arc1, arc2, p));
|
|
1002
|
-
}
|
|
1003
|
-
return out;
|
|
1004
|
-
}
|
|
1005
|
-
const hit = circleCircleIntersections(arc1.center, arc1.radius, arc2.center, arc2.radius);
|
|
1006
|
-
if (hit.kind !== 'points')
|
|
1007
|
-
return [];
|
|
1008
|
-
const out = [];
|
|
1009
|
-
for (const p of hit.points) {
|
|
1010
|
-
if (tryParamOnCurve(arc1, p) === undefined || tryParamOnCurve(arc2, p) === undefined)
|
|
1011
|
-
continue;
|
|
1012
|
-
pushUniqueResult(out, tryBuildPointInfo(arc1, arc2, p));
|
|
1013
|
-
}
|
|
1014
|
-
return out;
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
export class ArcEllipsePairSolver extends ParametricImplicitPairSolver {
|
|
1018
|
-
asParam(curve) { return assertArc(curve); }
|
|
1019
|
-
asTarget(curve) { return assertEllipse(curve); }
|
|
1020
|
-
makeImplicit(target) { return ellipseImplicit(target); }
|
|
1021
|
-
valueTolScale(target) { return Math.max(target.rx, target.ry); }
|
|
1022
|
-
}
|
|
1023
|
-
export class ArcEllipseArcPairSolver extends ParametricImplicitPairSolver {
|
|
1024
|
-
asParam(curve) { return assertArc(curve); }
|
|
1025
|
-
asTarget(curve) { return assertEllipseArc(curve); }
|
|
1026
|
-
makeImplicit(target) { return ellipseImplicit(target); }
|
|
1027
|
-
valueTolScale(target) { return Math.max(target.rx, target.ry); }
|
|
1028
|
-
}
|
|
1029
|
-
export class ArcBSplinePairSolver {
|
|
1030
|
-
intersect(c1, c2) {
|
|
1031
|
-
const arc = assertArc(c1);
|
|
1032
|
-
const bspline = assertBSpline(c2);
|
|
1033
|
-
return intersectImplicitBSplinePair(arc, bspline, circleImplicit(arc), arc.radius);
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
export class EllipseEllipsePairSolver {
|
|
1037
|
-
intersect(c1, c2) {
|
|
1038
|
-
const e1 = assertEllipse(c1);
|
|
1039
|
-
const e2 = assertEllipse(c2);
|
|
1040
|
-
return solveMutualParametricImplicitRoots(e1, e2, ellipseImplicit(e1), ellipseImplicit(e2), Math.max(e1.rx, e1.ry), Math.max(e2.rx, e2.ry));
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
export class EllipseEllipseArcPairSolver {
|
|
1044
|
-
intersect(c1, c2) {
|
|
1045
|
-
const ellipse = assertEllipse(c1);
|
|
1046
|
-
const ellipseArc = assertEllipseArc(c2);
|
|
1047
|
-
return collectUniqueResults(solveParametricImplicitRoots(ellipse, ellipseArc, ellipseImplicit(ellipseArc), Math.max(ellipseArc.rx, ellipseArc.ry)));
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
export class EllipseBSplinePairSolver {
|
|
1051
|
-
intersect(c1, c2) {
|
|
1052
|
-
const ellipse = assertEllipse(c1);
|
|
1053
|
-
const bspline = assertBSpline(c2);
|
|
1054
|
-
return intersectImplicitBSplinePair(ellipse, bspline, ellipseImplicit(ellipse), Math.max(ellipse.rx, ellipse.ry));
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
export class EllipseArcEllipseArcPairSolver {
|
|
1058
|
-
intersect(c1, c2) {
|
|
1059
|
-
const arc1 = assertEllipseArc(c1);
|
|
1060
|
-
const arc2 = assertEllipseArc(c2);
|
|
1061
|
-
return solveMutualParametricImplicitRoots(arc1, arc2, ellipseImplicit(arc1), ellipseImplicit(arc2), Math.max(arc1.rx, arc1.ry), Math.max(arc2.rx, arc2.ry));
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
export class EllipseArcBSplinePairSolver {
|
|
1065
|
-
intersect(c1, c2) {
|
|
1066
|
-
const ellipseArc = assertEllipseArc(c1);
|
|
1067
|
-
const bspline = assertBSpline(c2);
|
|
1068
|
-
return intersectImplicitBSplinePair(ellipseArc, bspline, ellipseImplicit(ellipseArc), Math.max(ellipseArc.rx, ellipseArc.ry));
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
export class BSplineBSplinePairSolver {
|
|
1072
|
-
intersect(c1, c2) {
|
|
1073
|
-
const bs1 = assertBSpline(c1);
|
|
1074
|
-
const bs2 = assertBSpline(c2);
|
|
1075
|
-
return solveBSplineBSplineRoots(bs1, bs2);
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
export { LineLinePairSolver };
|