计算线是否穿过圆,在某些角度出现奇怪的行为
Calculate if line crosses circle, weird behavior at certain angles
好的,我希望能够计算一条线是否穿过一个圆(至少是圆圈内线的一部分)。我找到了几个答案,但我认为它们太复杂了,所以我想出了这个。我不是数学家,所以我现在有点卡住了。当直线垂直对齐时,"半径>= Math.sqrt(len * len + len * len - o);"变为true(45°角变为0)。我不知道为什么会这样。谢谢:)
function lineInCircle(sx, sy, x, y, cx, cy, radius) {
cx -= sx; x -= sx; //sx is the first point's x position
cy -= sy; y -= sy;//sy is the first point's y position
len = Math.sqrt((cy * cy) + (cx * cx))//hypotenuse of circle (cy, cx) to (0, 0) (with offset)
atanx = Math.atan(y / x); //angle of (0, 0) to (x, y) in radians
atany = atanx - Math.atan(cy / cx); //to center
var o = 2 * len * len * Math.cos(atany);
var o = o < 0 ? -o:o//Had to do this, at some point the value can become inverted
return radius >= Math.sqrt(len * len + len * len - o);
}
编辑:
function lineInCircle(sx, sy, x, y, cx, cy, radius) {
cx -= sx; x -= sx; //sx is the first point's x position
cy -= sy; y -= sy;//sy is the first point's y position
ctp = Math.sin(Math.atan(y / x) - Math.atan(cy / cx)) * Math.sqrt((cy * cy) + (cx * cx));
return radius >= ctp && ctp >= -radius;
}
工作原理几乎相同,但速度更快。问题是它计算的是一条无限线。我将如何解决这个问题?
编辑 2:
function lineInCircle(sx, sy, x, y, cx, cy, radius) {
cx -= sx; x -= sx;
cy -= sy; y -= sy;
var h = Math.sqrt(cy * cy + cx * cx)
ctp = Math.sin(Math.atan(y / x) - Math.atan(cy / cx)) * h;
sideb = Math.sqrt(h * h - ctp * ctp);
line = Math.sqrt(x * x + y * y)
if (sideb - radius > line) {return false}
return radius >= ctp && ctp >= -radius;
}
部分修复,不会从线(线端)的一个方向继续到无穷大
编辑3:有点长,但快了两倍多,回到原点
function lineInCircle2(sx, sy, x, y, cx, cy, radius) {
var ysy = y - sy
var xsx = x - sx
var k = ((y-sy) * (cx-sx) - (x-sx) * (cy-sy)) / (ysy * ysy + xsx * xsx)
var ncx = cx - k * (y-sy)
var ncy = cy + k * (x-sx)
ncx -= cx
ncy -= cy
var ctp = Math.sqrt(ncx * ncx + ncy * ncy)
return radius >= ctp && ctp >= -radius;
}
编辑4:成功!
function lineInCircle(sx, sy, x, y, cx, cy, radius) {
if (sx > cx + radius && x > cx + radius || x < cx - radius && sx < cx - radius) {return false;}
if (sy > cy + radius && y > cy + radius || y < cy - radius && sy < cy - radius) {return false;}
var k = ((y - sy) * (cx - sx) - (x - sx) * (cy - sy)) / ((y - sy) * (y - sy) + (x - sx) * (x - sx))
var ncx = k * (y - sy)
var ncy = k * (x - sx)
return radius >= Math.sqrt(ncx * ncx + ncy * ncy);
}
完全按照我的意愿,我将其优化为 4.5 - 4.6 秒,迭代 100000000 次,而第一个版本的迭代为 10+ 秒,并且仍然更准确(意味着在某些角度没有更多的奇怪行为)。我很满意:D
工作量太大。找到穿过中心的法线,看看交点是否比半径更近。
function lineInCircle(sx, sy, x, y, cx, cy, radius) {
if (sx > cx + radius && x > cx + radius || x < cx - radius && sx < cx - radius) {return false;}
if (sy > cy + radius && y > cy + radius || y < cy - radius && sy < cy - radius) {return false;}
var k = ((y - sy) * (cx - sx) - (x - sx) * (cy - sy)) / ((y - sy) * (y - sy) + (x - sx) * (x - sx))
var ncx = k * (y - sy)
var ncy = k * (x - sx)
return radius >= Math.sqrt(ncx * ncx + ncy * ncy);
}
在我的机器上完成 100000000 次迭代大约需要 4.5 - 4.6 秒。
相关文章:
- 检查字符串是否包含计算
- iFrame 是否计算页面浏览量
- 计算多边形是否足够大,可以在 gmap 上可见
- Ember-自定义计算属性,用于检查是否存在所有依赖字段
- 了解网页和桌面应用程序是否在同一台计算机上启动
- 是否有HQMF到QRDA cat 3计算的简单示例
- 计算日期选择器+时间选择器是否在东部标准时区的过去
- 使用JavaScript计算用户是否超过16岁
- 如何在Ember.js中创建一个计算属性来查看单个EmberData属性是否脏
- 年龄验证输入框 - 计算是否超过 18 岁
- 使用 JavaScript 或 C# 检查客户端计算机上是否安装了 Java 应用程序(不是 JAVA!)
- 如何提高javascript html5程序的整体性能:是否可以在两台计算机上同步两个版本
- 是否有一个JavaScript库可以在没有UI的情况下进行电子表格计算
- 当网页存储在计算机上时,cookie 是否有效
- 是否应该在同一台计算机上的两个火狐浏览器共享相同的cookie
- 计算线是否穿过圆,在某些角度出现奇怪的行为
- 是否可以通过在 javascript 中使用正则表达式来计算具有输入年份出生的年龄
- 是否可以从外部样式表中获取 dom 元素的特定 css 属性的值,而不是从计算的样式表中获取
- 是否可以在评估右侧之前强制“=”的左侧完全计算为引用
- 检查指令是否计算为特定的HTML元素