I've always sucked at math, but the vector math I'm using right now is going along smoothly. I thought I'd share a bit for my fellow programmers with poor maths.
You can see some of the problems I have encountered here.
the transitions between segments is incorrect, but it turned out to be a logical fix.
The code might be hard to read, but I'll just add it there for completion's sake.
When I was re-factoring my rectangle mesh creation I noticed I was using some pretty inflexible code, the rectangles would only work if their width is longer than their height.
I actually just want to draw a rectangle based on a vector, but I never did anything like that. I was thinking about it for like an hour, the solution was actually super simple.
Let's grab a vector
If you look at the vector, you pretty much just want to extrude the 2 edges outwards, so you get a pretty rectangle.
What you do, is simply grabbing the right perpendicular angle of the vector, and that to the starting and ending points.
do the same thing with the left perpendicular, and add a bunch of points with length X at the end.
Connect all the points, and you have a rectangle
It's height is X / 2, and it's length is the the vector's magnitude.
In my case, the 4 points are the vertices
Vector2 topLeftPoint = currentPoint + (rightPerp.normalized * 1);
Vector2 topRightPoint = nextPoint + (rightPerp.normalized * 1);
Vector2 bottomLeftPoint = currentPoint + (leftPerp.normalized * 1);
Vector2 bottomRightPoint = nextPoint + (leftPerp.normalized * 1);
vertices[ i * 4 ] = new Vector3( topLeftPoint.x, topLeftPoint.y, 0);
vertices[ (i * 4) + 1 ] = new Vector3( topRightPoint.x, topRightPoint.y, 0);
vertices[ (i * 4) + 2 ] = new Vector3( bottomRightPoint.x, bottomRightPoint.y, 0);
vertices[ (i * 4) + 3 ] = new Vector3( bottomLeftPoint.x, bottomLeftPoint.y, 0);
Now we can piece together a bunch of rectangles to make our terrain tool, awesome.
But things don't look quite right.
That's because we need to align point 2 and 3 of rectangle 1 to point 1 and 2 of of rectangle 2. Or in other words, connect the end of rectangle 1, to the start of rectangle 2.
Vector2 prevVec = path.getPos( i ) - path.getPos( i-1 );
Vector2 prevPerpRight = prevVec.rightNormal();
Vector2 prevPerpLeft = prevVec.leftNormal();
topLeftPoint = currentPoint + (prevPerpRight.normalized * 1);
bottomLeftPoint = currentPoint + (prevPerpLeft.normalized * 1);
Looking good, right? Not quite, it's not very noticeable on straight connections, but you can see that something is definitely off on a bend.
This is because we're basing the angle of the connection solely on rectangle 1. While we should take both angles into account.
To be precise;
combinedAngle = vector1.rightPerpendicular.normalized + vector2.leftPerpendicular.normalized.
point2 (most upper point) = rectangleVector.endPoint + combinedAngle * X (for rectangle height);
same thing for the bottom point, but grab the inversed perpendiculars.
if( i > 0 )
Vector2 prevVec = path.getVector( i -1 );
Vector2 curVecReversed = path.getReversedVector( i );
Vector2 averageAngleTop = curVecReversed.leftNormal().normalized + prevVec.rightNormal().normalized;
topLeftPoint = currentPoint + ( averageAngleTop.normalized * 1 );
Vector2 averageAngleBottom = curVecReversed.rightNormal().normalized + prevVec.leftNormal().normalized;
bottomLeftPoint = currentPoint + ( averageAngleBottom.normalized * 1 );
//smooth the end
if( i < path.Length -1 )
Vector2 nextVecReverse = path.getReversedVector( i + 1 );
Vector2 averageAngleTop = nextVecReverse.leftNormal().normalized + rightPerp.normalized;
topRightPoint = nextPoint + (averageAngleTop.normalized * 1);
Vector2 averageAngleBottom = nextVecReverse.rightNormal().normalized + leftPerp.normalized;
bottomRightPoint = nextPoint + ( averageAngleBottom.normalized * 1);
Endresult, pretty connected rectangles, woohoo.
I added some other terrain types aswell.
Far from done, but it's coming along.