Divide Curve Straight

Demonstrates how to divide a curve using equi-distance points.

partial class Examples
{
  private static void NextintersectParamAndPoint(Curve[] overlapCurves, Point3d[] intersectPoints,
    Curve curve, out double intersectParam, out Point3d intersectPoint)
  {
    var intersect_params_and_points = new Dictionary<double, Point3d>();
    foreach (var point in intersectPoints)
    {
      double curve_param;
      curve.ClosestPoint(point, out curve_param);
      intersect_params_and_points[curve_param] = point;
    }
    foreach (var overlap_curve in overlapCurves)
    {
      intersect_params_and_points[overlap_curve.Domain.Min] = overlap_curve.PointAt(overlap_curve.Domain.Min);
      intersect_params_and_points[overlap_curve.Domain.Max] = overlap_curve.PointAt(overlap_curve.Domain.Max);
    }
    var min_t = intersect_params_and_points.Keys.Min();
    intersectParam = min_t;
    intersectPoint = intersect_params_and_points[intersectParam];
  }

  public static Result DivideCurveStraight(RhinoDoc doc)
  {
    // user input
    ObjRef[] obj_refs;
    var rc = RhinoGet.GetMultipleObjects("Select curve to divide", false,
      ObjectType.Curve | ObjectType.EdgeFilter, out obj_refs);
    if (rc != Result.Success || obj_refs == null)
      return rc;

    double distance_between_divisions = 5;
    rc = RhinoGet.GetNumber("Distance between divisions", false,
      ref distance_between_divisions, 1.0, Double.MaxValue);
    if (rc != Result.Success)
      return rc;

    // generate the points
    var points = new List<Point3d>();
    foreach (var obj_ref in obj_refs)
    {
      var curve = obj_ref.Curve();
      if (curve == null) return Result.Failure;

      var t0 = curve.Domain.Min;
      points.Add(curve.PointAt(t0));

      var sphere_center = curve.PointAt(t0);
      var t = t0;
      var rest_of_curve = curve;
      while (true)
      {
        var sphere = new Sphere(sphere_center, distance_between_divisions);
        Curve[] overlap_curves;
        Point3d[] intersect_points;
        var b = Intersection.CurveBrep(rest_of_curve, sphere.ToBrep(), 0.0,
          out overlap_curves, out intersect_points);
        if (!b || (overlap_curves.Length == 0 && intersect_points.Length == 0))
          break;
        double intersect_param;
        Point3d intersect_point;
        NextintersectParamAndPoint(overlap_curves, intersect_points, rest_of_curve,
          out intersect_param, out intersect_point);
        points.Add(intersect_point);
        t = intersect_param;
        sphere_center = intersect_point;
        rest_of_curve = curve.Split(t)[1];
      }
    }

    foreach (var point in points)
      doc.Objects.AddPoint(point);

    doc.Views.Redraw();
    return Result.Success;
  }
}
import rhinoscriptsyntax as rs
import Rhino
from Rhino.Input import *
from Rhino.DocObjects import *
from Rhino.Commands import *
from Rhino.Geometry import *
from Rhino.Geometry.Intersect import *

def nextIntersectParamAndPoint(overlapCurves, intersectPoints, curve):
    intersectParamsAndPoints = [(curve.ClosestPoint(point)[1], point) for point in intersectPoints]
    for overlapCurve in overlapCurves:
        intersectParamsAndPoints.append((overlapCurve.Domain.Min, overlapCurve.PointAt(overlapCurve.Domain.Min)))
        intersectParamsandPoints.append((overlapCurve.Domain.Max, overlapCurve.PointAt(overlapCurve.Domain.max)))
    return min(intersectParamsAndPoints, key =  lambda t: t[0])

def divide_curve():
    # get user input
    res, obj_refs = RhinoGet.GetMultipleObjects("Curves to divide",
        False, ObjectType.EdgeFilter | ObjectType.Curve)
    if res != Result.Success: return res
    curves = [obj_ref.Curve() for obj_ref in obj_refs]

    distance_between_divisions = rs.GetReal(
        message = "Distance between divisions",
        number = 5.0, minimum = 1.0)
    if distance_between_divisions == None: return

    # generate the points
    points = []
    for curve in curves:
        t0 = curve.Domain.Min
        points.append(curve.PointAt(t0))

        sphere_center = curve.PointAt(t0)
        t = t0
        rest_of_curve = curve
        while True:
            sphere = Sphere(sphere_center, distance_between_divisions)
            b, overlapCurves, intersectPoints = Intersection.CurveBrep(rest_of_curve, sphere.ToBrep(), 0.0)
            if b == False or (overlapCurves.Length == 0 and intersectPoints.Length == 0):
                break
            t, point = nextIntersectParamAndPoint(overlapCurves, intersectPoints, rest_of_curve)
            points.append(point)
            sphere_center = point
            rest_of_curve = curve.Split(t)[1]

    rs.AddPoints(points)
    rs.Redraw()

if __name__ == "__main__":
    divide_curve()