前のapproachは機能していないようで、ソリューションはやや複雑なので、もう少し簡単なアプローチを試してみました。円に六角形を塗りつぶす(別のアプローチ)
今回は、コードが六角形を描画する前に、あらかじめ定義された円にいくつの行と列が収まるかを決定し、この結果に基づいてすべての六角形の描画を開始します。
これまでのところ、これまでのアプローチのように、ヘックスが重なったり、円の下部に大きな隙間が残ったりすることがあります。
また、これらの六角形をグリッドにフォーマットするにはどうすればいいですか?
円の半径を増減することができ、六角形を再描画できる小さなスライダがキャンバスの下にあります。
var c_el = document.getElementById("myCanvas");
var ctx = c_el.getContext("2d");
var canvas_width = c_el.clientWidth;
var canvas_height = c_el.clientHeight;
var circle = {
\t r: 120, /// radius
\t pos: {
\t \t x: (canvas_width/2),
\t \t y: (canvas_height/2)
\t }
}
var hexagon = {
\t r: 20,
\t pos:{
\t \t x: 0,
\t \t y: 0
\t }
}
var hex_w = hexagon.r * 2;
var hex_h = Math.floor(Math.sqrt(3) * hexagon.r);
var hex_s = (3/2) * hexagon.r;
fill_CircleWithHex(circle);
function fill_CircleWithHex(circle){
\t drawCircle(circle);
\t
\t var c_h = circle.r * 2; /// circle height ////
\t var c_w = c_h; //// circle width /////
\t
\t var max_hex_H = Math.round(c_h/hex_h);
\t
\t var row_sizes = []
\t for(var row= 0; row< max_hex_H; row++){
\t \t
\t \t var d = circle.r - (row* hex_h); //// distance from circle's center to the row's chord ////
\t \t var c = 2 * (Math.sqrt((circle.r*circle.r) - (d * d))); /// length of the row's chord ////
\t \t var row_length = Math.floor(c/(hexagon.r * 3));
\t \t row_sizes.push(row_length )
\t }
\t
\t console.log("circle_r : "+circle.r);
\t console.log("hex_r : "+hexagon.r);
\t console.log("max_hex_H : "+max_hex_H);
\t console.log("max_hex_W : ", row_sizes)
\t for(var row = 0; row < row_sizes.length; row++){
\t \t var max_hex_W = row_sizes[row];
\t \t
\t \t var x_offset = Math.floor((c_w - (max_hex_W * hex_w))/2);
\t \t
\t \t for(var col = 1; col < max_hex_W; col++){
\t \t \t hexagon.pos.x = (col * hex_w) + (circle.pos.x - circle.r) + x_offset ;
\t \t \t hexagon.pos.y = (row * hex_h) + (circle.pos.y - circle.r);
\t \t \t ctx.fillText(row+""+col, hexagon.pos.x - 6, hexagon.pos.y+4);
\t \t \t drawHexagon(hexagon)
\t \t }
\t }
}
function drawHexagon(hex){
\t var angle_deg, angle_rad, cor_x, cor_y;
\t ctx.beginPath();
\t for(var c=0; c <= 5; c++){
\t \t angle_deg = 60 * c;
\t \t angle_rad = (Math.PI/180) * angle_deg;
\t \t cor_x = hex.r * Math.cos(angle_rad); //// corner_x ///
\t \t cor_y = hex.r* Math.sin(angle_rad); //// corner_y ///
\t \t if(c === 0){
\t \t \t ctx.moveTo(hex.pos.x+ cor_x, hex.pos.y+cor_y);
\t \t }else{
\t \t \t ctx.lineTo(hex.pos.x+cor_x, hex.pos.y+cor_y);
\t \t }
\t }
\t ctx.closePath();
\t ctx.stroke();
}
function drawCircle(circle){
\t ctx.beginPath();
\t ctx.arc(circle.pos.x, circle.pos.y, circle.r, 0, 2 * Math.PI);
\t ctx.stroke();
}
$(function() {
$("#slider").slider({
\t \t max: 200,
\t \t min:0,
\t \t value:100,
\t \t create: function(event, ui) {
\t \t \t $("#value").html($(this).slider('value'));
\t \t },
\t \t change: function(event, ui) {
\t \t \t $("#value").html(ui.value);
\t \t },
\t \t slide: function(event, ui){
\t \t \t $("#value").html(ui.value);
\t \t \t circle.r = ui.value;
\t \t \t ctx.clearRect(0,0, canvas_width, canvas_height);
\t \t \t fill_CircleWithHex(circle);
\t \t }
\t });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<canvas id="myCanvas" width="350" height="250" style="border:1px solid #d3d3d3;"> </canvas>
<div style="width: 200px; height: 40px;">
\t <div id="slider" style="position:relative; width: 150px; top: 4px;float: left;"></div> <div id="value" style="float: left;"> 0 </div>
</div>
私は混乱しています。六角形と円のサイズはどちらも指定できますか?あなたは問題をより正確に述べることができますか?ハードな制約と最大限にしようとしていることは何ですか? –
ハードな拘束は円のサイズで、これに基づいて六角形のグリッドが生成されます。 – Alexus
六角形のように見えるだけですか?六角形は番号を付ける必要がありますか?私はちょうど六角形のスタイルを生成するスマートCSSの背景を適用することを考えています。 – Paul