我怎样才能用HTML5画布绘制镜头横截面?

时间:2014-01-20 20:38:41

标签: javascript html5 canvas

我希望能够绘制镜头元素的横截面。它们通常由1或2个圆形表面(正面和背面)和任意形状的边缘组成。就我的目的而言,我只想绘制一条或两条线来连接正面和背面。

这是我正在谈论的一个例子:

enter image description here

此图片中的每个元素都由两条[可能]圆弧组成,两条和六条直线之间用于连接它们。 (我并不担心非常使用非球面透镜元件)。

我最初的想法是绘制具有适当弧长的弧,然后绘制线以连接它们。我对这种方法的担心是弧线和线可能不匹配,由于精度误差,可能存在重叠或间隙。

有没有更好的方法来解决这个问题?我可以绘制包含直边和弯边的多边形吗?

1 个答案:

答案 0 :(得分:2)

经过一堆圆圈的绘图,做了一些数学计算,然后睡在上面,我想出了以下解决方案:

//draw the top and bottom edges of the lens    
ctx.beginPath();
ctx.moveTo(lens.x - (lens.thickness / 2), lens.y - lens.radius);
ctx.lineTo(lens.x + (lens.thickness / 2), lens.y - lens.radius);
ctx.moveTo(lens.x - (lens.thickness / 2), lens.y + lens.radius);
ctx.lineTo(lens.x + (lens.thickness / 2), lens.y + lens.radius);
ctx.stroke();


ctx.beginPath();
//draw the left face of the lens
var lensToCircleRatio = lens.radius / lens.leftRadius;
var xOffset = lens.leftRadius * Math.cos(Math.asin(lensToCircleRatio)) - (lens.thickness / 2);  //change the - to a + for a right-side concave face
var arcStart = Math.PI - Math.asin(lensToCircleRatio);
var arcEnd = Math.PI + Math.asin(lensToCircleRatio);
ctx.arc(lens.x + xOffset, lens.y, lens.leftRadius, arcStart, arcEnd);
ctx.stroke();


ctx.beginPath();
//draw the right face of the lens
lensToCircleRatio = lens.radius / lens.rightRadius;
xOffset = lens.rightRadius * Math.cos(Math.asin(lensToCircleRatio)) - (lens.thickness / 2);     //change the - to a + for a left-side concave face
arcStart = -1 * Math.asin(lensToCircleRatio);
arcEnd = Math.asin(lensToCircleRatio);
ctx.arc(lens.x - xOffset, lens.y, lens.rightRadius, arcStart, arcEnd);
ctx.stroke();

这是一个与此代码完成的图像非常相似的图像: enter image description here

根据各自的曲率半径计算每个面的弧长,然后计算出这些弧的中心位置。然后,如果需要,它会绘制弧线和边缘以连接它们。如果镜头的两个面都凸出,我的代码添加到此模型中的是额外的镜头厚度。幸运的是,即使在许多不同的尺寸和镜头配置之后,我认为可能从这种方法中出现的精度问题也没有显示出来。

这是一个早期测试(使用略微更新的代码绘制):

enter image description here