Draw crosswalks in detail with the JavaScript canvas

Recently, In my work, I try to draw a crossroad with zebra lines and traffic light directions. It's quite tricky and takes me lots of time. So, Here is a paragraph to record and share the experience.

Frist of all, Let's see what kind of data we have. In the picture below, the left side is the data, and the right side is what we want.

https://static.zhuwenlong.com/upload/image/1509690126944-20171103-1.png?imageView2/0/w/900/

In fact, we have two kinds of data, center and the roads. In this case, our center is [116.159005, 40.1233605] and the other four roads are [-79.56, -91.27], [71.41, 83.24], [178.74, -38.50], [-110.2.72, 38.03]. To make it easy, we need to normalize the data. We define the center is [0, 0], So, other roads' coordinate should minus 116.159005 in X-axis, and minus 40.1233605 in the y-axis.

After that, let's make radial from center to every road point, and set the radial with a width. To make it easier to be understood, we get this picture.

https://static.zhuwenlong.com/upload/image/1509691616255-2.png?imageView2/0/w/900/

And in other situations, we may have:

https://static.zhuwenlong.com/upload/image/1509691759423-3.png

https://static.zhuwenlong.com/upload/image/1509691789621-4.png

Now, let's think about the real crossroad. Usually, it has a zebra line on each road close to the center. It allows the pedestrian to go across the road. So, if we get the cross point on both sides of each road which crosses with other roads and connect the two points, it brings us the zebra line!

But how can we get the two crosspoints on both sides of the road? Yes, you're right, If we sort the road by its angle with the positive x-axis(in fact you can choose any axis), you can easily find the previous and the next road. It can help us to figure out the crosspoint. For the first picture, the correct index of the road is 2, 1, 3, 0.

We have the sorted roads with the angle and width. Now, let's figure out the crosspoint. I'll show you another picture to explain how to make it!

https://static.zhuwenlong.com/upload/image/1509694632931-4.png

We take road 2 and road 1 for example. In the picture, the yellow angle is the road 2's angle. The violet angle is the road 1's angle. The [x, y] is what we need. If we make a perpendicular line on the road 2, you'll find that the vertical line's width equals the half of the road width. And in the red right triangle, you can quickly get the angle by using (胃2 - 胃1) / 2.

Overall the formula we use is: sin胃 = y / Math.sqrt(x**2 + y**2) cos胃 = x / Math.sqrt(x**2 + y**2)

And we got this four red points:

https://static.zhuwenlong.com/upload/image/1509696361421-5.png

Zebra line is coming!

How to draw the zebra line? The first idea comes to my mind is:

https://static.zhuwenlong.com/upload/image/1509697211216-6.png

We are going to get every point of the zebra line like A1, A2 ... B1, B2 ... . But What the hell! It's so complicated to get all the zebra points.

But! The good news is that we DON'T NEED to do this.

https://static.zhuwenlong.com/upload/image/1509697737386-7.png

We can compute the center of the zebra, translate and rotate the canvas to make the zebra horizontal, and make the canvas's center is the zebra's center. After this transform, you can do everything quickly!

Finally, we got the cross, like this.

https://static.zhuwenlong.com/upload/image/1509698015365-8.png

Good Job, congratulations!

BUT ...

We still have some bad cases like these:

https://static.zhuwenlong.com/upload/image/1509698109152-9.png

It looks weird, especially at the bottom of this road. That's because we use two road's crosspoint to draw the zebra line. It works in most of the situations, but if the two road's angle is too big, let's say more than 160deg, those two roads are nearly straight. But in the straight road, the zebra line always goes to the other side vertical. So we should deal with this situation. If the two roads are nearly straight, we use different rules to make the zebra line go to the other side vertically.

https://static.zhuwenlong.com/upload/image/1509699435218-10.png?imageView2/0/w/900/

Thus, we got a beautiful crossroad, but we still have some small problems, I will not write in this article bacuse of the article's limit. Still if you are interested in this topic, you can live message under this article, we can have further discussion.

78260
  • logo
    • HI, THERE!I AM MOFEI

      (C) 2010-2024 Code & Design by Mofei

      Powered by Dufing (2010-2020) & Express

      IPC证:沪ICP备2022019571号-1