[Solved] Help me do math! Spacing points on a line

Okay, so I’m having trouble finishing this one up and could use a hand figuring out this last part. Enjoy a handy Paint drawn graphic:

I have two Vector3s, x and y (1). I want to add points along that line at a spaced interval guided by m (2). m is the maximum distance two points can be from each other.

If m divides into the distance between x and y evenly, everything’s fine (3), and when y is moved enough, an additional point is added (4).

The problem I’m having is that when the distance does not divide by m evenly, the distance between the last point and y is not equal to the distance of all the other points to each other (5).

What I want is to be able to use m as a maxDistance for points to calculate the number of points that will fit on the line. Then use that to place the points evenly across the line (6).

What I have so far:

Vector3 pointX;
Vector3 pointY;
float maxSpacing;

public void DrawLinePoints() {
    float totalLineDistance = Vector3.Distance(pointX, pointY);
    int numberOfPoints = Mathf.FloorToInt(totalLineDistance / maxSpacing);

    // skip 0 to avoid the first point that would be placed at x
    for (int i = 1; i < numberOfPoints; i++) {
        Vector3 pos = GetPointOnLine(pointX, pointY, i / totalLineDistance); // I think this is where my problem is
        Object.Instantiate(pointObj, pos);
    }
}

// normalized distance is a value between 0 and 1 to get a point long the line
private Vector3 GetPointOnLine(Vector3 x, Vector3 y, float normalizedDistance) {
    return x + (y - x) * normalizedDistance;
}

I don’t think the problem is with the GetPointOnLine function, as that seems to be doing its job fine. I feel like I’m not passing the right value into it with that normalized distance, though. I’ve tried calculating the actual point spacing using numberOfPoints with the totalLineDistance again, but I can’t figure out what that math should look like.

get a unit vector from x to y
get the distance from x to y
find how many dots should be on x to y: count = floor(dist/m)
if you always want 1 point, and count is 0, make it 1
n = dist / (count + 1)

float m = *defined*;
Vector3 x = *defined*;
Vector3 y = *defined*;

Vector3 dir = y - x;
float dist = dir.magnitude;
dir.Normalize(); //make unit

int count = Mathf.FloorToInt(dist / m);
if(count == 0) count = 1; //don't do this if you don't want it
float n = dist / (count + 1);

for(int i = 0; i < count; i++)
{
    Vector3 p = x + dir * n * (i + 1);
    //place point p
}

[edit]
my first post wasn’t just right, cleaned up

1 Like

That’s it! Thanks, @lordofduct !

To use my existing code, what I was missing was using the number of calculated points with the distance to calculate the actual spacing, then passing the product of that and i divided by the distance to normalize it into my function. So:

Vector3 pointX;
Vector3 pointY;
float maxSpacing;
public void DrawLinePoints() {
    float totalLineDistance = Vector3.Distance(pointX, pointY);
    int numberOfPoints = Mathf.FloorToInt(totalLineDistance / maxSpacing);
    float actualSpacing = totalLineDistance / numberOfPoints;
    // skip 0 to avoid the first point that would be placed at x
    for (int i = 1; i < numberOfPoints; i++) {
        Vector3 pos = GetPointOnLine(pointX, pointY, i * actualSpacing / totalLineDistance);
        Object.Instantiate(pointObj, pos);
    }
}
// normalized distance is a value between 0 and 1 to get a point long the line
private Vector3 GetPointOnLine(Vector3 x, Vector3 y, float normalizedDistance) {
    return x + (y - x) * normalizedDistance;
}

Works like a charm! Thank you!