Is there a way to get an average "range" between two points in pymel?

73 Views Asked by At

The title may be a bit confusing, so let me put it this way:

I have a polygon strip at a tilted angle, I want to add a curve(in a straight line) that goes through the strip, from start to end, and stays centered in the strip.

I can get the starting point, middle point and endpoint of the strip with the use of these variables:

startPos = polygonStrip.getTranslation() # I've moved the pivot point to be at the base of the strip. This variable is where I want the curve to start.

centerXCoord = pm.objectCenter(polygonStrip,x=True) #this variable gets the center of the strip.

endPos = centerXCoord + (startPos[0]/2) # this variable gets the endpoint. This is where I want the curve to end.

Basically, I want to find a way for all of the curve points to fall between the start and end points evenly so they form a tilted but straight line between them. I've got the Y and Z values working, it's just X that is giving me trouble.

Does anyone have any suggestions? Thank you!

Image to help visualize

1

There are 1 best solutions below

0
On

To summarize you have:

  • a start position (the coords of the start of you strip)
  • a mid position (coords of the "center" of you strip)
  • a end position (coords of the end point of you strip)
  • the number of points you want on your curve (this is something you didn't mention but it's cool if you want to add more precision)

With these parameters we can compute points coords along your strip, to do that we will use a very basic math formula :

# start_point and end_point are 3D point (X,Y,Z)
# ratio_val is a float value between 0.0 and 1.0
start_point + ratio_val(end_point - start_point)

In the function I made below I added multiple early return to avoid unnecessary calculation. I also a lot of comments so you can follow along what the function is doing.

def getCurvePointsCoords(strip_start_pos, strip_mid_pos, strip_end_pos, curve_points_num):
    """Compute the 3D points that constitute the curve

    Args:
        strip_start_pos: 3D starting point of the strip
        strip_mid_pos: 3D middle point of the strip
        strip_end_pos: 3D ending point of the strip
        curve_points_num: Number of points that constitute the curve

    Returns:
        The list of 3D

    """
    if curve_points_num < 2:
        # A valid curve cannot have less than 2 points
        # Maybe raise an exception or print an error /!\
        return []

    if curve_points_num == 2:
        # Only two points, no calculation necessary
        return [strip_start_pos, strip_end_pos]

    if curve_points_num == 3:
        # Only three points, no calculation necessary
        return [strip_start_pos, strip_mid_pos, strip_end_pos]

    curve_mid_value = (curve_points_num - 1) * 0.5
    check_mid_point = curve_mid_value.is_integer()

    # Create the list that we will populate below
    curve_points_coords = []

    # Add the curve start point
    curve_points_coords.append(strip_start_pos)

    # Compute coords of intermediaries points
    for point_index in range(1, (curve_points_num - 1)):
        if check_mid_point and point_index == int(curve_mid_value):
            # The current point is perfectly in the middle of the curve
            curve_points_coords.append(strip_mid_pos)
        elif point_index < curve_mid_value:
            # Point is on the first portion (between strip_start_pos and strip_mid_pos)
            point_pos_ratio = point_index / curve_mid_value
            # Equation is: start_point + ratio_val(end_point - start_point)
            point_coords = strip_start_pos + point_pos_ratio * (strip_mid_pos - strip_start_pos)
            curve_points_coords.append(point_coords)
        else:
            # Point is on the second portion (between strip_mid_pos and strip_end_pos)
            point_pos_ratio = (point_index - curve_mid_value) / curve_mid_value
            # Equation is: start_point + ratio_val(end_point - start_point)
            point_coords = strip_mid_pos + point_pos_ratio * (strip_end_pos - strip_mid_pos)
            curve_points_coords.append(point_coords)

    # Add curve ending point
    curve_points_coords.append(strip_end_pos)

    return curve_points_coords

This is a pure Python function, this means that it work with numpy but also pymel vector (or 3D points).