using System.Collections.Generic;
using Rhino;
using Rhino.Commands;
using Rhino.Geometry;
namespace ArcLengthReverse
{
public class ArcLengthReverseCommand : Command
{
public ArcLengthReverseCommand()
{
// Rhino only creates one instance of each command class defined in a
// plug-in, so it is safe to store a refence in a static property.
Instance = this;
}
///<summary>The only instance of this command.</summary>
public static ArcLengthReverseCommand Instance
{
get; private set;
}
///<returns>The command name as it appears on the Rhino command line.</returns>
public override string EnglishName
{
get { return "ArcLengthReverseCommand"; }
}
protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
List<Point3d> curvePoints=new List<Point3d>{new Point3d(0,0,0),new Point3d(0,9,0),new Point3d(0,10,0)};
Curve testcrv = new PolylineCurve(curvePoints);
doc.Objects.AddCurve(testcrv);
Point3d testPoint = new Point3d(0, 5, 0);
doc.Objects.AddPoint(testPoint);
//-----------------------------------------------
// getting to the Domain Normalized Value and back again.
// a test point half way up this curve
testcrv.ClosestPoint(testPoint, out double crvParam);
// the parameter for this test point is 0.5555555555555555
RhinoApp.WriteLine($"The parameter on this curve at 0,5,0 = {crvParam}");
double normalizedDomainValue = testcrv.Domain.NormalizedParameterAt(crvParam);
// normalized domain value = 0.2777777777777777 (not 0.5)
RhinoApp.WriteLine($"Domain Normalized Value = {normalizedDomainValue}");
// and back again = 0.5555555555555555
double backparam = testcrv.Domain.ParameterAt(normalizedDomainValue);
RhinoApp.WriteLine($"param on curve back out {backparam}");
// and back to the original point:
Point3d pointOnCrv = testcrv.PointAt(backparam);
RhinoApp.WriteLine($"Point y = {pointOnCrv.Y}");
//---------------------------------------------------
// getting to the Normalized Arc Length Value and back again.
// a test point half way up this curve
testcrv.ClosestPoint(testPoint, out double crvParam1);
// the parameter for this test point is 0.5555555555555555
RhinoApp.WriteLine($"The parameter on this curve at 0,5,0 = {crvParam1}");
// Question revolves around this line:
double normalizedArcLengthValue = testcrv.GetLength(new Interval(testcrv.Domain.Min,crvParam1))/testcrv.GetLength();
// normalized ArcLength Value = 0.5 !!! (Half way along the curve so want 0.5, got it correctly here.)
RhinoApp.WriteLine($"Normalized ArcLength Value = {normalizedArcLengthValue}");
// and back again = 0.5555555555555555
testcrv.NormalizedLengthParameter(normalizedArcLengthValue,out double backparam1);
RhinoApp.WriteLine($"param on curve back out {backparam1}");
// and back to the original point:
Point3d pointOnCrv1 = testcrv.PointAt(backparam1);
RhinoApp.WriteLine($"Point y = {pointOnCrv1.Y}");
doc.Views.Redraw();
return Result.Success;
}
}
}
So we have the functions for normalized domain and back is:
double normalizedDomainValue = testcrv.Domain.NormalizedParameterAt(crvParam);
double backparam = testcrv.Domain.ParameterAt(normalizedDomainValue);
But normalized arc length and back is missing a function: (as far as I can see.)
double normalizedArcLengthValue = testcrv.GetLength(new Interval(testcrv.Domain.Min,crvParam1))/testcrv.GetLength();
testcrv.NormalizedLengthParameter(normalizedArcLengthValue,out double backparam1);
For the Normalized arc length version of this it has always been a little confusing.
I want a function that take a crv param and returns a Normalized Arc Length Parameter from that curve parameter.
And we always make the mistake from its name that curve.NormalizedLengthParameter(double t, out double s); would do this,
but it is actually the function for the other way around function.
NormalizedLengthParameter take a normalized parameter and returns a crv parameter.
And there is no reverse function of this built in.
Which brings us back to:
double normalizedArcLengthValue = testcrv.GetLength(new Interval(testcrv.Domain.Min,crvParam1))/testcrv.GetLength();
So am looking for something like:
double arclengthValue=testcrv.NormalizedArcLengthParameterAt(crvParam);