Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Linearize an exponential function

    Cinema 4D SDK
    c++ sdk
    2
    4
    578
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • mfersaouiM
      mfersaoui
      last edited by mfersaoui

      Hi,
      I have created an user data slider (with percent unit) to controlling subdivisions number of a spline (spline with an Adaptive interpolation). So I have used a MapRange function to convert a percentage to a degree but this dosen't returnning a natural result. because the number of an intermediate subdivision points is increasing exponentially.
      I want to know how to fit an exponential number of intermediate points to a linear.

              SplineObject *sp = SplineObject::Alloc(4, SPLINETYPE_BEZIER); // create a spline with 3 verts
              Vector *gp = sp->GetPointW();
      
              gp[0] = Vector(0, 0, 0);
              gp[1] = Vector(0, 0, 900);
              gp[2] = Vector(0, 250, 1200);
              gp[3] = Vector(0, 900, 1200);
      
              sp->GetDataInstance()->SetBool(SPLINEOBJECT_CLOSED, false);
      
              Float value = data->GetFloat(BSK_OBJECT_CURVE_SUB);
      	Float min_input = 0;
      	Float max_input = 1;
      	Float min_output = 90;
      	Float max_output = 1;
      
      	Float inrange = max_input - min_input;
      	if (CompareFloatTolerant(inrange, 0.0)) value = 0.0;
      	else value = (value - min_input) / inrange;
      	curve_sub = DegToRad(min_output + (max_output - min_output) * value);
      
      	sp->SetParameter(SPLINEOBJECT_ANGLE, curve_sub, DESCFLAGS_SET_0);
      
      1 Reply Last reply Reply Quote 0
      • r_giganteR
        r_gigante
        last edited by r_gigante

        Hi mfersaoui, thanks for reaching out us.

        With regard to your issue I've a few notes:

        • the Adaptive interpolation is by definition strictly dependent on the shape of the spline with regard to the tessellation of the curve: the curve will be tessellated more where the curvature is larger and this generates evidently non-uniform segments distribution - check here for further notes -;
        • standing on the code presented the in_range variable is always 1.0 which makes this
        if (CompareFloatTolerant(inrange, 0.0)) value = 0.0;
        	else value = (value - min_input) / inrange;
        

        pretty useless.

        I would recommend, assuming that the adaptive strategy is the one you want to keep to consider ( sorry for the python code, but porting should be trivial)

                # swap the max/min values of the slider
                val = op[c4d.ID_USERDATA, 1]
                # set the interpolation method
                interp = 3
                # allocate the spline
                spline = c4d.SplineObject(4, c4d.SPLINETYPE_BSPLINE)
                # set interpolation method
                spline[c4d.SPLINEOBJECT_INTERPOLATION] = interp
                # switch according to interpolation method
                if interp == 2: # uniform
                    # set the max number of segs
                    maxSegs = 100
                    spline[c4d.SPLINEOBJECT_SUB] = int(maxSegs * val)
                if interp == 3: # adaptive
                    # get the rad representation of the slider's value
                    radVal = c4d.utils.DegToRad(90 * (1.0 - val))
                    # set the adaptive angle value
                    spline[c4d.SPLINEOBJECT_ANGLE] = radVal
                # set the points
                point = spline.SetAllPoints((c4d.Vector(0,0,0),c4d.Vector(0,0,900),c4d.Vector(0,900,900), c4d.Vector(0,900,0)))
                # return the spline
                return spline
        

        If instead you'd like to linearly increase the subdivision, I warmly recommend to switch to the uniform method and you'll see that a linear behavior is established

        Best, R

        mfersaouiM 2 Replies Last reply Reply Quote 1
        • mfersaouiM
          mfersaoui @r_gigante
          last edited by mfersaoui

          @r_gigante Thank you for the detailed reply,

          Sorry, I didn't put the last part of my code in my question above. I will mention that I want to set a tangent on the points 2 and 3, here is the last part of my code in python:

          curve_offset = op[c4d.BSK_OBJ_CURVE_OFFSET] # correspond to the value "250" in my above code
          spline.SetTangent(1, Vector(0, 0, 0), Vector(0, 0, curve_offset * 0.5))
          spline.SetTangent(2, Vector(0, -curve_offset * 0.5, 0), Vector(0, 0, 0))
          

          So, I try to add the lines above on your code but this returning this error message:

          IndexError: tangent index out of range
          

          Thanks Again.

          1 Reply Last reply Reply Quote 0
          • mfersaouiM
            mfersaoui @r_gigante
            last edited by mfersaoui

            @r_gigante
            Finally I found the solution to linearize the subdivision expansion on Adaptive spline interpolation on the angle deviation.

            I just replaced the line :

            radVal = c4d.utils.DegToRad(90 * (1.0 - val)
            

            By :

            radVal = math.pow(val, -0.85)
            

            I changed also the slider user data unit to REAL
            if I want to keep it with a PERCENT unit I just multiply the value by 100

            radVal = math.pow(val*100, -0.85)
            

            Here is demo:
            ezgif.com-optimize.gif

            1 Reply Last reply Reply Quote 0
            • First post
              Last post