2016-02-26 22 views
13

Poiché il mio precedente approach non sembra funzionare e una soluzione sarebbe piuttosto complessa, ho deciso di provare un altro approccio che potrebbe essere un po 'più semplice.cerchio di riempimento con esagoni (approccio diverso)

Questa volta, prima che il codice disegna un esagono, deve determinare quante righe e colonne possono rientrare nel cerchio predefinito e in base a questo risultato inizia quindi a disegnare tutti gli esagoni.

Finora si tratta di un tipo di lavoro, ma come nel mio precedente approccio, ci sono momenti in cui gli esagoni si sovrappongono o lasciano un grande spazio nella parte inferiore del cerchio.

Un'altra preoccupazione è, come posso formattare questi esagoni in una griglia?

Nota, c'è un piccolo dispositivo di scorrimento sotto la tela, che consente di aumentare/diminuire il raggio del cerchio e ridisegnare gli esagoni.

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>

+0

Sono confuso. Le dimensioni di entrambi esagono e cerchio sono date? Puoi dire il problema più precisamente? Quali sono i vincoli e cosa stai cercando di massimizzare. –

+0

il vincolo rigido è la dimensione del cerchio, in base a ciò viene generata la griglia esagonale. – Alexus

+0

Deve solo sembrare un modello esagonale? Gli esagoni devono essere numerati? Sto pensando di applicare solo sfondi css intelligenti per generare uno stile esagonale. – Paul

risposta

6

La seguente risolve il problema dell'imballaggio per una struttura a nido d'ape regolare centrata sulla mezzeria del cerchio. Mezzi regolari:

  • l'insieme di tutti gli esagoni è simmetrico con rotazioni di 60 gradi attorno al centro del cerchio.

Le coordinate dei singoli esagoni rappresentano il numero ordinale del guscio esagonale contrastato dal centro e il numero di sequenza in senso orario che inizia a mezzogiorno.

Man mano che il cerchio si allarga, i nuovi gusci esagonali non vengono necessariamente riempiti nel loro complesso. Sebbene il grado di libertà di riempire il guscio esterno produca in parte una soluzione migliorata, non è ancora ottimale. Rilassando la regolarità a simmetrie rotazionali con angoli diversi da 60 gradi (cioè 120 e 180 gradi) si otterrà una maggiore copertura dell'interno del cerchio.

Analizzerò la matematica dietro a ciò per la prossima revisione di questo codice (e possibilmente troverò un teorema per dimostrare che la simmetria rotazionale attorno al punto di mezzo del cerchio è una condizione necessaria per l'ottimalità).

var c_el; 
 
var ctx; 
 
var canvas_width; 
 
var canvas_height; 
 
var circle; 
 
var hexagon; 
 
var hex_w; 
 
var hex_h; 
 
var hex_s; 
 
var delta; 
 

 
function drawHexagonAt (po_ctr_hex, pn_circle, pn_sector) { 
 
    var cur 
 
     ; 
 
     
 
    cur = { x: po_ctr_hex.x - 0.5 * hexagon.r, y: po_ctr_hex.y - delta }; 
 
    
 
    ctx.beginPath(); 
 
    ctx.moveTo(cur.x, cur.y); 
 
    cur.x = cur.x + hexagon.r; 
 
    cur.y = cur.y; 
 
    ctx.lineTo(cur.x, cur.y); 
 
    cur.x = cur.x + hexagon.r/2; 
 
    cur.y = cur.y + delta; 
 
    ctx.lineTo(cur.x, cur.y); 
 
    cur.x = cur.x - hexagon.r/2; 
 
    cur.y = cur.y + delta; 
 
    ctx.lineTo(cur.x, cur.y); 
 
    cur.x = cur.x - hexagon.r; 
 
    cur.y = cur.y; 
 
    ctx.lineTo(cur.x, cur.y); 
 
    cur.x = cur.x - hexagon.r/2; 
 
    cur.y = cur.y - delta; 
 
    ctx.lineTo(cur.x, cur.y); 
 
    cur.x = cur.x + hexagon.r/2; 
 
    cur.y = cur.y - delta; 
 
    ctx.lineTo(cur.x, cur.y); 
 
\t ctx.closePath(); 
 
\t ctx.stroke(); 
 

 
    cur.x = cur.x + hexagon.r/2; 
 
    cur.y = cur.y + delta; 
 
\t ctx.fillText(pn_circle + "/" + pn_sector, cur.x-6, cur.y+4); 
 
} // drawHexagonAt 
 

 
function fill_CircleWithHex(circle){ 
 
\t drawCircle(circle); 
 
\t 
 
\t var radacc2; 
 
\t var iter = 0; 
 
\t var sector = 0; 
 
\t var i, j; 
 
\t var ctr  = { x: circle.pos.x , y: circle.pos.y }; 
 
\t var cur  = { x: 0   , y: 0 }; 
 
\t 
 
\t delta = Math.floor(Math.sqrt(3) * 0.5 * hexagon.r); 
 
    radacc2 = hexagon.r * hexagon.r; 
 
\t while ((radacc2 < circle.r * circle.r)) { 
 
\t  cur.x = ctr.x; 
 
\t  cur.y = ctr.y - iter * 2 * delta; 
 
\t  
 
\t  if (iter === 0) { 
 
\t   drawHexagonAt (cur, 0, 0); 
 
\t  } 
 
\t  else { 
 
    \t  for (var i=0; i < 6; i++) { 
 
    \t   // j-loops -- next honeycomb 
 
    \t   sector = 0; 
 
    \t   for (var j=0; j < iter; j++) { 
 
    \t    cur.x = cur.x + 1.5 * hexagon.r; 
 
    \t    cur.y = cur.y + delta; 
 
    \t    drawHexagonAt (cur, iter, sector++); 
 
    \t   } 
 
    \t   for (var j=0; j < iter; j++) { 
 
    \t    cur.x = cur.x; 
 
    \t    cur.y = cur.y + 2 * delta; 
 
    \t    drawHexagonAt (cur, iter, sector++); 
 
    \t   } 
 
    \t   for (var j=0; j < iter; j++) { 
 
    \t    cur.x = cur.x - 1.5 * hexagon.r; 
 
    \t    cur.y = cur.y + delta; 
 
    \t    drawHexagonAt (cur, iter, sector++); 
 
    \t   } 
 
    \t   for (var j=0; j < iter; j++) { 
 
    \t    cur.x = cur.x - 1.5 * hexagon.r; 
 
    \t    cur.y = cur.y - delta; 
 
    \t    drawHexagonAt (cur, iter, sector++); 
 
    \t   } 
 
    \t   for (var j=0; j < iter; j++) { 
 
    \t    cur.x = cur.x; 
 
    \t    cur.y = cur.y - 2 * delta; 
 
    \t    drawHexagonAt (cur, iter, sector++); 
 
    \t   } 
 
    \t   for (var j=0; j < iter; j++) { 
 
    \t    cur.x = cur.x + 1.5 * hexagon.r; 
 
    \t    cur.y = cur.y - delta; 
 
    \t    drawHexagonAt (cur, iter, sector++); 
 
    \t   } 
 
    \t  } // i-loop -- meta-honeycomb 
 
    \t } // if -- Iteration 1 vs. n > 1 
 
    \t  
 
    \t  // radacc update 
 
    \t  iter++; 
 
     radacc2 = ((2*iter + 1) * delta) * ((2*iter + 1) * delta) + hexagon.r * hexagon.r/4; 
 
    } // while -- komplette Shells 
 
    
 
    // 
 
    // Partielle Shells 
 
    // 
 
    var proceed; 
 
    do { 
 
\t  cur.x = ctr.x; 
 
\t  cur.y = ctr.y - iter * 2 * delta; 
 
     proceed = false; 
 

 
\t  for (var i=0; i < 6; i++) { 
 
\t   // j-loops -- next honeycomb 
 
\t   sector = 0; 
 
\t   for (var j=0; j < iter; j++) { 
 
\t    cur.x = cur.x + 1.5 * hexagon.r; 
 
\t    cur.y = cur.y + delta; 
 
\t    sector++ 
 
\t    if (Math.sqrt ((cur.x - ctr.x) * (cur.x - ctr.x) + (cur.y - ctr.y) * (cur.y - ctr.y)) + hexagon.r < circle.r) { 
 
\t     drawHexagonAt (cur, iter, sector); 
 
\t     proceed = true; 
 
\t    } 
 
\t   } 
 
\t   for (var j=0; j < iter; j++) { 
 
\t    cur.x = cur.x; 
 
\t    cur.y = cur.y + 2 * delta; 
 
\t    sector++ 
 
\t    if (Math.sqrt ((cur.x - ctr.x) * (cur.x - ctr.x) + (cur.y - ctr.y) * (cur.y - ctr.y)) + hexagon.r < circle.r) { 
 
\t     drawHexagonAt (cur, iter, sector); 
 
\t     proceed = true; 
 
\t    } 
 
\t   } 
 
\t   for (var j=0; j < iter; j++) { 
 
\t    cur.x = cur.x - 1.5 * hexagon.r; 
 
\t    cur.y = cur.y + delta; 
 
\t    sector++ 
 
\t    if (Math.sqrt ((cur.x - ctr.x) * (cur.x - ctr.x) + (cur.y - ctr.y) * (cur.y - ctr.y)) + hexagon.r < circle.r) { 
 
\t     drawHexagonAt (cur, iter, sector); 
 
\t     proceed = true; 
 
\t    } 
 
\t   } 
 
\t   for (var j=0; j < iter; j++) { 
 
\t    cur.x = cur.x - 1.5 * hexagon.r; 
 
\t    cur.y = cur.y - delta; 
 
\t    sector++ 
 
\t    if (Math.sqrt ((cur.x - ctr.x) * (cur.x - ctr.x) + (cur.y - ctr.y) * (cur.y - ctr.y)) + hexagon.r < circle.r) { 
 
\t     drawHexagonAt (cur, iter, sector); 
 
\t     proceed = true; 
 
\t    } 
 
\t   } 
 
\t   for (var j=0; j < iter; j++) { 
 
\t    cur.x = cur.x; 
 
\t    cur.y = cur.y - 2 * delta; 
 
\t    sector++ 
 
\t    if (Math.sqrt ((cur.x - ctr.x) * (cur.x - ctr.x) + (cur.y - ctr.y) * (cur.y - ctr.y)) + hexagon.r < circle.r) { 
 
\t     drawHexagonAt (cur, iter, sector); 
 
\t     proceed = true; 
 
\t    } 
 
\t   } 
 
\t   for (var j=0; j < iter; j++) { 
 
\t    cur.x = cur.x + 1.5 * hexagon.r; 
 
\t    cur.y = cur.y - delta; 
 
\t    sector++ 
 
\t    if (Math.sqrt ((cur.x - ctr.x) * (cur.x - ctr.x) + (cur.y - ctr.y) * (cur.y - ctr.y)) + hexagon.r < circle.r) { 
 
\t     drawHexagonAt (cur, iter, sector); 
 
\t     proceed = true; 
 
\t    } 
 
\t   } 
 
\t  } // i-loop -- meta-honeycomb 
 
\t  
 
\t  iter++; 
 
    } while (proceed && (iter < 15));  
 
    
 
} // fill_CircleWithHex 
 

 

 
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 }); 
 
    }); 
 
    
 
$(document).ready(function() { 
 
    c_el = document.getElementById("myCanvas"); 
 
    ctx = c_el.getContext("2d"); 
 
    
 
    canvas_width = c_el.clientWidth; 
 
    canvas_height = c_el.clientHeight; 
 

 
    circle = { 
 
    \t r: 120, /// radius 
 
    \t pos: { 
 
    \t \t x: (canvas_width/2), 
 
    \t \t y: (canvas_height/2) 
 
    \t } 
 
    }; 
 
    
 
    hexagon = { 
 
    \t r: 20, 
 
    \t pos:{ 
 
    \t \t x: 0, 
 
    \t \t y: 0 
 
    \t } 
 
    }; 
 
    
 
    hex_w = hexagon.r * 2; 
 
    hex_h = Math.floor(Math.sqrt(3) * hexagon.r); 
 
    hex_s = (3/2) * hexagon.r; 
 
    
 
    fill_CircleWithHex(circle); 
 
});
<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;"> 
 
<div id="slider" style="position:relative; width: 150px; top: 4px;float: left;"></div> <div id="value" style="float: left;"> 0 </div> 
 
</div>

+0

Finora la risposta migliore, anche se è più complessa di quanto mi aspettassi .. sarebbe possibile semplificarla un po '? (Mi riferisco alla quantità di loop for utilizzati nell'esempio sopra.) – Alexus

+0

I 6 loop più interni potrebbero essere compressi al cpost di un'istruzione switch con 6 casi per differenziare il calcolo del punto medio del prossimo esagono da disegnare. Allo stesso modo, il codice per le shell parziali potrebbe essere collassato nei primi loop. Tuttavia, attualmente il punto medio dell'esagono più interno e il cerchio coincidono sempre. Rilassare ciò consentirà una soluzione ancora migliore, ma la struttura del codice probabilmente deve essere adattata comunque. Lo esaminerò stasera. – collapsar

+3

Bel lavoro. Può trasformare questi loop interni in chiamate di funzione: https://jsfiddle.net/7ekv24ab/ Semplifica un po '. – tiffon

0

trascorso qualche tempo sul vostro codice di confezionare l'esagono del. Non è perfetto e sono sicuro che c'è un modo migliore per farlo. Controllalo se è d'aiuto o se puoi correggere l'esagono che esce dal cerchio [ora c'è un problema con il calcolo di row_sizes]. Forse potrò guardarlo di nuovo ogni volta che avrò tempo, o possiamo guardare ad altri modi per farlo.

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 * 3; /// added spacing 
 
var hex_h = Math.floor(Math.sqrt(3) * hexagon.r/2); /// added spacing 
 
var hex_s = (3/2) * hexagon.r; 
 

 
var hex_width = 33.4; //based on r = 20 
 

 
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 var max_hex_H = Math.round(c_h/(hex_h )); 
 
\t var row_sizes = [] 
 
    
 
\t for(var col= 0; col < max_hex_H; col++){ 
 
\t \t 
 
\t \t var d = circle.r - (col * 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 
 
\t \t row_sizes.push(Math.ceil(c/(hexagon.r * 3))) 
 
\t } 
 

 
\t for(var row = 0; row < row_sizes.length; row++){ 
 
\t \t var max_hex_W = row_sizes[row]; 
 
    console.log(hex_w); 
 
\t \t var x_offset = Math.floor((c_w - (max_hex_W * hex_w))) + row%2 * hex_width - hex_width/2; // changed offset to define a zig zag 
 
\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 * 17.3) + (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>

+0

Downvoted poiché la soluzione viola il vincolo di contenimento. – collapsar

0

La risposta breve: non c'è modo semplice per farlo. Hai troppi casi speciali. Per illustrare ciò, inizia semplice con 1, 2, 3, 4, 6 e 7 esagoni, disegna il cerchio minimo che si adatta a loro e prendi nota dove finisce il centro del cerchio.

Come potete vedere il centro del cerchio si muove un po '.Può finire nel mezzo di un esagono, su un vertice o una giunzione.

Da quel momento in poi peggiora solo.

Il più vicino che ho trovato su questo problema è this page.

MODIFICA: Si consiglia di consultare la seguente pagina del blog per un trattamento completo sugli esagoni nella programmazione.

http://www.redblobgames.com/grids/hexagons/