绘制圆形扇区中的随机点
plotting random points in circle sector
我在画布上有一个饼状图,我想在饼的每个扇形中绘制随机点。
我得到了每个扇区的面积。使用圆弧扇形
var arcsector = Math.PI * (2 * sector / total);
var startAngle = (lastend - offset) * (radius/Math.PI);
var endAngle = (lastend + arcsector - offset) * (radius/Math.PI);
var sectorAngle = arcsector * (radius/Math.PI);
var sectorArea = .5 * (sectorAngle*Math.PI/180) * (radius*radius);
如何在该区域内随机绘制点?
饼是圆的一部分,用你的符号,它开始于startAngle,结束于endAngle。
得到一个随机点的最简单的方法是建立一个随机的角度startAngle和endAngle)和一个随机半径,然后你就有了这些线的点:
var randAngle = startAngle + Math.random()*( endAngle - startAngle );
var randRadius = Math.random()*radius;
var randX = centerX + randRadius * Math.cos(randAngle);
var randY = centerY + randRadius * Math.sin(randAngle);
ctx.fillRect ( randX, randY, 1, 1 ) ;
简单的方法是:
- 在路径 上创建临时圆弧
- 创建随机点
- 根据形状对点进行命中测试,并在 内绘制
你可以像这样创建一个临时的弧形路径(根据你的情况进行调整)(不需要描边/填充):
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.arc(cx, cy, radius, startAngle, endAngle);
ctx.closePath();
然后在边界内创建随机点,或者只是使用一种非常基本的方法(在大多数情况下可能足够快,除非你需要很多点)-与使用基于半径的方法相比,扩展甚至:
var randomX = cx + radius * 2 * Math.random() - radius;
var randomY = cy + radius * 2 * Math.random() - radius;
和最后的hit-test:
if (ctx.isPointInPath(randomX, randomY)) {
// plot point, count etc.
}
小提琴
在圆弧形状中生成随机点的一种更有效的方法是直接绘制到屏幕外的画布上,而不使用任何边界检查和昂贵的cos/sin操作,最后将其合成在圆弧形状上(或使用圆弧作为剪辑)。
// create off-screen canvas
var ocanvas = document.createElement('canvas');
var octx = ocanvas.getContext('2d');
var d;
d = ocanvas.width = ocanvas.height = 300;
octx.fillStyle = '#fff';
while(count) {
var randomX = d * Math.random();
var randomY = d * Math.random();
octx.fillRect(randomX - 1, randomY - 1, 2, 2);
count--;
}
// composite random points with main arc
ctx.globalCompositeOperation = 'source-atop';
ctx.drawImage(ocanvas, 0, 0);
ctx.globalCompositeOperation = 'source-over';
可以通过让屏幕外画布只代表圆弧形状的边界来进一步优化。
小提琴
演示: http://jsfiddle.net/jv6nP/3/
点在边界上是不完美的,因此它们的半径大于零会使它们重叠在饼的其他部分上。这也会导致它们越过黑色边界。
var can = $('#can')[0].getContext('2d'),
border=2,
x=100,
y=75,
r=60,
sRadius= 0,
leadAngle=null,
points= [],
dotRadius=2,
data = {
water:[30,'#5CC5FA'],
earth:[60,'#F0A71F'],
air:[10,'#26EDE3']
};
function reDraw(){
//making border...
can.beginPath();
can.arc(x,y,r+border,0,2*Math.PI);
can.fillStyle='black';
can.fill();
var newAngle=null;
for (var k in data) { //making piechart..
leadAngle = (2*Math.PI)*(data[k][0]/100);
newAngle = sRadius+leadAngle;
calPoints(sRadius,leadAngle,k);
can.beginPath();
can.arc(x,y,r,sRadius,newAngle);
can.lineTo(x,y);
can.fillStyle=data[k][1];
can.fill();
sRadius= newAngle;
}
//calculating points..
function calPoints(s,e,name) {
if (name!='water') return;
var py,px,rAngle,rRad;
for (var i=0; i<15; i++) {
rAngle=s+Math.random()*(e);
rRad = Math.random()*r;
px = (Math.cos(rAngle) * rRad)+x;
py = (Math.sin(rAngle) * rRad)+y;
points.push([px,py]);
}
}
//plotting dots from data...
points.forEach(function(v){
can.beginPath();
can.arc(v[0],v[1],dotRadius,0,2*Math.PI);
can.fillStyle='fff';
can.fill();
});
points=[];
requestAnimationFrame(reDraw);
}
reDraw();
相关文章:
- $(document).height()在刷新时随机化值(Safari 5.1.10)
- 使用当前日期生成随机id
- DOM元素和angular元素之间的主要区别是什么
- 从a-z中随机选择一个字母
- RequireJ无法随机加载脚本
- 单击按钮时显示随机字符串
- Ajax更新面板随机错误'PRM_MissingPanel'
- 什么'$.get和$.ajax之间的区别是什么
- 如何检查if/else语句中的随机条件
- 是否可以自动拉取“随机”;标签“;从一长串文本中提取
- 如何使用D3生成特定范围内的随机颜色
- 如何在 Javascript/jQuery 中获取一些随机下拉列表的选定值
- 在固定位置显示随机图像
- 有效地获取两个区间之间的随机整数
- 如何使用 d3.js 使工具提示显示在饼图扇区附近
- 使用 Raphaël JS 和 SVG 调整扇区路径大小的更优雅方法
- 使用css和javascript对圆形图像的扇区进行着色处理
- D3 -地图上的中心和比例扇区
- 如何显示扇区颜色与JustGage
- 绘制圆形扇区中的随机点