本文介绍了用金字塔图案绘制圆的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在金字塔图案的HTML画布上绘制圆形球。



像这样:





小提琴,你可以告诉我算法:



/ p>

  var canvas = document.getElementById('canvas') ; canvas.width = 400; canvas.height = 400; var ctx = canvas.getContext('2d'); var balls = []; var ballsLength = 15; var Ball = function(){this.x = 0; this.y = 0; this.radius = 10;}; Ball.prototype.draw = function(x,y){this.x = x; this.y = y; ctx.fillStyle ='#333'; ctx.beginPath(); ctx.arc(this.x,this.y,this.radius,0,Math.PI * 2,true); ctx.fill(); ctx.closePath();}; init(); function init(){for(var i = 0; i< ballsLength; i ++){balls.push(new Ball()); } render();} function render(){for(var i = 1; i< = ballsLength; i ++){if(i> = 1&& i< = 5){balls [i]。画(i * 20 +球[i] .radius,20 +球[i] .radius); } if(i> = 6&& i< = 9){balls [i] .draw(i * 20 + balls [i] .radius,20 + balls [i] .radius * 2); } if(i> = 10&& i< = 12){balls [i] .draw(i * 20 + balls [i] .radius,20 + balls [i] .radius * 3); } if(i> = 13&& i< = 14){balls [i] .draw(i * 20 + balls [i] .radius,20 + balls [i] .radius * 4); } if(i == 15){balls [i] .draw(i * 20 + balls [i] .radius,20 + balls [i] .radius * 5); window.requestAnimationFrame(render);}  
  canvas { border:1px solid#333;}  
 < canvas id =canvas>< / canvas>  



我有 Ball x y radius 变量:

  var Ball = function(){
this.x = 0;
this.y = 0;
this.radius = 10;
};

然后我有 Ball 类的方法它在画布上绘制球:

  Ball.prototype.draw = function(x,y){
this .x = x;
this.y = y;
ctx.fillStyle ='#333';
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,Math.PI * 2,true);
ctx.fill();
ctx.closePath();
};

我想创建一个将任意数量的球放入金字塔的方法。

解决方案

像这样的台球金字塔总是有一些已知的事实:




  • 每一行总是包含一个比前一个更多的球

  • 这是一个等边的三角形,这意味着下一行总是开始偏移60°



所以我们可以制作一个矢量(台球游戏中的其他所有内容都非常涉及矢量,所以为什么不呢! :))为下一行的起点的方向如下:

  var deg60 = -60 / 180 * Math.PI ; // -60°,右上方向
var v = {
x:radius * Math.cos(deg60),
y:radius * Math.sin(deg60)
}

然后算法将(由总球数驱动):




  • 从第一行的最大限制为1开始

  • 绘制球直到达到行的最大限制


    • 然后,添加一个到最大限额

    • 重置行数

    • 将位置移至开头最后一行+向量


  • 重复直到达到球数



结果:





示例



  var ctx = c.getContext(2d),radius = 9,//球半径deg = -60 / 180 * Math.PI,//行开始方向-60°球= 15,//绘制绘制的球数= 0,//计算当前行上绘制的球rowLen = 1,// max当前行的长度(第一个= 1)x = 150,//起始点y = 140,cx = 150,cy = 140,//复制起点+偏移量v = {//向量x:半径* 2 *数学。 cos(deg),y:radius * 2 * Math.sin(deg)},i; for(i = 0;我<球; i ++){drawBall(cx,cy); // draw ball cx  -  = radius * 2; //将球的直径向左移动(在这种情况下)绘制++; //如果(绘制=== rowLen){//达到行的最大球数,则增加行数? cx = x + v.x * rowLen; //增加一行cy = y + v.y * rowLen; drawn = 0; //重置行rowLen ++的球数; //增加行限制}} ctx.fillStyle =#D70000; ctx.fill();函数drawBall(x,y){ctx.moveTo(x + radius,y); ctx.arc(x,y,radius,0,6.28); ctx.closePath();}  
 < canvas id = c height = 300>< / canvas>  



如果你想要在旋转方面更灵活,你可以简单地交换这一行:

  cx  -  = radius * 2; 

向量垂直(计算未显示)到第一个向量所以:

  cx + = pv.x; 
cy + = pv.y;


I want to draw circular balls on an HTML canvas in a pyramid pattern.

Like this:

Fiddle where you can show me the algorithm:

https://jsfiddle.net/ofxmr17c/3/

var canvas = document.getElementById('canvas');
canvas.width = 400;
canvas.height = 400;
var ctx = canvas.getContext('2d');

var balls = [];
var ballsLength = 15;

var Ball = function() {
	this.x = 0;
    this.y = 0;
    this.radius = 10;
};

Ball.prototype.draw = function(x, y) {
	this.x = x;
    this.y = y;
	ctx.fillStyle = '#333';
	ctx.beginPath();
	ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
	ctx.fill();
	ctx.closePath();
};

init();

function init() {
	for (var i = 0; i < ballsLength; i++) {
    	balls.push(new Ball());
    }
    render();
}

function render() {
	for (var i = 1; i <= ballsLength; i++) {
    	if (i >= 1 && i <= 5) {
        	balls[i].draw(i * 20 + balls[i].radius, 20 + balls[i].radius);
        }

        if (i >= 6 && i <= 9) {
        	balls[i].draw(i * 20 + balls[i].radius, 20 + balls[i].radius * 2);
        }

        if (i >= 10 && i <= 12) {
        	balls[i].draw(i * 20 + balls[i].radius, 20 + balls[i].radius * 3);
        }

        if (i >= 13 && i <= 14) {
        	balls[i].draw(i * 20 + balls[i].radius, 20 + balls[i].radius * 4);
        }

        if (i == 15) {
        	balls[i].draw(i * 20 + balls[i].radius, 20 + balls[i].radius * 5);
        }
    }

	window.requestAnimationFrame(render);
}
canvas {
    border: 1px solid #333;
}
<canvas id="canvas"></canvas>

I have Ball class with x, y and radius variables:

var Ball = function() {
    this.x = 0;
    this.y = 0;
    this.radius = 10;
};

Then I have method of the Ball class which draws the balls on the canvas:

Ball.prototype.draw = function(x, y) {
    this.x = x;
    this.y = y;
    ctx.fillStyle = '#333';
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
    ctx.fill();
    ctx.closePath();
};

I want to create method which will place any number of balls into a pyramid.

解决方案

A billiard pyramid like this is always made with some known facts:

  • Each row always contains one more ball than the previous
  • It's an equilateral triangle which means next row always starts offset 60°

So we can make a vector (everything else in a billiard game would very much involve vectors so why not! :) ) for the direction of the next row's start point like so:

var deg60 = -60 / 180 * Math.PI;    // -60°, up-right direction
var v = {
    x: radius * Math.cos(deg60),
    y: radius * Math.sin(deg60)
  }

Then the algorithm would be (driven by total number of balls):

  • Start with a max limit of 1 for first row
  • Plot balls until max limit for row is reached
    • Then, add one to the max limit
    • Reset row count
    • Move position to beginning of last row + vector
  • Repeat until number of balls is reached

Result:

Example

var ctx = c.getContext("2d"),
    radius = 9,                         // ball radius
    deg = -60 / 180 * Math.PI,          // direction of row start -60°
    balls = 15,                         // number of balls to draw
    drawn = 0,                          // count balls drawn on current row
    rowLen = 1,                         // max length of current row (first=1)
    x = 150,                            // start point
    y = 140,
    cx = 150, cy =140,                  // replicates start point + offsets
    v = {                               // vector
      x: radius * 2 * Math.cos(deg),
      y: radius * 2 * Math.sin(deg)
    },
    i;

for(i = 0; i <  balls; i++) {
  drawBall(cx, cy);                     // draw ball
  cx -= radius * 2;                     // move diameter of ball to left (in this case)
  drawn++;                              // increase balls on row count
  if (drawn === rowLen) {               // reached max balls for row?
    cx = x + v.x * rowLen;              // increase one row
    cy = y + v.y * rowLen;
    drawn = 0;                          // reset ball count for row
    rowLen++;                           // increase row limit
  }
}

ctx.fillStyle = "#D70000";
ctx.fill();

function drawBall(x, y) {
  ctx.moveTo(x + radius, y); ctx.arc(x, y, radius, 0, 6.28);
  ctx.closePath();
}
<canvas id=c height=300></canvas>

If you want more flexibility in terms of rotation you can simply swap this line:

cx -= radius * 2;

with a vector perpendicular (calculation not shown) to the first vector so:

cx += pv.x;
cy += pv.y;

这篇关于用金字塔图案绘制圆的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-11 11:21