# Rhinocommon opposite of NormalizedLengthParameter

So is there an opposite function to Curve.NormalizedLengthParameter.

We have a point on a curve as a parameter in the domain of the curve,
and want to get a normalized arc length parameter back from this curve and parameter.

Right now we are using:
double nParam = InCurve.Curve.GetLength(new Interval(InCurve.Curve.Domain.Min, parameterInCurve)) / InCurve.Curve.GetLength();

Which works, just wanting to know if we really have to code this by hand? or am I missing a function to do this somewhere?

Thanks.

Gordon J.

1 Like

Hi @gordon,

If you have curve parameter, which fall within a curve’s domain, and you want it’s normalized form, then use Interval.NormalizedParameterAt.

Likewise, if you have a normalized parameter and you want to convert it to a curve parameter, then use Interval.ParameterAt.

A Python example:

``````import Rhino
import rhinoscriptsyntax as rs

obj_id = rs.GetObject("Select curve")
if rs.IsCurve(obj_id):
crv = rs.coercecurve(obj_id)
dom = crv.Domain
t = (dom.Max + dom.Min) * 0.5
nt = dom.NormalizedParameterAt(t)
print 'Normalized parameter: ', nt
ct = dom.ParameterAt(nt)
print 'Curve parameter: ', ct
``````

Does this help?

– Dale

So I am looking to get from a curve parameter to a normalized arc length value and back again.

you example above is:
parameter to normalized domain parameter and back.
Which is a different thing.

Hi @gordon,

If you have a parameter (of any kind) and you want it normalized, then use the technique I show above.

To get the parameter of the point on the curve that is a prescribed arc length from the start of the curve, then use `Curve.NormalizedLengthParameter`.

I guess I need more information on what you are trying to do - sorry.

– Dale

``````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);

Point3d testPoint = new Point3d(0, 5, 0);

//-----------------------------------------------
// 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);

Hi @gordon,

There isn’t a function to do this. But you can calculate it yourself if needed.

``````// Convert the arc-length parameter to a normalized parameter
var sub_domain = new Interval(curve.Domain.Min, t1);
var sub_length = curve.GetLength(sub_domain);
var length = curve.GetLength();
var s1 = sub_length / length;
RhinoApp.WriteLine(\$"Arc-length parameter = {t1}, normalized parameter = {s1} (+/- {ftol})");
``````

TestGordon.cs (3.0 KB)

– Dale