当前位置: 首页 > 编程日记 > 正文

javascript运动系列第九篇——碰撞运动

前面的话

碰撞可以分为碰壁和互碰两种形式,上篇介绍了碰壁运动,本文将从浅入深地介绍碰撞运动的互碰形式

碰撞检测

对于互碰形式的碰撞运动来说,首先要解决的是碰撞检测。对于矩形元素的碰撞检测前面的博文已经详细介绍过,下面主要介绍圆形元素的碰撞检测

矩形元素的碰撞检测利用九宫格分析法,而圆形元素的碰撞检测则简单很多,判断两个圆形元素的半径之和是否大于两个圆形元素的圆心点坐标之间的距离即可

由示意图可知,元素一的圆心位置为(x1,y1),半径为r1,元素二的圆心位置为(x2,y2),半径为r2

两个元素圆心之间的距离len = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))

当len<= r1+r2时,说明两个圆形元素发生碰撞

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Document</title>
</head>
<body>
<div id="test1" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;border-radius: 50%;"></div>
<div id="test2" style="height: 200px;width: 200px;background:orange;position:absolute;top:150px;left:150px;border-radius: 50%;"></div>
<script>
function getCSS(obj,style){if(window.getComputedStyle){return getComputedStyle(obj)[style];}return obj.currentStyle[style];
} 
function bump(obj,objOther,bgColor){/***被碰元素***/var r1 = obj.offsetWidth/2;var x1 = parseFloat(getCSS(obj,'left')) + r1;var y1 = parseFloat(getCSS(obj,'top')) + r1;/**侵入元素**/var r2 = objOther.offsetWidth/2;var x2 = parseFloat(getCSS(objOther,'left')) + r2;var y2 = parseFloat(getCSS(objOther,'top')) + r2;//碰撞检测var len = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));if(len <= r1 + r2){obj.style.backgroundColor = 'red';}else{obj.style.backgroundColor = bgColor;}
}function drag(obj){obj.onmousedown = function(e){e = e || event;//提升当前元素的层级
        obj.style.zIndex = '1';//获取元素距离定位父级的x轴及y轴距离var x0 = this.offsetLeft;var y0 = this.offsetTop;//获取此时鼠标距离视口左上角的x轴及y轴距离var x1 = e.clientX;var y1 = e.clientY;//鼠标按下时,获得此时的页面区域var L0 = 0;var R0 = document.documentElement.clientWidth;var T0 = 0;var B0 = document.documentElement.clientHeight;//鼠标按下时,获得此时的元素宽高var EH = obj.offsetHeight;var EW = obj.offsetWidth;document.onmousemove = function(e){e = e || event;//获取此时鼠标距离视口左上角的x轴及y轴距离
            x2 = e.clientX;y2 = e.clientY;    //计算此时元素应该距离视口左上角的x轴及y轴距离var X = x0 + (x2 - x1);var Y = y0 + (y2 - y1);/******范围限定*******///获取鼠标移动时元素四边的瞬时值var L = X;var R = X + EW;var T = Y;var B = Y + EH;//在将X和Y赋值给left和top之前,进行范围限定//只有在范围内时,才进行相应的移动//如果脱离左侧范围,则left置L0if(L < L0){X = L0;}//如果脱离右侧范围,则left置为R0if(R > R0){X = R0 - EW;}//如果脱离上侧范围,则top置T0if(T < T0){Y = T0;}//如果脱离下侧范围,则top置为B0if(B > B0){Y = B0 - EH;}obj.style.left = X + 'px';obj.style.top = Y + 'px';//运行碰撞检测函数
            bump(test2,test1,'orange')}document.onmouseup = function(e){//降低当前元素的层级
            obj.style.zIndex = '0';//当鼠标抬起时,拖拽结束,则将onmousemove赋值为null即可
            document.onmousemove = null;//释放全局捕获if(obj.releaseCapture){obj.releaseCapture();}}//阻止默认行为return false;//IE8-浏览器阻止默认行为if(obj.setCapture){obj.setCapture();}}    
}
drag(test1);
drag(test2);
</script>      
</body>
</html>

无损碰撞

假设两个元素的碰撞,对元素的速度并不产生损耗,而只是改变元素速度方向

假设元素一在与元素二碰撞前的瞬时速度是v,将该速度分解为平行于碰撞方向的速度v1和垂直于碰撞方向的速度v2

碰撞发生后,碰撞方向的速度v1变成了反向的v1

将反向的v1分解到水平方向v1x和垂直方向v1y

将垂直于碰撞方向的速度v2分解到水平方向v2x和垂直方向v2y

    水平方向的速度vx = v2x - v1x垂直方向的速度vy = v2y - v1y

元素二的速度分解形式与元素一类似,就不再赘述

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Document</title>
</head>
<body>
<button id="btn1">开始运动</button>
<button id="reset">还原</button>
<div id="test1" style="height: 150px;width: 150px;background:pink;position:absolute;top:50px;left:50px;border-radius: 50%;"></div>
<div id="test2" style="height: 150px;width: 150px;background:orange;position:absolute;top:250px;left:250px;border-radius: 50%;"></div>
<script>
//声明元素的步长值
//步长值默认值为[-25,-20,-15,-10,-5,0,5,10,15,20]中的一个随机数
test1.stepX =  5*Math.floor(Math.random() * 10 - 5);
test1.stepY =  5*Math.floor(Math.random() * 10 - 5);
test2.stepX =  5*Math.floor(Math.random() * 10 - 5);
test2.stepY =  5*Math.floor(Math.random() * 10 - 5);
btn1.onclick = function(){collisionMove({obj:test1})collisionMove({obj:test2})
}
reset.onclick = function(){history.go();
}
function collisionMove(json){var obj = json.obj;var fn = json.fn;//声明x、y轴的当前值var curX,curY;//声明x、y轴方向var dirX = json.dirX;var dirY = json.dirY;dirX = obj.stepX > 0 ? '+' : '-';dirY = obj.stepY > 0 ? '+' : '-';//声明offset宽高var offsetWidth = obj.offsetWidth;var offsetHeight = obj.offsetHeight;//声明元素活动区域宽高var activeWidth = json.activeWidth;var activeHeight = json.activeHeight;//元素获取区域宽高默认值为可视区域宽高
    activeWidth = Number(activeWidth) || document.documentElement.clientWidth;activeHeight = Number(activeHeight) || document.documentElement.clientHeight;//声明left、top样式值var left,top;//清除定时器if(obj.timer){return;}//开启定时器
    obj.timer = setInterval(function(){//获取x、y轴的当前值
        curX = parseFloat(getCSS(obj,'left'));curY = parseFloat(getCSS(obj,'top'));bump(test1,test2);//更新left、top值
        left = curX + obj.stepX;top = curY + obj.stepY;//右侧碰壁前一刻,步长大于剩余距离,且元素向右运动时if((left > activeWidth - offsetWidth) && (dirX == '+')){left = activeWidth - offsetWidth;}//左侧碰壁前一刻,步长大于剩余距离,且元素向左运动时if((Math.abs(obj.stepX) > curX) && (dirX == '-')){left = curX;}//下侧碰壁前一刻,步长大于剩余距离,且元素向下运动时if((top > activeHeight - offsetHeight) && (dirY == '+')){top = activeHeight - offsetHeight;}//上侧碰壁前一刻,步长大于剩余距离,且元素向上运动时if((Math.abs(obj.stepY) > curY) && (dirY == '-')){top = curY;}obj.style.left= left + 'px';obj.style.top = top + 'px';//左侧或右侧碰撞瞬间if(left == activeWidth - offsetWidth || left == curX){obj.stepX = -obj.stepX;}//上侧或下侧碰撞瞬间if(top == activeHeight - offsetHeight || top == curY){obj.stepY = -obj.stepY;}//更新运动方向
        dirX = obj.stepX > 0 ? '+' : '-';dirY = obj.stepY > 0 ? '+' : '-';},20);            
}function getCSS(obj,style){if(window.getComputedStyle){return getComputedStyle(obj)[style];}return obj.currentStyle[style];
} 
//碰撞检测函数
function bump(obj,objOther){/***动态元素***/obj.r = obj.offsetWidth/2;
    obj.x0 = parseFloat(getCSS(obj,'left')) + obj.r;obj.y0 = parseFloat(getCSS(obj,'top')) + obj.r;/**静态元素**/objOther.r = objOther.offsetWidth/2;
    objOther.x0 = parseFloat(getCSS(objOther,'left')) + objOther.r;objOther.y0 = parseFloat(getCSS(objOther,'top')) + objOther.r;//圆心之间的距离var len = Math.sqrt((obj.x0-objOther.x0)*(obj.x0-objOther.x0) + (obj.y0-objOther.y0)*(obj.y0-objOther.y0));//发生碰撞if(len <= obj.r + objOther.r){//碰撞方向与水平负方向的夹角a var a = Math.atan(Math.abs((obj.y0-objOther.y0)/(obj.x0-objOther.x0)));
        stepChange(test1,test2,a);stepChange(test2,test1,a);}
}
//碰撞时,步长变化函数
function stepChange(obj,objOther,a){//步长合并
    obj.step = Math.sqrt(obj.stepX*obj.stepX + obj.stepY*obj.stepY);//假设总步长方向与x轴方向的夹角为b
    obj.b = Math.atan(Math.abs(obj.stepY/obj.stepX));//假设总步长方向与碰撞方向的夹角为c
    obj.c = Math.abs(a - obj.b);//步长分解//碰撞方向
    obj.step1 = obj.step*Math.cos(obj.c);//垂直方向
    obj.step2 = obj.step*Math.sin(obj.c);//按照运动元素(侵入元素)的起始运动方向对步长进行重新分解//左上if(obj.x0 <= objOther.x0 && obj.y0 <= objOther.y0){obj.stepX = -obj.step1*Math.cos(a) + obj.step2*Math.sin(a)obj.stepY = -obj.step1*Math.sin(a) - obj.step2*Math.cos(a)}//左下if(obj.x0 < objOther.x0 && obj.y0 > objOther.y0){obj.stepX = -obj.step1*Math.cos(a) + obj.step2*Math.sin(a)obj.stepY = obj.step1*Math.sin(a) + obj.step2*Math.cos(a) }//右上if(obj.x0 > objOther.x0 && obj.y0 < objOther.y0){obj.stepX = obj.step1*Math.cos(a) - obj.step2*Math.sin(a)obj.stepY = -obj.step1*Math.sin(a) - obj.step2*Math.cos(a)}//右下if(obj.x0 > objOther.x0 && obj.y0 > objOther.y0){obj.stepX = obj.step1*Math.cos(a) - obj.step2*Math.sin(a)obj.stepY = obj.step1*Math.sin(a) + obj.step2*Math.cos(a)}
}
</script>      
</body>
</html>

有损碰撞

匀速有损碰撞是在无损碰撞的基础上,每次碰撞都有一定的速度损耗,在碰撞或碰壁的瞬间乘以损耗因子即可

变速有损碰撞类似于击打台球,元素运动时,速度就一直在减小,碰撞或碰壁时,除了速度方向改变外,速度也有所损耗,当速度减小到0时,停止运动。由于代码相似,就不再重复,源码见此

相关文章:

Asp.Net 使用 GDI+ 绘制3D饼图入门篇源码

出处&#xff1a;www.knowsky.com 作者&#xff1a;www.knowsky.com <script languageJavaScript src"/ad/ad.js"></script> topn3dpie.aspx------------------<% Page language"c#" CodeBehind"topn3dpie.aspx.cs" AutoEventW…

【Visual C++】游戏开发笔记十三 游戏输入消息处理(二) 鼠标消息处理

本系列文章由zhmxy555编写&#xff0c;转载请注明出处。 http://blog.csdn.net/zhmxy555/article/details/7405479作者&#xff1a;毛星云 邮箱&#xff1a; happylifemxyqq.com 欢迎邮件交流编程心得上一节我们讲解了键盘消息处理相关的知识。键盘加鼠标作为目前人机交互…

当最懂 5G 的中国移动遇见云,移动云专题赛正式启动!

根据《中国云计算产业发展白皮书》预测&#xff0c;2023年中国云计算产业规模将超过3000亿人民币&#xff0c;其中&#xff0c;中国政府和企业上云率将超过60%。在国家新基建战略的大力推动下&#xff0c;5G和云计算迎来了巨大的发展契机。作为中国移动5G战略的重要组成部分&am…

spring配置文件详解【总结】

知其然&#xff0c;知其所以然 <?xml version"1.0" encoding"UTF-8"?> <beans:beans xmlns"http://www.springframework.org/schema/mvc" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance…

ucontext实现的用户级多线程框架3(实现echo服务器)

前面一篇文章实现了一个抢先式的用户级多线程框架&#xff0c;现在用那个框架编写一个echo服务&#xff0c; 因为只是个实验&#xff0c;所以代码写得比较杂乱&#xff0c;还有很多可能出错的情况也没有处理&#xff0c;这些在今后的进一 步研究中都会慢慢修改&#xff0c;下面…

asp.net 2.0中用GRIDVIEW插入新记录

出处&#xff1a;www.knowsky.com 作者&#xff1a;www.knowsky.com <script languageJavaScript src"/ad/ad.js"></script> name"mq" marginwidth"0" marginheight"0" src"../../ad.html" frameborder"no…

我在攻克机器学习硕士学位的那些年

编者按&#xff1a;人工智能发展日趋成熟&#xff0c;也成为众多开发者职业生涯的首选方向。然而相较于其他领域&#xff0c;人工智能中的深度学习、机器学习、计算视觉、神经网络等技术更为错综复杂&#xff0c;进修难度也更胜一筹。对此&#xff0c;对于入门和想要进阶的学生…

POJ 3174 暴力枚举

思路&#xff1a; 暴力枚举三个点 判一判 搞定 &#xff08;x1*y1x2*y2&#xff09; x1、y1、x2、y2为他们两两的差 //By SiriusRen #include <cstdio> using namespace std; int n,cnt; struct Point{int x,y;}point[888]; struct ans{int x,y,z;}ans[888]; int main…

TensorFlow、PyTorch夹缝之下:后浪的进击和野望

作者 | Just出品 | AI科技大本营&#xff08;rgznai100&#xff09;“我发现&#xff0c;软件研发总会延期。”一流科技CEO袁进辉说。按照他的预期&#xff0c;深度学习框架OneFlow做两年就能开源给开发者检验&#xff0c;但时间向后延长了近一年半&#xff0c;“确实预计的不准…

在Win 2003中配置ASP.net环境

作者&#xff1a;未知大家知道&#xff0c;Microsoft为了更好地预防恶意用户和攻击者的攻击&#xff0c;在默认情况下&#xff0c;没有将 IIS6.0 安装到 Windows Server 2003 家族的成员上。而且&#xff0c;当我们最初安装 IIS6.0 时&#xff0c;该服务在高度安全和"锁定…

网页中的数学公式

无意中发现一个在网页中显示数学公式的解决方案,MathJax&#xff0c;太崇拜这些人了&#xff01;他们才是真正地IT人&#xff0c;哪像国内我们这些民工&#xff1f; 代码如下&#xff1a; <!DOCTYPE html><html><head><title>MathJax AsciiMath Test P…

php删除目录下的所有文件和目录

<?php /*** 递归实现删除目录下的所有的文件和文件夹* param $dir 要删除的目录* param bool $deleteRootToo 是否删除根目录 默认不删除http://www.manongjc.com/article/1333.html*/ function unlinkRecursive($dir, $deleteRootToo false) {if(!$dh opendir($dir)){re…

DZX2无法读取会员短消息

我们在升级Discuz论坛时&#xff0c;如果没升级好&#xff0c;可能会出现各种各样的问题。比如登陆会员&#xff0c;但点“短消息”会出现错误&#xff0c;如下&#xff1a;提示&#xff1a;UCenter info: MySQL Query ErrorSQL:SELECT COUNT(*) FROM [Table]pm_members m WHER…

ASP.NET 如何操作文件

本文由chenyangasp版权所有&#xff0c;可以转载&#xff0c;复制&#xff0c;粘贴&#xff0c;并请注明出处&#xff0c;但不得修改&#xff01; 在asp.net操作文件的所有concept都在system.io namespace中&#xff0c;这个namespace包含读写操作文件所必需的类。 本文将详细…

摊牌了:我就靠这几点,搞定了算法面试官

很多时候&#xff0c;你即使提前复习了这些最常见的面试算法题&#xff0c;你依旧无法通过算法面试&#xff01;为什么&#xff1f;1. 你在提前准备复习的时候&#xff0c;在网上找了半天相应题目的分析文章&#xff0c;但你看了就是不懂。2. 你在面试的时候&#xff0c;卡壳了…

Spoooooky CSS 选择器

2019独角兽企业重金招聘Python工程师标准>>> 让我们今年有一些万圣节主题的帖子精神&#xff01;我会从超过 GRAVE.eR.CSS选择器中挑选一些将冻结你骨头的选择器。也许不可能&#xff0c;但他们至少有点怪异。 迟钝的猫头鹰选择器&#xff08;the lobotomized owl s…

关于无法创建aps.web项目的解决办法

出处&#xff1a;CSDN 作者&#xff1a;ahking <script languageJavaScript src"/ad/ad.js"></script> 1、当站点主目录没有创建应用程序&#xff1a; 通过FP扩展虚拟目录的方式来建立WEBAPP,步骤如下&#xff1a; &#xff08;1&#xff09;、右击站…

国内ntp时间服务器ip地址

NTP&#xff08;Network Time Protocol&#xff09;是由美国德拉瓦大学的David L. Mills教授于1985年提出&#xff0c;除了可以估算封包在网络上的往返延迟外&#xff0c;还可独立地估算计算机时钟偏差&#xff0c;从而实现在网络上的高精准度计算机校时&#xff0c;它是设计用…

谷歌顶级量子科学家详述他为何从谷歌辞职

加州大学圣塔芭芭拉分校&#xff08;UCSB&#xff09;的教授John Martinis作者 | Paul Smith-Goodson译者 | 天道酬勤&#xff0c;责编 | Carol 约翰马丁尼斯&#xff08;John Martinis&#xff09;教授从Google辞职的消息在整个量子学界引起了轩然大波。消息宣布几天后&#x…

论文笔记之:Generative Adversarial Text to Image Synthesis

Generative Adversarial Text to Image Synthesis ICML 2016 摘要&#xff1a;本文将文本和图像练习起来&#xff0c;根据文本生成图像&#xff0c;结合 CNN 和 GAN 来有效的进行无监督学习。 Attribute Representation: 是一个非常具有意思的方向。由图像到文本&#xff0c;可…

ADO.NET 2.0 中的架构

Bob BeaucheminDevelopMentor 适用于&#xff1a;Microsoft ADO.NET 2.0Microsoft Visual Studio 2005C# 编程语言 摘要&#xff1a;了解在 ADO.NET 中对于从您的数据源访问元数据的增强支持。下载相关的 SchemasSample.exe 示例代码。 本页内容 深入了解新的公共元数据 API究…

Android实现程序前后台切换效果

本文演示如何在Android中实现程序前后台切换效果。 在介绍程序实现之前&#xff0c;我们先看下Android中Activities和Task的基础知识。 我们都知道&#xff0c;一个Activity 可以启动另一个Activity,即使这个Activity是定义在别一个应用程序里的&#xff0c;比如说&#xff0c;…

如果特斯拉制造相机的梦想像激光雷达一样真正实现,它可能会帮助到更多同行...

这张来自伪激光雷达论文的图片显示了旧的黄色实点云作者 | Brad Templeton译者 | 天道酬勤&#xff0c;责编 | Carol特斯拉 CEO 埃隆马斯克&#xff08;Elon Musk&#xff09;对自动驾驶激光雷达&#xff08;3D图像技术&#xff09;的看法是众所周知的。他不打算在特斯拉里使用…

java分享第五天(数组)

1 声明数组变量&#xff1a; double[] mylist; or double mylist[]; 2 创建数组&#xff1a; 可以通过使用new运算符使用以下语法创建一个数组&#xff1a; arrayRefVarnew dataType[arraySize]; 上面的语句做了两件事&#xff1a; 它创建一个数据使用new dataType[…

效率!效率!效率!

原著&#xff1a;Mark Davis 翻译&#xff1a;onefi 2004年4月21日 摘要&#xff1a; 此篇文章包括了一些在网页设计中时常用到的脚本。我们可以清晰的体会到其中的执行速度。这将有助于提高您的动态网页的速度。 导言&#xff1a; 自从有了IE4.0以后&#xff0c;我们所看到的…

Android UI Button 和GridView 的设计--优化(2)

Android 按钮的UI设计&#xff0c;ListView 以及GridView的UI设计 一.按钮的状态 我们一般搞UI设计,按钮通常有三个状态&#xff1a;normal(正常状态);focus(焦点状态),pressed(按下状态)。如下图所示: 我们会在res/drawable目录下定义一个资源文件&#xff0c;比如我们本例中要…

玩转社区开源贡献,看这篇就够了!

来源 | TensorFlow本文来自社区投稿与征集。作者唐源&#xff0c;现任蚂蚁集团技术专家&#xff0c;目前专注于建立 AI 基础架构和自动机器学习平台。本文转自&#xff1a;https://zhuanlan.zhihu.com/p/165098355作为最早一批非谷歌的 TensorFlow 社区贡献者&#xff0c;同时也…

grub2 命令行进入系统

有时候grub引导可能出问题&#xff0c;因此我们需要在grub界面利用命令行进入系统。下边就做一个简单的介绍。1、在grub界面&#xff0c;按c进入命令行界面2、命令行输入“ grub>set root(hd ”之后按tab键&#xff0c;查看你的硬盘&#xff0c;hd0表示第一块硬盘&#xf…

梯度中心化,一行代码加速训练并提升泛化能力

来源 | 晓飞的算法工程笔记优化器(Optimizer)对于深度神经网络在大型数据集上的训练是十分重要的&#xff0c;如SGD和SGDM&#xff0c;优化器的目标有两个&#xff1a;加速训练过程和提高模型的泛化能力。目前&#xff0c;很多工作研究如何提高如SGD等优化器的性能&#xff0c;…

Microsoft程序员测试题

原创&#xff1a;onefi http://www.frontfree.net/2003年6月1日 最近大家在网站上看到不少Microsoft的测试题&#xff0c;引来不少的眼光。我在这里把所有的测试题加以整理&#xff0c;再附上自己的答案。&#xff08;个别题目答案有多种&#xff0c;文本仅代表作者的思路&a…