javascript - 在圆形路径周围放置不同大小的圆圈,没有间隙

标签 javascript math canvas

我正在创建一个 Canvas 动画,并设法在圆形路径中放置了 x 个圆圈。这是我使用的代码的简化版本:

var total = circles.length,
    i = 0,
    radius = 500,
    angle = 0,
    step = (2*Math.PI) / total;

for( i; i < total; i++ ) {
    var circle = circles[i].children[0],
        cRadius = circle[i].r,
        x = Math.round(winWidth/2 + radius * Math.cos( angle ) - cRadius),
        y = Math.round(winHeight/2 + radius * Math.sin( angle ) - cRadius);

    circle.x = x;
    circle.y = y;

    angle += step;
}

结果是: enter image description here

我想要实现的是所有圆圈彼此相邻且之间没有间隙(第一个和最后一个除外)。圆的大小(半径)是随机生成的,不应调整以适应圆形路径:

function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

我预计第一个和最后一个圆圈之间会有间隙。

我正在努力解决这个问题,所以非常感谢任何帮助:)

干杯!

最佳答案

主要创建循环:
• 获取当前半径
• 计算它覆盖的 Angular ( = atan2(smallRadius/bigRadius) )
• 将底 Angular 移动最近的 Angular 。

enter image description here

http://jsfiddle.net/dj2v7mbw/9/

function CircledCircle(x, y, radius, margin, subCircleCount, subRadiusMin, subRadiusMax) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.subCircleCount = subCircleCount;
    var circles = this.circles = [];
    // build top sub-circles
    var halfCount = Math.floor(subCircleCount / 2);
    var totalAngle = addCircles(halfCount);
    // re-center top circles
    var correction = totalAngle / 2 + Math.PI / 2;
    for (var i = 0; i < halfCount; i++) this.circles[i].angle -= correction;
    // build bottom sub-circles
    totalAngle = addCircles(subCircleCount - halfCount);
    // re-center bottom circles
    var correction = totalAngle / 2 - Math.PI / 2;
    for (var i = halfCount; i < subCircleCount; i++) this.circles[i].angle -= correction;
    // -- draw this C
    this.draw = function (angleShift) {
        for (var i = 0; i < this.circles.length; i++) drawDistantCircle(this.circles[i], angleShift);
    }
    //
    function drawDistantCircle(c, angleShift) {
        angleShift = angleShift || 0;
        var thisX = x + radius * Math.cos(c.angle + angleShift);
        var thisY = y + radius * Math.sin(c.angle + angleShift);
        ctx.beginPath();
        ctx.arc(thisX, thisY, c.r, 0, 2 * Math.PI);
        ctx.fillStyle = 'hsl(' + (c.index * 15) + ',75%, 75%)';
        ctx.fill();
        ctx.stroke();
    }
    //
    function addCircles(cnt) {
        var currAngle = 0;
        for (var i = 0; i < cnt; i++) {
            var thisRadius = getRandomInt(subRadiusMin, subRadiusMax);
            var thisAngle = Math.atan2(2 * thisRadius + margin, radius);
            var thisCircle = new subCircle(thisRadius, currAngle + thisAngle / 2, i);
            currAngle += thisAngle;
            circles.push(thisCircle);
        }
        return currAngle;
    }
}

function subCircle(radius, angle, index) {
    this.r = radius;
    this.angle = angle;
    this.index = index;
}

function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

使用

 var myCircles = new CircledCircle(winWidth / 2, winHeight / 2, 350, 2, 24, 5, 50);
 myCircles.draw();

动画:

var angleShift = 0;

function draw() {
    requestAnimationFrame(draw);
    ctx.clearRect(0, 0, winWidth, winHeight);
    myCircles.draw(angleShift);
    angleShift += 0.010;
}
draw();

关于javascript - 在圆形路径周围放置不同大小的圆圈,没有间隙,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25470730/

相关文章:

c++ - Casteljau 算法 - 实例

javascript - onkeyup 和 onkeydown 没有捕捉到任何东西

css - Canvas 太高

javascript - bluebird promise : any() collection return value undefined

javascript - 如何将 Owl Carousel 导航移到默认 div 之外?

javascript - 添加overflow属性时Material UI奇怪的蓝线

javascript - 无法在 Node 中导入 ESM .ts 模块

math - 面试题 : f(f(x)) == 1/x

Java 求两个整数的中点

javascript - 旋转后得到正确的左上角坐标