# Generate race track using freeform curves I am trying to generate a race track in Vertex Shader(constraint) and only using B-Spline/Bezier/Hermite curves. My problem is that when i try to widen the obtained curve by translating another instance of it (lets say translate the x value), at certain turns, the road gets thinner.

As input, i can only have a certain number of control points/knots with which to generate a 2-degree closed(start point = end point) curve B-spline. The closed curve (translated on Z) is shown in the picture attached. The camera is positioned right above it. Every vertex from the curve has Y = 0, seeing how the track is flat without any height(no perspective view).

Is there any possible way to keep the road's width on all its sections?

• Can you be more specific? What is the specific implementation you are using (i.e., input data and code) and what is the expected, and actual, output? – user1430 Oct 23 '14 at 22:21
• I added info on input. The main problem is that, given a close curve, how can you generate from it a track that may have U turns, in which case, translating the vertices will not give it any width in those sections? – Rowan Oct 23 '14 at 22:34
• Can you provide pictures? I'm still not clear what you are seeing as a problem. I also don't think it's possible to see how you're arriving at that problem without more information about your specific shader. – user1430 Oct 23 '14 at 22:35
• I have added a picture... it's the track as seen from exactly above it, y = 0 in every vertex. At the far left/right, the track gets thinner. I don't think it is a shader specific problem, more of an mathematical equation or so? – Rowan Oct 23 '14 at 22:49
• That's not a perspective projection, I assume? What is the math you are using to "widen" the spline into vertices? It looks like you're just sampling the spline and widening it by adding +/- some offset to the Y coordinate, rather than trying to offset the split along the normal vector of the spline at the sample point? – user1430 Oct 23 '14 at 22:54

This is a known issue. One of the best and most suitable solution would be to use a library like this one Clipper

There are other known ways that are more complex and not open source yet.

http://www.angusj.com/delphi/clipper.php

Another solution would be to form the track as a spline from Béziers and then convert it to a rigid spline by sampling points along the path. You then use this point with the vector of their approximate direction of flow which could be computer by deducting the previous point from the next point on the road to compute where the left and right sides of the road need to be. To get a smoother result, apply a Bézier on the resulting borders like this: How do I generate a smooth random horizontal 2D tunnel? and add a bit of noise too.  In this step you extend the sampled points on the spline into egdges by picking two points in a 90 degree angle from the direction of the spline. @Trilarion • Great answer! Now one would just need the math to create perpendicular lines of a spline. If I have time I will work it out. – Trilarion Oct 24 '14 at 8:19
• You take a point that is epsilon behind and epsilon ahead of the current one and then compute the angle between them, after that you rotate by 90 degree in each direction. In this case you could take the previously sampled point and the next one. – AturSams Oct 24 '14 at 8:23
• @Trilarion pn+1 is the position of the next point (x, y) and pn-1 is the position of the previous one. :) – AturSams Oct 24 '14 at 8:35
• Thanks for the formula. I wish I could upvote more than once. :) – Trilarion Oct 24 '14 at 8:41
• A good answer indeed, but on Vertex Shader, let's say I can compute the positions of Pn-1 and Pn+1 because i know their gl_VertexID, i compute atan2 and obtain the angle... and then I compute Pn+1 - Pn, i normalize the vector, rotate it by (angle +/- Pi/2) and that gives me the perpendicular position, right? – Rowan Oct 24 '14 at 11:34

Instead of simple shift, you need to widen the track by calculating a perpendicular in every point and shifting the contours along it inside and/or outside. 