如何使用HTML5画布绘制镜头横截面?

贾斯汀

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

这是我正在谈论的示例:

在此处输入图片说明

此图片中的每个元素都由两个[可能]圆弧组成,两个圆弧之间的直线介于2到6条之间。(我现在还不担心绘制非球面镜片元素)。

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

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

贾斯汀

一堆画圆的图片,做一些数学运算,然后在上面睡觉之后,我想出了以下解决方案:

//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();

这是与该代码完成的图像非常相似的图像: 在此处输入图片说明

它根据其各自的曲率半径确定每个面的弧长,然后确定将这些弧的中心放在何处。然后根据需要绘制圆弧和边缘以连接它们。我的代码在此模型中添加的是如果镜片的两个表面均为凸面,则镜片厚度会增加。幸运的是,我认为这种方法可能会出现的精度问题并未出现,即使经过许多不同的尺寸和镜头配置也是如此。

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

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章