我想在HTML5 <canvas>
元素上使用0.0
和PI*2.0
之间任意数量的弧度和给定半径将一组点(当前为正方形)排列成等边三角形(例如150
)。
您可以在on this JS Bin中看到黑色方块以圆形排列,使用画布的rotate()
和translate()
方法定位。
我尽可能接近as this:
var w = canvas.width = 360;
var h = canvas.height = 360;
var PI = Math.PI,
TAU = PI * 2,
sqrt = Math.sqrt,
pow = Math.pow;
var radius = 150;
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, w, h);
ctx.translate(w/2, h/2);
ctx.fillStyle = "#000";
// draw circle (omitted)
var corners = 3;
// draw triangle (omitted)
for(var i = 0, max = 90; i < max; i++){
var delta = i/max; // between 0.0 and 1.0
var radian = delta * TAU; // between 0 and PI*2
var dist = radius;
var portion = (delta * corners) % 1;
var dist = radius - 70 * sqrt(4 - pow(portion * 4 - 2, 2)) / 2;
ctx.save();
ctx.rotate(radian);
ctx.translate(0, dist);
ctx.fillRect(-2, -2, 4, 4);
ctx.restore();
}
答案 0 :(得分:0)
您可以在三角形顶点之间的线段上插值点,如下所示:
// a function that does linear interpolation
var lerp=function(a,b,pct){ return(a+pct*(b-a)); };
// x1,y1 & x2,y2 are vertices of the triangle
// pct is the percentage (0.00-1.00) between the 1st & 2nd vertex
// where you want to place a point
var x=lerp(x1,x2,pct/100);
var y=lerp(y1,y2,pct/100);
以下是示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var PI=Math.PI;
var PI2=PI*2;
var lerp=function(a,b,pct){ return(a+pct*(b-a)); };
var interpolatedDotCount=15;
var a1=PI/2;
var a2=a1+PI2/3;
var a3=a2+PI2/3;
//
var nextTime=0;
var delay=16*3;
//
var cx=150;
var cy=150;
var minRadius=50;
var maxRadius=100;
var radius=minRadius;
var radiusDirection=1;
var angleIncrement=PI2/60;
var dotSize=3;
requestAnimationFrame(animate);
function dottedTriangle(cx,cy,radius){
ctx.clearRect(0,0,cw,ch);
var vertex1x=cx+radius*Math.cos(a1);
var vertex1y=cy+radius*Math.sin(a1);
var vertex2x=cx+radius*Math.cos(a2);
var vertex2y=cy+radius*Math.sin(a2);
var vertex3x=cx+radius*Math.cos(a3);
var vertex3y=cy+radius*Math.sin(a3);
var dx=vertex2x-vertex1x;
var dy=vertex2y-vertex1y;
var length=Math.sqrt(dx*dx+dy*dy);
ctx.beginPath();
ctx.arc(cx,cy,radius,0,PI2);
ctx.closePath();
ctx.strokeStyle='lightcoral';
ctx.stroke();
interpolateDots(vertex1x,vertex1y,vertex2x,vertex2y);
interpolateDots(vertex2x,vertex2y,vertex3x,vertex3y);
interpolateDots(vertex3x,vertex3y,vertex1x,vertex1y);
dot(vertex1x,vertex1y,dotSize,'red');
dot(vertex2x,vertex2y,dotSize,'green');
dot(vertex3x,vertex3y,dotSize,'blue');
}
function interpolateDots(x1,y1,x2,y2){
for(var pct=0;pct<100;pct+=100/interpolatedDotCount){
var x=lerp(x1,x2,pct/100);
var y=lerp(y1,y2,pct/100);
dot(x,y,dotSize,'gold');
}
}
function dot(x,y,r,color){
ctx.fillStyle=color;
ctx.beginPath();
ctx.arc(x,y,r,0,PI2);
ctx.closePath();
ctx.fill();
}
function animate(time){
requestAnimationFrame(animate);
if(time<nextTime){return;}
nextTime+=delay;
dottedTriangle(cx,cy,radius);
a1+=angleIncrement;
a2=a1+PI2/3;
a3=a2+PI2/3;
radius+=radiusDirection;
if(radius<minRadius || radius>maxRadius){
radiusDirection*=-1;
radius+=radiusDirection;
}
}
&#13;
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
&#13;
<canvas id="canvas" width=300 height=300></canvas>
&#13;