سؤال

I am implementing a map-like interface for a personal project, in Javascript with HTML5 canvas, and I am mostly looking for ideas on how I could properly tessellate all 2D polygon sides with equal-length rectangles per side. Before explaining further, here are two actual screenshots of the existing interface:

Screenshot
(source: mavrosxristoforos.com)

As you can see, there are "n" rectangles on each of the polygon sides, with length equal to "side's length" divided by "n", and width their length divided by 2. The number of rectangles is user-set. The actual data I have is: the polygon corner coordinates and the number of rectangles. The sides are always populated clockwise.

At the moment, the pseudocode for how they are drawn, looks like this:

RECT_LENGTH = polygon_side_length / count_of_rectangles;
i = first_corner_of_the_polygon_side;
for ( j = 0; j < count_of_rectangles; j++) {
    move pen to i;
    point1 = i + RECT_LENGTH * right_angle_on_polygon_side_slope;
    line to point1;
    point2 = point1 - RECT_LENGTH * polygon_side_slope;
    line to point2;
    i += RECT_LENGTH * polygon_side_slope;
    line to i;
}

It is pretty obvious from the code, that it doesn't take into consideration anything other than the polygon side slope, which is the angle from the horizontal axis, measured in -π (pi) to +π, calculated from the two corner coordinates. There are mainly three appearance problems in these screenshots:

  1. In the upper screenshot, on the left, the big rectangle goes out of the polygon side.
  2. In the upper screenshot, on the bottom right, the rectangles overlap (also on other corners, but that particular one looks completely unnatural).
  3. In the lower screenshot, on the top corner, both sides' rectangles get out of the original polygon.

As a solution, I thought that I could search for a line segment intersection between the current line being drawn and the polygon sides, as well as the previous rectangle, but that doesn't feel right, and it would perform quite slow.

As already mentioned, any idea is welcome. I am not a native English speaker, so please feel free to correct me on my English.

Thank you for your time!

EDIT: I wouldn't mind it if the last rectangle became a trapezoid, just to completely cover the polygon side.

هل كانت مفيدة؟

المحلول

Since you're using rectangles you just can cover right-angled areas. So you have to leave some area of polygons uncovered. You have to reduce the actual length of edges like this:

enter image description here

In this solution you can reduce length of edges just form heads which meet an acute angle. With Alpha as the inner angle of corner, the reduction amount would be Rectangle.Width / Tan(Alpha). It keeps rectangles inside polygon but wont solve the overlap problem.

To prevent rectangles from overlapping you have to leave more area uncovered:

enter image description here

To do this you have to reduce the length of edge form both heads by Rectangle.Width / Tan(Alpha / 2) (Alpha may differ at each corner).

But all of these wont help since width of rectangle is unknown. In fact width of rectangle is calculated by length of edge itself, and we are using it to calculate the length of edge!!

So we have a mathematical problem here:

Known:

L1: actual length of edge
N: number of divisions
Alpha & Beta: half of inner angle of head corners

Unknown:

L2: reduced length of edge
W: width of rectangles

We can form two equations:

(1): L2 = 2 * N * W
(2): L2 = L1 - (W / Tan(Alpha) - (W / Tan(Beta)

By solving them we can find W:

W = L1 / (2 * N + Cot(Alpha) + Cot(Beta))

All these are true in convex polygons. If either head corners of edge are concave you can replace their inner angle with Pi / 2 to prevent reduction from those corners. Please recheck everything! Considering your lovely UI, I suppose you can handle trigonometric calculations for finding start and end point of rectangles.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top