I love city building and transportation games, and ever since I worked on one, I’ve had a side interest in how to represent and draw roads and railroad tracks. After playing lots of Cities XL, I started to wonder how I’d represent curved roads.
The roads in Cities XL aren’t curves. They’re approximations to curves, using short line segments. I noticed in screenshots and videos of SimCity 5 that it also uses short line segments. Is there a way to represent curved roads without turning them into line segments? I wanted to avoid seeing roads like this:
“You see those roads in Hammerfell? They’ve got curved roads. Curved. Roads.”
So I wrote up my notes on circular arcs.
It took much longer than I had planned to write it. I started in October and was hoping to finish in December, but here it is two months later. Why did it take so long?
- I got distracted for several weeks learning about Geometric Algebra. This is a fascinating topic, and potentially useful for a future project, but I couldn’t figure out how to use it for this project.
- I’m quite rusty with math, and there’s some geometry and algebra involved here. The math for biarcs in particular took some time to figure out, with different approaches given in different papers, and none of them giving me everything I needed to know.
- Over the holidays I lost motivation, and ended up spending a month relaxing, hiking, and birdwatching.
Some things that could’ve gone better:
- The way arcs are defined in SVG seems really strange to me. The core definition is ambiguous so they include two extra flags to disambiguate. The way arcs are drawn in Canvas seems more intuitive but I’m guessing SVG’s approach must have some advantages.
- Arc radius goes to infinity for straight roads, which are common. I’m ignoring this to some extent but a real game will have to handle them. An alternative might be using curvature instead of radius, but I didn’t try this.
- IE9 doesn’t like
d3.hsl()
so I instead am usingd3.hsl().toString()
. This would’ve been easier to debug if IE had a nicer inspector. - Android stock browser requires SVG clip paths to be defined inside
<defs>
; I’m not sure if that’s part of the standard but it was annoying to debug. Android’s Chrome and Firefox browsers are more forgiving. - On iOS, large SVG arcs take a really long time to draw, and freeze up the phone. I have not put in a workaround.
- I’ve attempted to automatically adjust the layout for wide vs. narrow browsers, as well as mobile and tablet, but I’m unsatisfied with the results. It’ll have to do for now; I’ll take another look at this later.
It was lots of fun to play with this. However, I think that I may stick to grids for the next game.
Here’s the article about curved roads.
Labels: math
I really don't mind games with "curved" roads that are actually made up by line segments, as long as it is done somewhat smoothly and the overall gameplay is good. I've noticed this in a few games and have never really complained or minded much. But I guess settling for just "okay" isn't good either, so good for you for looking for solutions or better ways of doing things!
"On iOS, large SVG arcs take a really long time to draw, and freeze up the phone. I have not put in a workaround."
If you've got a good example of this running particular bad, I'd be interested to try it with SVGKit (the native SVG renderer we wrote for iOS).
From your description, I suspect the bug is in Apple's browser code (the browser renders SVG internally - it's not supported at OS level), but most of the SVG calls transfer simply to native OS calls (which is what we do in SVGKit).
...if the same problem happens in the native SVGKit, it would point to a bug in Apple's, CoreGraphics - and it might be easier to spot a simple workaround (that could be used in the web version)
PS: in case it wasn't clear, SVGKit is an open-source project, approx 10 regular contributors - https://github.com/SVGKit/SVGKit/
This is great!
Post a Comment