如何使用 JavaScript 检测线段与圆的相交

如何使用 javascript 检测线段与圆的相交

本文详细介绍了如何使用 JavaScript 检测线段与圆是否相交。通过计算线段到圆心的最近距离,并与圆的半径进行比较,可以有效地判断是否存在交点。文章提供了两种实现方法,一种避免了昂贵的平方根运算,另一种则能计算出交点距离。同时,提供了可运行的示例代码,方便读者理解和应用。

线段与圆相交检测的原理

判断线段与圆是否相交,核心在于计算线段到圆心的最短距离。如果这个最短距离小于或等于圆的半径,则线段与圆相交;反之,则不相交。

计算线段到圆心的最短距离,首先需要找到线段上距离圆心最近的点。这个点可以通过向量投影的方式求得。然后,计算圆心到该点的距离,并与圆的半径进行比较。

方法一:避免平方根运算的实现

以下代码展示了如何使用 rayInterceptsCircle 函数判断线段(ray)是否与圆相交,避免使用平方根运算,提高了效率。

立即学习“Java免费学习笔记(深入)”;

function rayInterceptsCircle(ray, circle) {        const dx = ray.p2.x - ray.p1.x;    const dy = ray.p2.y - ray.p1.y;    const u = Math.min(1, Math.max(0, ((circle.x - ray.p1.x) * dx + (circle.y - ray.p1.y) * dy) / (dy * dy + dx * dx)));    const nx = ray.p1.x + dx * u - circle.x;    const ny = ray.p1.y + dy * u - circle.y;        return nx * nx + ny * ny < circle.radius * circle.radius;}

代码解释:

dx 和 dy 分别表示线段在 x 和 y 轴上的分量。u 是一个参数,表示线段上距离 ray.p1 最近的点的位置,它的值被限制在 0 到 1 之间,确保该点在线段上。nx 和 ny 表示圆心到线段上最近点的向量。最后,比较 nx * nx + ny * ny (最近距离的平方) 与 circle.radius * circle.radius (半径的平方)。如果前者小于后者,则表示线段与圆相交。

优点:

避免了平方根运算,性能更高。

缺点:

Topaz Video AI Topaz Video AI

一款工业级别的视频增强软件

Topaz Video AI 388 查看详情 Topaz Video AI 只能判断是否相交,无法获取交点信息。

方法二:计算交点距离的实现

以下代码展示了如何使用 rayDist2Circle 函数计算线段与圆的交点距离。如果线段与圆不相交,则返回 Infinity。

function rayDist2Circle(ray, circle) {    const dx = ray.p2.x - ray.p1.x;    const dy = ray.p2.y - ray.p1.y;    const vcx = ray.p1.x - circle.x;     const vcy = ray.p1.y - circle.y;    var v =  (vcx * dx +  vcy * dy) * (-2 / Math.hypot(dx, dy));    const dd = v * v - 4 * (vcx * vcx + vcy * vcy - circle.radius * circle.radius);    if (dd <= 0) { return Infinity; }    return  (v - Math.sqrt(dd)) / 2;}

代码解释:

dx 和 dy 分别表示线段在 x 和 y 轴上的分量。vcx 和 vcy 表示线段起点到圆心的向量。v 是一个中间变量,用于简化计算。dd 是判别式,如果小于等于 0,则表示线段与圆不相交,返回 Infinity。最后,计算交点距离并返回。

优点:

可以计算交点距离,获取更详细的相交信息。

缺点:

需要进行平方根运算,性能相对较低。

完整示例代码

以下是一个完整的示例代码,演示了如何使用这两种方法进行线段与圆的相交检测。

Line Circle Intersectioncanvas {  position: absolute;  top: 0px;  left: 0px;}const ctx = canvas.getContext("2d");const TAU = Math.PI * 2;requestAnimationFrame(renderLoop);var W = canvas.width, H = canvas.height;const Point = (x, y) => ({x, y}); const Ray = (p1, p2) => ({p1, p2}); const Circle = (p, radius) => ({x: p.x, y: p.y, radius});function drawRayLeng(ray, len) {  ctx.beginPath();  ctx.lineTo(ray.p1.x, ray.p1.y);  if (len < Infinity) {    const dx = ray.p2.x - ray.p1.x;    const dy = ray.p2.y - ray.p1.y;    const scale = len / Math.hypot(dx, dy);    ctx.lineTo(ray.p1.x + dx * scale , ray.p1.y + dy  * scale);  } else {    ctx.lineTo(ray.p2.x, ray.p2.y);  }  ctx.stroke();}function drawRay(ray) {  ctx.beginPath();  ctx.lineTo(ray.p1.x, ray.p1.y);  ctx.lineTo(ray.p2.x, ray.p2.y);  ctx.stroke();}function drawCircle(circle) {  ctx.beginPath();  ctx.arc(circle.x, circle.y, circle.radius, 0, TAU);  ctx.stroke();}function rayInterceptsCircle(ray, circle) {        const dx = ray.p2.x - ray.p1.x;    const dy = ray.p2.y - ray.p1.y;    const u = Math.min(1, Math.max(0, ((circle.x - ray.p1.x) * dx + (circle.y - ray.p1.y) * dy) / (dy * dy + dx * dx)));    const nx = ray.p1.x + dx * u - circle.x;    const ny = ray.p1.y + dy * u - circle.y;        return nx * nx + ny * ny < circle.radius * circle.radius;}function rayDist2Circle(ray, circle) {    const dx = ray.p2.x - ray.p1.x;    const dy = ray.p2.y - ray.p1.y;    const vcx = ray.p1.x - circle.x;     const vcy = ray.p1.y - circle.y;    var v =  (vcx * dx +  vcy * dy) * (-2 / Math.hypot(dx, dy));    const dd = v * v - 4 * (vcx * vcx + vcy * vcy - circle.radius * circle.radius);    if (dd <= 0) { return Infinity; }    return  (v - Math.sqrt(dd)) / 2;}const mouse  = {x : 0, y : 0}function mouseEvents(e){    mouse.x = e.pageX;    mouse.y = e.pageY;}document.addEventListener("mousemove", mouseEvents);const c1 = Circle(Point(150, 120), 60);const r1 = Ray(Point(0, 50), Point(300, 50));function renderLoop(time) {   ctx.clearRect(0, 0, W, H);   r1.p1.x = c1.x + Math.cos(time / 5000) * 100;   r1.p1.y = c1.y + Math.sin(time / 5000) * 100;   r1.p2.x = mouse.x;   r1.p2.y = mouse.y;   ctx.lineWidth = 0.5;   drawCircle(c1);   drawRay(r1);   ctx.lineWidth = 5;   if (rayInterceptsCircle(r1, c1)) {     ctx.strokeStyle = "red";     drawRayLeng(r1, rayDist2Circle(r1, c1));   } else {     drawRay(r1);   }   ctx.strokeStyle = "black";   requestAnimationFrame(renderLoop);}

使用方法:

将代码保存为 HTML 文件。使用浏览器打开该文件。移动鼠标,观察线段与圆的相交情况。当线段与圆相交时,线段会变为红色,并显示交点。

总结

本文介绍了两种使用 JavaScript 检测线段与圆相交的方法。rayInterceptsCircle 函数通过避免平方根运算,提高了性能,适用于只需要判断是否相交的场景。rayDist2Circle 函数可以计算交点距离,获取更详细的相交信息,适用于需要精确计算交点位置的场景。开发者可以根据实际需求选择合适的方法。

以上就是如何使用 JavaScript 检测线段与圆的相交的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/753772.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月25日 21:49:33
下一篇 2025年11月25日 21:50:13

相关推荐

  • Sui Golden Cross触发了380%的价格上涨,因为其区块链的增长加速了

    sui近期在其日常k线图中触发了“黄金交叉”形态,这一技术信号通常预示着强劲的上涨趋势。若第四季度2024年的牛市结构如期显现,可能会推动价格实现高达380%的增长。随着sui网络用户活动显著增加,这种积极信号显得尤为突出。 据CoinMarketCap数据显示,当前SUI的交易价格约为3.30美元…

    2025年12月8日
    000
  • Etoro扩大其加密货币产品,包括5个新资产

    现在,美国的用户可以“投资20种不同的加密资产,包括:基本关注令牌,曲线,分散者,制造商和多边形。” eToro, the trading and investing platform that empowers you to invest, share and learn founded with…

    2025年12月8日
    000
  • 炒作驱动加密的日子正在衰落

    近年来,加密货币市场涌现出所谓的“炒作代币”。虽然部分人借此快速获利,但不少投资者却因这类代币的不可预测暴跌而蒙受损失。 由炒作推动的加密代币已不再主导市场。精明的投资者,包括大型机构投资者,正逐渐转向具备长期价值的实用型项目。Ruvi AI和Tron成为那些追求创新与可扩展性的投资者的理想选择。正…

    2025年12月8日
    000
  • ChainLink(Link)鲸鱼交易6000万美元,市场活动峰值45%

    分散的Oracle协议ChainLink(Link)在过去24小时内作为鲸鱼交易在过去24小时内注册了重大市场活动。 根据Intotheblock数据,ChainLink(Link)的鲸鱼活动激增,在过去24小时内,大量交易量增加了45%。 这种活动的激增可能是由于市场的价格转移,这引起了大型持有人…

    2025年12月8日
    000
  • 链链接(链接)结束了会议,以看涨的关闭,暗示了潜在的进一步增长

    cryptowzrd在近期关于x的最新动态中提到,chainlink会议圆满结束,这种结束方式预示着可能进一步的增长潜力。不过,分析师也指出,比特币的表现将在很大程度上影响这一走势。 我们的新闻是如何产生的 我们坚持严格的编辑方针,注重信息的准确性、相关性和公正性。 Ad Dibleiamer Mo…

    2025年12月8日
    000
  • 随着谣言围绕着埃隆·马斯克(Elon Musk)的默契与直接的教堂有关的讨论,每个人都认为这不是再见 – 而是巨大的开始

    马斯克从未是dogecoin的支持者——他是它最坚定的倡导者,被称为“人民的加密货币”。 传闻称,尽管埃隆·马斯克减少了公开谈论Doge的频率,但这并非结束,而是更大动作的开端。 马斯克从来都不是Dogecoin的朋友——他是它的最大支持者,被称为“人民的加密货币”。随着2025年机构兴趣的增长以及…

    2025年12月8日
    000
  • 比特币公牛捍卫101,000美元,因为Market Eyes Key Reclaim $ 107,000

    比特币跌破$ 101,000后,出现了显著的反弹,在再次回落至10万关口之前触及了大量流动性区域。 周四,比特币价格展现出韧性,从低点回升至100,800美元,并成功突破104,000美元的交易区间。 这一主要加密货币短暂下探至101,000美元下方,触发了流动性吸筹,为后续走势铺平道路,而这一走势…

    2025年12月8日
    000
  • 如果Binance和Coinbase List Kaspa,KAS价格在2025年有多高?

    卡巴依旧未能登上全球最受欢迎的两大交易所——coinbase和binance,这一情况正逐渐引发其用户的担忧。 卡巴仍未在Coinbase和Binance两大加密货币巨头平台上成功上市,这使其用户群体日益感到焦虑。不过,不妨设想一下,假如卡巴真的在2025年获得了这两家顶级交易所的青睐,它的价格又会…

    2025年12月8日
    000
  • 美国证券交易委员会(Securities and Exchange Commission

    委员会于本周六发布的公告中提到,发起人或发行方并未以任何形式在本国资本市场内合法运作,这种模因货币便是典型例子之一。 美国证券交易委员会(SEC)已将一种名为“惩罚者币”(亦称“Spun”)的新模因币列为非法且未经许可的公开发行货币。公告明确指出,该模因币的发起人或发行人未按要求进行注册,也未取得S…

    2025年12月8日
    000
  • 虚拟协议[虚拟]跳增10.48%

    virtuals协议[虚拟]在过去24小时内上涨了10.48%,这一增长主要得益于现货和衍生品市场活跃度的提升。 在最近一天里,虚拟协议[虚拟价格]的价格上涨了10.48%,原因是现货和衍生品市场的活动增强推动了资产价值的上升。 显然,这样的增长并不是偶然发生的。 因此,Ambcrypto开始关注资…

    2025年12月8日
    000
  • 用Ruvi AI的VIP投资层系统奖励早期采用者

    ruvi ai预售的一大亮点是其独特的vip投资层级系统,该系统通过提供高额代币奖励,让小额投资也能转化为丰厚收益,以此回馈早期支持者。以下是其运作机制: 在快速变化的加密领域中,Ruvi AI不仅专注于技术创新,还致力于构建一个回馈用户的生态系统。其中,VIP投资层级系统尤为引人注目,它以高比例的…

    2025年12月8日
    000
  • 在2025年6月购买的顶级预售加密货币,准备好胜过Dogecoin和Shiba Inu:FPPE,Pepe的想法

    随着2025年6月的到来,顶级预售加密货币逐渐吸引了人们的目光,超越了广为人知的名字(例如dogecoin(doge)和shiba inu(shib))。 2025年6月带来了多种多样的加密项目,其中前代币展现了有趣的投资潜力。尽管Dogecoin(Doge)和Shiba Inu(Shib)持续受到…

    2025年12月8日
    000
  • ruvi ai(ruvi)可能是下一个爆炸的大加密货币

    加密货币市场生机勃勃,新机遇层出不穷。二强硬币(bnb)依然稳居重要地位。 加密货币市场持续变动,为投资者创造了全新机会。尽管Binance Coin(BNB)因与最大加密交易所之一的关系而继续保持强劲竞争力,但分析师指出,新型代币可能是2023年的关键焦点:Ruvi AI(Ruvi)。 Ruvi …

    2025年12月8日
    000
  • Unilabs Finance(UNIL)作为本周的突破表演者出现,价值超过60%

    尽管不少加密货币仍在努力站稳脚跟,比如pi币正围绕着0.38美元的关键支撑位波动,但unilabs finance(unil)无疑成为了本周的最大亮点。 在加密市场持续波动之际,许多代币都在艰难寻找稳定的基础,像Pi币目前就在0.38美元附近挣扎,而Unilabs Finance(UNIL)却凭借超…

    2025年12月8日
    000
  • 区块链 – ai混合动力项目Ruvi AI在预售期间筹集了150万美元

    传统上,卡尔达诺(cardano)作为加密货币市场的重要一员,凭借其创新的区块链技术吸引了众多投资者的目光。 传统上,卡尔达诺(cardano)作为加密货币市场的重要一员,凭借其创新的区块链技术吸引了众多投资者的目光。然而,一个新面孔正逐渐掀起波澜,成为许多精明投资者关注的焦点。 区块链与人工智能融…

    2025年12月8日
    000
  • XRP继续在薄冰上行走

    xrp仍在脆弱的状态下前行,因关键支撑位2.10美元正承受巨大压力。对此,市场分析师bit guru指出: Ripple币(原名XRP)似乎正行走在薄冰之上,其2.10美元的重要支撑区域正面临严峻挑战。 市场分析师BIT GURU评论道:“XRP多次试探2.10美元的支撑线,逐渐形成了一个潜在的下行…

    2025年12月8日
    000
  • 随着2025年的一半,投资者将重点转移到了有望大量回报和长期增长的项目上

    尽管solana一直保持着强大的区块链平台地位,但新兴的竞争者ruvi ai正凭借其令人瞩目的预售表现和实际应用场景吸引关注。 随着2025年的到来,加密货币投资者的目光逐渐转向那些有望带来显著回报和长远发展的项目。虽然Solana展现出作为区块链平台的强大实力,但新晋选手Ruvi AI正通过其出色…

    2025年12月8日
    000
  • REMITTIX(RTX)可能是下一个大笔钱加密:目标全球汇款

    remittix(rtx)当前正在平稳的市场环境中交易,其市值约为20.7亿美元,24小时成交量为3857万美元。近期并未出现显著的增长趋势。 如果您正寻找适合加入投资组合的小额加密货币,此时或许是入手的好机会。 某些低价币种展现出超越单纯炒作的实际应用场景。 实际应用驱动价值:Vechain(VE…

    2025年12月8日
    000
  • 主机AI(OSAK):100x 100x A AltCoin突破的下一个

    在佩佩与邦克等 meme 币引发热潮的市场中,一股悄然兴起的力量正在挑战传统认知——一种并非依赖于炒作,而是依托坚实技术支撑的新型资产正在崭露头角。让我们聚焦于这张图片,它见证了这一变革历程的一部分。 在佩佩和邦克(Pepe 和 Bonk)这类 meme 币风靡一时的背后,另一颗明星正悄然升起,它就…

    2025年12月8日
    000
  • 随着更广泛的加密货币市场的流行,雪崩(avax)下降了5%

    阿瓦克斯(Avax)是市场上限的第18大加密货币,随着更广泛的加密市场受到打击,人们感到压力。这种下降提出了投资者之间的疑问:这只是另一种更正,还是对令牌更深入的下降趋势的开始? 雪崩(Avax)是市值第18大加密货币,随着更广泛的加密市场受到打击,人们感到压力。在过去的24小时内,Avax下降了5…

    2025年12月8日
    000

发表回复

登录后才能评论
关注微信