jjzjj

javascript - 计算两个椭圆之间的重叠

coder 2024-12-14 原文

我有 2 ellipses我需要检测它们之间的任何重叠。

这是一个检测两个圆之间重叠的示例,我正在寻找与椭圆类似的东西:

var circle1 = {radius: 20, x: 5, y: 5};
var circle2 = {radius: 12, x: 10, y: 5};

var dx = circle1.x - circle2.x;
var dy = circle1.y - circle2.y;
var distance = Math.sqrt(dx * dx + dy * dy);

if (distance < circle1.radius + circle2.radius) {
    // collision !
}

对于椭圆,我有相同的变量,因为我在垂直轴上的半径比水平轴上的半径小 2 倍:

var oval1 = {radius: 20, x: 5, y: 5};
var oval2 = {radius: 12, x: 10, y: 5};

// what comes here?

if ( /* condition ? */ ) {
    // collision !
}

var result = document.getElementById("result");
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");


// First eclipse
var eclipse1 = { radius: 20,
                 x: 100,
                 y: 40 };


// Second eclipse
var eclipse2 = { radius: 20,
                 x: 120,
                 y: 65 };



function have_collision( element1, element2 )
{
  var dx = element1.x - element2.x;
  var dy = element1.y - element2.y;
  var distance = Math.sqrt(dx * dx + dy * dy);

  if (distance <= element1.radius + element2.radius) {
    return true;
  }
  else {
    return false;
   }
}

function draw( element ) {
// http://scienceprimer.com/draw-oval-html5-canvas
context.beginPath();
for (var i = 0 * Math.PI; i < 2 * Math.PI; i += 0.01 ) {
  xPos = element.x - (element.radius/2 * Math.sin(i)) * Math.sin(0 * Math.PI) + (element.radius * Math.cos(i)) * Math.cos(0 * Math.PI);
  yPos = element.y + (element.radius * Math.cos(i)) * Math.sin(0 * Math.PI) + (element.radius/2 * Math.sin(i)) * Math.cos(0 * Math.PI);

  if (i == 0) {
    context.moveTo(xPos, yPos);
  } else {
    context.lineTo(xPos, yPos);
  }
}
context.fillStyle = "#C4C4C4";
context.fill();
context.lineWidth = 2;
context.strokeStyle = "#FF0000";
context.stroke();
context.closePath();
}

function getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: evt.clientX - rect.left,
    y: evt.clientY - rect.top
  };
}

canvas.addEventListener('mousemove', function(e) {
  var mousePos = getMousePos(canvas, e);
  eclipse2.x = mousePos.x;
  eclipse2.y = mousePos.y;
  result.innerHTML = 'Collision ? ' + have_collision( eclipse1, eclipse2 );
  context.clearRect(0, 0, canvas.width, canvas.height);
  draw( eclipse1 );
  draw( eclipse2 );
}, false);


draw( eclipse1 );
draw( eclipse2 );
result.innerHTML = 'Collision ? ' + have_collision( eclipse1, eclipse2 );
#canvas {
  border: solid 1px rgba(0,0,0,0.5);
}
<canvas id="canvas"></canvas>
<p id="result"></p>
<code>distance = Math.sqrt(dx * dx + dy * dy);</code>

最佳答案

由于你的椭圆非常具体,因为它们只是沿 Y 轴缩小的圆,你可以想象如果你将平面沿 Y 轴拉伸(stretch) 2 倍会发生什么。你会同意那些重叠的椭圆会变成重叠的圆,而那些不重叠的椭圆在拉伸(stretch)后也不会重叠。你可以把它想象成椭圆是画在弹性 Material 上的,你只是在垂直方向拉伸(stretch) Material :这当然不会改变任何重叠情况。

所以,你可以这样写:

var stretchedDistance = Math.sqrt(dx * dx + 2 * dy * 2 * dy);

... 并继续保持目前的条件,因为它基于 X 方向的半径,拉伸(stretch)后也是 Y 方向的半径。当然,我以不同的方式命名了变量,因此您应该使用该变量进行测试。所以为了完成代码,我们得到:

var stretchedDistance = Math.sqrt(dx * dx + 4 * dy * dy);
if (stretchedDistance < circle1.radius + circle2.radius) {
    // collision !
}

请注意,拉伸(stretch)是通过乘以 dy 来考虑的与 2. 在距离公式中,写成 4 * dy * dy 是等效且更短的.

这是很好的互动 fiddle你创建了,我更新了它。

关于javascript - 计算两个椭圆之间的重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33849519/

有关javascript - 计算两个椭圆之间的重叠的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  2. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  3. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  4. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  5. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  6. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  7. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  8. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  9. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  10. ruby - 具有两个参数的 block - 2

    我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋

随机推荐