/// <summary>
 /// Calculates 3d points on a curve where the linear distance between the points is equal.
 /// </summary>
 /// <param name="distance">The distance betwen division points.</param>
 /// <returns>An array of equidistant points, or null on error.</returns>
 public Point3d[] DivideEquidistant(double distance)
 {
   Point3d[] rc = null;
   SimpleArrayPoint3d points = new SimpleArrayPoint3d();
   IntPtr pConstThis = ConstPointer();
   IntPtr pPoints = points.NonConstPointer();
   if (UnsafeNativeMethods.RHC_RhinoDivideCurveEquidistant(pConstThis, distance, pPoints) > 0)
     rc = points.ToArray();
   points.Dispose();
   return rc;
 }
    /// <summary>
    /// Divide the curve into a number of equal-length segments.
    /// </summary>
    /// <param name="segmentCount">Segment count. Note that the number of division points may differ from the segment count.</param>
    /// <param name="includeEnds">If true, then the points at the start and end of the curve are included.</param>
    /// <param name="points">A list of division points. If the function returns successfully, this point-array will be filled in.</param>
    /// <returns>Array containing division curve parameters on success, null on failure.</returns>
    public double[] DivideByCount(int segmentCount, bool includeEnds, out Point3d[] points)
    {
      points = null;

      if (segmentCount < 1)
        return null;

      int tcount = segmentCount - 1;

      if (IsClosed && includeEnds)
        tcount = segmentCount;
      else if (includeEnds)
        tcount = segmentCount + 1;

      double[] rc = new double[tcount];
      IntPtr curve_ptr = ConstPointer();

      SimpleArrayPoint3d outputPoints = new SimpleArrayPoint3d();
      IntPtr outputPointsPtr = outputPoints.NonConstPointer();

      bool success = UnsafeNativeMethods.RHC_RhinoDivideCurve2(curve_ptr, segmentCount, includeEnds, tcount, outputPointsPtr, ref rc[0]);

      if (success)
        points = outputPoints.ToArray();

      outputPoints.Dispose();
      return success ? rc : null;
    }
    /// <summary>
    /// Several types of Curve can have the form of a polyline 
    /// including a degree 1 NurbsCurve, a PolylineCurve, 
    /// and a PolyCurve all of whose segments are some form of 
    /// polyline. IsPolyline tests a curve to see if it can be 
    /// represented as a polyline.
    /// </summary>
    /// <param name="polyline">
    /// If true is returned, then the polyline form is returned here.
    /// </param>
    /// <param name="parameters">
    /// if true is returned, then the parameters of the polyline
    /// points are returned here.
    /// </param>
    /// <returns>true if this curve can be represented as a polyline; otherwise, false.</returns>
    public bool TryGetPolyline(out Polyline polyline, out double[] parameters)
    {
      polyline = null;
      parameters = null;
      SimpleArrayPoint3d outputPts = new SimpleArrayPoint3d();
      int pointCount = 0;
      IntPtr pCurve = ConstPointer();
      IntPtr outputPointsPointer = outputPts.NonConstPointer();
      Rhino.Runtime.InteropWrappers.SimpleArrayDouble tparams = new SimpleArrayDouble();
      IntPtr ptparams = tparams.NonConstPointer();
      UnsafeNativeMethods.ON_Curve_IsPolyline2(pCurve, outputPointsPointer, ref pointCount, ptparams);
      if (pointCount > 0)
      {
        polyline = Polyline.PolyLineFromNativeArray(outputPts);
        parameters = tparams.ToArray();
      }

      tparams.Dispose();
      outputPts.Dispose();
      return (pointCount != 0);
    }
    /// <summary>
    /// Evaluate the derivatives at the specified curve parameter.
    /// </summary>
    /// <param name="t">Curve parameter to evaluate.</param>
    /// <param name="derivativeCount">Number of derivatives to evaluate, must be at least 0.</param>
    /// <param name="side">Side of parameter to evaluate. If the parameter is at a kink, 
    /// it makes a big difference whether the evaluation is from below or above.</param>
    /// <returns>An array of vectors that represents all the derivatives starting at zero.</returns>
    public Vector3d[] DerivativeAt(double t, int derivativeCount, CurveEvaluationSide side)
    {
      if (derivativeCount < 0) { throw new InvalidOperationException("The derivativeCount must be larger than or equal to zero"); }

      Vector3d[] rc = null;
      SimpleArrayPoint3d points = new SimpleArrayPoint3d();
      IntPtr pPoints = points.NonConstPointer();
      if (UnsafeNativeMethods.ON_Curve_Evaluate(ConstPointer(), derivativeCount, (int)side, t, pPoints))
      {
        Point3d[] pts = points.ToArray();
        rc = new Vector3d[pts.Length];
        for (int i = 0; i < pts.Length; i++)
        {
          rc[i] = new Vector3d(pts[i]);
        }
      }
      points.Dispose();
      return rc;
    }
    /// <summary>
    /// Several types of Curve can have the form of a polyline 
    /// including a degree 1 NurbsCurve, a PolylineCurve, 
    /// and a PolyCurve all of whose segments are some form of 
    /// polyline. IsPolyline tests a curve to see if it can be 
    /// represented as a polyline.
    /// </summary>
    /// <param name="polyline">
    /// If true is returned, then the polyline form is returned here.
    /// </param>
    /// <returns>true if this curve can be represented as a polyline; otherwise, false.</returns>
    public bool TryGetPolyline(out Polyline polyline)
    {
      polyline = null;

      SimpleArrayPoint3d outputPts = new SimpleArrayPoint3d();
      int pointCount = 0;
      IntPtr pCurve = ConstPointer();
      IntPtr outputPointsPointer = outputPts.NonConstPointer();

      UnsafeNativeMethods.ON_Curve_IsPolyline2(pCurve, outputPointsPointer, ref pointCount, IntPtr.Zero);
      if (pointCount > 0)
      {
        polyline = Polyline.PolyLineFromNativeArray(outputPts);
      }

      outputPts.Dispose();
      return (pointCount != 0);
    }