Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

#Polygon in a square with labels science

You have a rectangle, which you will fill with a regular polygon with a specific number of points. Polygon inside rectangle

From each of the points you need to draw of a certain length outside each of the points. Each of these can have different widths. Polygon with labels

If you know the x/y position of each points, and can measure the width of the text, find the largest polygon size you can fit in the rectangle along with the labels at each point. Fitted polygon

Express this as an x position of the centre point, and a distance between the centre of the polygon, and one of the points.

@jolleekin

This comment has been minimized.

Copy link

jolleekin commented Nov 17, 2014

The math to correctly place the labels is

ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var x = center.x + math.cos(angle) * (radius + textWidth / 2); // (*)
var y = center.y + math.sin(angle) * (radius + textHeight / 2); // (**)

Explanation:

First, let's place a point at radius radius and angle angle around the center.

var x = center.x + math.cos(angle) * radius; // (1)
var y = center.y + math.sin(angle) * radius; // (2)

Now, consider a text whose width and height are textWidth and textHeight, respectively.
Equations (1) and (2) define the position of the text's center. Then, we need translate the text's center horizontally by dx pixels and vertically by dy pixels so that the text doesn't overlap the polygon.

At angle 0    : dx = textWidth / 2 , dy = 0
At angle PI/2 : dx = 0             , dy = textHeight / 2
At angle PI   : dx = -textWidth / 2, dy = 0
At angle 3PI/2: dx = 0             , dy = -textHeight / 2

We can easily see that

dx = math.cos(angle) * textWidth / 2; // (3)
dy = math.sin(angle) * textHeight / 2; // (4)

Combine (1) with (3) and (2) with (4), we have (*) and (**).

Next step:

Using this math, you can calculate the smallest bouding box and then adjust the radius to have everything fit inside the container.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.