I have a custom SpaceMorph that uses curve coordinates to calculate the morphs. It uses common functions like Curve.ClosestPoint, TangentAt, some vector math, etc, and works quite efficiently.
I have added NormalizedLengthParamater as a step to getting the correct coordinates. As simple as this:
curve.ClosestPoint(point, out t);
otherCurve.NormalizedLengthParameter(t, out t);
The second line changes the calculation time from about 2-3 seconds to over 40 seconds.
Setting the fractional tolerance does not seem to be useful. Even a tolerance of 1 takes 14 seconds, and gives an output that is completely wrong, as expected. But other values I tried (0.1, 0.001 and 0.00001) all took so long I had to give up. This is a bit strange.
Is this normal? I know it can be worked around by for example rebuilding the curve uniformly. But my curves non-uniformity conveys important information, and the whole solution uses a mix of morphs that need to fit together, some normalized and some not, so the most convenient method would be to reuse use the same curves and their coordinate systems.
Curve.ClosestPoint returns a curve paraemter, not a normalized parameter.
So maybe something more like this?
if (curve.ClosestPoint(point, out var curve_t))
{
var normalized_t = curve.Domain.NormalizedParameterAt(curve_t);
if (other.NormalizedLengthParameter(normalized_t, out var other_t))
{
// TODO...
}
}
It did help a litte, using NormalizedParameterAt instead of my old method (setting the curve domains to (0,1)) is more efficient. The main problem remains, though. My current code looks like this:
if (uniform)
{
// Set goal t to goal curve length parameter space
GoalCurve.NormalizedLengthParameter(normalized_t, out goal_t);
}
else
{
// Set goal t to goal curve parameter space
goal_t = GoalCurve.Domain.ParameterAt(normalized_t);
}
If uniform is true, my solution runs in 0.8 seconds. If it is false, it runs in 25 seconds. Both solutions look like expected.
Also setting the tolerance to some arbitrary but high value like here just seems to never arrive at a result.
GoalCurve.NormalizedLengthParameter(normalized_t, out goal_t, 0.01);
I have also tried clamping normalized_t between 0 and 1 to make sure no unwanted extrapolation happens anywhere, but it just increased calculation time.
Here is a grasshopper document with a component with the script and toggleable uniform setting. It works like I described above. planarcurvemorph_test.gh (14.1 KB)
The difference in result is not really visible with the curves set as inputs here, but the difference in time is.
I am not using the flow component because this is not being used for a grasshopper definition.
I also do not use FlowSpaceMorph because it does not do exactly what I need. But it seems to do part of it - if I replace my custom space morph with FlowSpaceMorph , FlowSpaceMorph with preventStretching set to false produces the same result as my custom morph with uniform set to true, but much quicker.
So using FlowspaceMorph when uniform is true works for this case, but in my complete solution, I also have a uniform start setting for the starting curve to account for. Which works without problems, it is just calculating normalized_t by measuring the normalized length at t along the curve.
I also am unsure of how the normal of linear curves is defined, so am hesitant to use a morph where it cannot be set explicitly.