Created
July 18, 2014 10:59
-
-
Save icio/0c07b374b222760204fd to your computer and use it in GitHub Desktop.
Fit polygon in box
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9 | |
--> | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset=utf-8 /> | |
<title>Polytext</title> | |
<style type="text/css"> | |
.polytext { | |
float: left; | |
height: 300px; | |
width: 400px; | |
margin: 20px; | |
border: 1px solid black; | |
font-family: Helvetica; | |
font-size: 10px; | |
} | |
</style> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.2/raphael-min.js"></script> | |
<script type="text/javascript"> | |
/** | |
* Render a regular polygon with number of sides equal to the number of | |
* labels. Assumptions | |
* 1. each label exists on only one line; | |
* 2. the first point of the polygon is at the top. | |
* | |
* @param {Array<String>} labels | |
* @param {Number} x | |
* @param {Number} y | |
* @param {Number} height | |
* @param {Number} width | |
* @param {Function} labelSetup | |
*/ | |
function polytext(paper, labels, x, y, width, height, labelSetup, debug) { | |
if (debug) paper.rect(x, y, width, height).attr("stroke", "red"); | |
var n = labels.length; | |
if (n < 3) { | |
throw "Cannot yet handle simpler than triangles"; | |
} | |
var cx = x + width / 2, cy = y + height / 2; | |
// Create and show the labels | |
// var labels = labels.map(function(label) { | |
// return paper.text(0, 0, label); | |
// }); | |
// if (labelSetup) labels.forEach(labelSetup); | |
var na = 2 * Math.PI / n; | |
// The tallest polygon which is going to fit into our bbox. | |
var heightR = (height / 2), topOffset = 0; | |
if (n & 1) { | |
var alpha = na * Math.floor(n / 2); | |
var shortfall = heightR / 2 * (1 + Math.cos(alpha)); | |
heightR += shortfall; | |
topOffset += shortfall; | |
console.log(n, Math.cos(alpha), heightR, shortfall, topOffset); | |
} | |
// heightROffset = (n & 1) * heightR * (1 - Math.cos(na * Math.floor(n / 2))/2), | |
// topOffset = -heightROffset / 2; | |
// heightR += heightROffset; | |
// The largest polygon which is going to fit into our bbox. | |
// We have constrained the radius to that imposed by the width of our | |
// bounding box. The sin calculation is to account for points of our | |
// polygon which do not touch the right-most point of the bounding | |
// circle we are calculating the radius of. | |
var widthR = (width / 2) / Math.sin(na * Math.floor(1 + n / 4)); | |
if (false && widthR < r) { | |
var r = widthR; | |
} else { | |
var r = heightR; | |
cy += topOffset; | |
} | |
if (debug) { | |
var path = "M " + labels.map(function(l, i) { | |
return (cx + r * Math.sin(na * i)) + ", " + | |
(cy + r * -Math.cos(na * i)); | |
}).join(" L ") + " z"; | |
paper.path(path).attr({"stroke": "green", "stroke-width": "2px"}); | |
paper.circle(cx, cy, r).attr("stroke", "green"); | |
} | |
} | |
Raphael(function() { | |
var tests = document.getElementsByClassName("polytext"); | |
for (var i = 0, l = tests.length; i < l; i++) { | |
var test = tests[i]; | |
var labels = JSON.parse(test.getAttribute("data-labels")); | |
var paper = Raphael(test, function() { | |
polytext( | |
this, labels, | |
0.1 * this.width, 0.1 * this.height, 0.8 * this.width, 0.8 * this.height, | |
null, true | |
); | |
}); | |
} | |
}); | |
</script> | |
</head> | |
<body> | |
<div class="polytext" data-labels='["x", "y", "z"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y"]'></div> | |
<div class="polytext" data-labels='["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]'></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment