bj,
sur
https://jsfiddle.net/m68cyze2/index.html
- Code: Tout sélectionner
<!DOCTYPE html>
<html>
<head>
<title>got a brick house</title>
<meta charset="UTF-8">
</head>
<body>
<style>
canvas{
width:600px;
height:600px;
background:#eeeeee;
display:block;
}
</style>
<canvas width="600" height="600"></canvas>
percentage of base brick
<div class="slidecontainer">
<input type="range" min="1" max="100" value="100" class="slider" id="myRange">
</div>
<hr/>
<div id="output"></div>
<script src="brick.js"></script>
</body>
</html>
brick.js
- Code: Tout sélectionner
function buildBriques(o){
var {r, brick, d, x} = o;
var X = {
x:x,
y:Math.sqrt(r*r - brick.w*brick.w/4) - brick.h
}
const ri = Math.sqrt(X.x*X.x+X.y*X.y);
var theta = 2*Math.atan2(x, X.y);//base brick
var beta = 2*Math.asin(d/2/ri)
var endAngle = Math.PI*2 + Math.PI/2 - theta/2;
var left = Math.PI/2 + theta/2;
//start from left
//end at right
var bricks = [{pts:[
X,
{
x:brick.w/2,
y:X.y+brick.h
},
{
x:-brick.w/2,
y:X.y+brick.h
},
{
x:-X.x,
y:X.y
}]}
];
var iter = 0;
while(left + theta + beta < endAngle && iter++ < 200){
var b = [
//right point
{
x:ri*Math.cos(left+beta),
y:ri*Math.sin(left+beta)
},
//left point
{
x:ri*Math.cos(left+beta+theta),
y:ri*Math.sin(left+beta+theta)
}
];
var u = {
x:b[1].x - b[0].x,
y:b[1].y - b[0].y
};
var dir = Math.sqrt( Math.pow(u.x, 2) + Math.pow(u.y, 2))
var nu = {
x: u.x / dir,
y: u.y / dir
}
var midU = {
x:(b[1].x + b[0].x ) /2,
y:(b[1].y + b[0].y ) /2
}
var a = -Math.PI/2;
var tr = {
x:(Math.cos(a)*nu.x - Math.sin(a) * nu.y) * brick.h + midU.x - nu.x * brick.w/2,
y:(Math.sin(a)*nu.x + Math.cos(a) * nu.y) * brick.h + midU.y - nu.y * brick.w/2,
}
var a = Math.PI/2;
var tl = {
x:(Math.cos(a)*-nu.x - Math.sin(a) * -nu.y) * brick.h + midU.x + nu.x * brick.w/2,
y:(Math.sin(a)*-nu.x + Math.cos(a) * -nu.y) * brick.h + midU.y + nu.y * brick.w/2,
}
bricks.push({
pts:[
b[0],
tr,
tl,
b[1]
]
});
left = left+beta+theta;
++iter;
}
return bricks;
}
function plot(b,ctx,s){
var [A,B,C,D] = b.pts;
ctx.beginPath();
ctx.strokeStyle = 'black';
ctx.moveTo(A.x*s, -A.y*s);
ctx.lineTo(B.x*s, -B.y*s);
ctx.lineTo(C.x*s, -C.y*s);
ctx.lineTo(D.x*s, -D.y*s);
ctx.closePath();
ctx.stroke();
}
function main(){
var canvas = document.querySelector('canvas');
var output = document.querySelector('#output');
var ctx = canvas.getContext('2d');
const R = 1;
const scale = canvas.height/2.1;
const brick = {w:0.1, h:0.1};
ctx.translate(canvas.width/2, canvas.height/2);
//ctx.transform(1*100, 0, 0, -1*100, canvas.width/2, canvas.height/2);
var brickass = function(x){
var bricks = buildBriques({r:R, brick:brick, d:0.01, x:x})
plotter = canvas.hei;
bricks.forEach(b=>{
plot(b, ctx,scale)
})
ctx.beginPath();
ctx.arc(0,0, R*scale, 0, Math.PI*2)
ctx.closePath();
ctx.strokeStyle = '#cccccc'
ctx.stroke();
output.innerHTML = 'half base size: '+x
}
brickass(0.045)
var slider = document.querySelector('input');
slider.oninput = function() {
ctx.clearRect(-canvas.width/2,-canvas.height/2,canvas.width, canvas.height);
brickass(this.value / 100 * brick.w/2);
}
}
main();
on voit que
1) en jouant avec la largeur de la base, on a pas forcément un tour de cercle complet
2) qu'avec des largeurs trop petites on a les briques qui se recouvrent. Idem avec une largeur de base suffisamment importante on est safe
3) je suis pas sûr qu'au final ca change grand chose de couper des briques XD
libre à toi apres d'estimer cb de briques tu veux enquiller ou combien d'espace th à la fin tu veux avoir (personnellement étant un gros degueux je prendrais l'écart le plus grand m'enfin..)
concernant les calculs, on pose x1 et x2 les points de la base
on déduit l'angle theta formés par le centre du cercle et ces deux points
on rajoute un angle beta correspondant à la distance interbrique (sin(beta/2)=d/2/R(x1))
du coup on peut construire les points x3,x4 et ainsi de suite