Python derivativeat

I need python, does it not exist in python?

@ivelin.peychev @ivelin.peychev
Does one of you might know which places the points by length?

EDIT: never mind, I found it from a former post
Curve.PointAtLength Method

You’ll have to normalize the length if I remember correctly, keep that in mind

1 Like

No it seems it can be used without normalizing the length.

1 Like

Great! :slight_smile:

You could also, you know, look up the documentation:

https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_Curve.htm

1 Like

I guess my component seems to work without a slider :slight_smile:

You’re logic is wrong, @ForestOwl! You need to remap your desired distance for each curve from the curve length domain to the curve domain.

Let’s say your desired, random distance for a point on the curve is 2.5, and the domain of the curve is (3.5, 5.0), whereas its length domain is (0.0, 84.856). At the moment, you try to create a point at the curve parameter 2.5, which doesn’t exist. This makes your point appear somewhere else.
Instead, you simply remap your distance to the curve domain. For this example, that should be a curve parameter of 3.544… that fits on your curve, since it’s included in the curve domain!

import Rhino.Geometry as rg
import random

random.seed(2)

def fit(value, source_domain, target_domain):
    """Fits a number between a target domain that is relative to a number in the source domain.
    
    Args:
        value: number to be fitted
        source_domain: tuple containing the domain start and end
        target_domain: tuple containing the domain start and end
    
    Returns:
        The refitted value, or None, if the initial value is outside the source domain.
    """
    if (value < source_domain[0]) or (value > source_domain[1]):
        return
    else:
        source_range = source_domain[1] - source_domain[0]
        if source_range == 0:
            fitted_value = target_domain[0]
        else:
            target_range = target_domain[1] - target_domain[0]
            fitted_value = (((value - source_domain[0]) * target_range) / source_range) + target_domain[0]
        return fitted_value


curr_plane = Planes[0]
curr_crv = Curves[0]
min_dist, max_dist = DistInterval

# Get the curve length
crv_len = curr_crv.GetLength()
# Get the curve domain
crv_dom = curr_crv.Domain

curr_dist = 0.0 # current desired distance
crv_parameters = [] # curve parameters
div_pts = [] # curve division points

while curr_dist < crv_len:
    # Remap the desired distance to the curve domain
    crv_param = fit(curr_dist, (0.0, crv_len), crv_dom)
    # Check if curve parameter hasn't been visited yet
    if crv_param not in crv_parameters:
        # Get the curve point for the curve parameter
        pt = curr_crv.PointAt(crv_param)
        # Add the curve point to the division points list
        div_pts.append(pt)
        # Add the curve parameter to the curve parameters list as history entry
        crv_parameters.append(crv_param)
    # Randomly increment the current desired distance
    curr_dist += random.randint(min_dist, max_dist)


# --- OUTPUTS
a = div_pts

problem derivativeat 08.gh (16.4 KB)

No, this wouldn’t work either! When normalising the curve domain or curve length, you still have to remap your distance to the normalised domain, when it’s not between 0.0 and 1.0.

2 Likes

:slight_smile: it’s been a while since I last work on this I do not remember every detail

PointAt has nothing to do with curve length. PointAt is related to curve parameter. You should use PointAtLength if length is an important condition in defining your point locations.

You don’t. That’s what PointAtNormalizedLength is for.
https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_Curve_PointAtNormalizedLength.htm

How’s that component different from grasshoppers evaluate length?

It re-adjusts the min and max of the slider to correspond to the curve’s length :wink:

But I noticed a bug with when given length is zero. I’ll have to fix that. I guess David has fixed one bug in GH with rounding floats and that affected my component.

Seems anti-parametric. The solution should be generate random numbers first of all only in the domain of 0-1 rather than this remap buisness and then use PointAtNormalizedLength.

:stuck_out_tongue_winking_eye: so my recollection was correct.

RTFM maybe :man_shrugging:t2:

Difficult to use C# api documentation as Python Manual!

If you are using rhinocommon, the documentation of what’s available is the same. It’s still Curve.PointAtLength(length) in both languages.

1 Like

well this is certainly getting off topic…but, a ridiculously useful resource, (when trying to work through a particular rhinocommon method), is to look at the rhinoscriptsyntax python files. (which are all locally available on your workstation). for example, look up the unrollsrf function, and try to convert that to a GHPython component, (it takes like 3 or 4 lines). The unroller class documentation does not have a specific python example…but it’s LITERALLY written out in the Rhinoscriptsyntax files…which are all python. I guarantee you will learn something new. If one is developing something, I think it’s that persons responsibility to dig a bit/research, to fully understand the process and how it’s working/intended to work.
// my .02 cents.

1 Like

That I can agree with.

I do this a lot when I get stuck trying to figure out RhinoCommon’s way by just looking at the documentation.