/*** 两小球弹性碰撞*

* 参考链接: https://www.jianshu.com/p/02ecbbb6afeb*/

private static void ballCollide(MovableUnit ball1, MovableUnit ball2) {

// 初始速度向量 Vector2d ball1SpeedInitial = ball1.getVector();

Vector2d ball2SpeedInitial = ball2.getVector();

// 球心方向单位向量 final double radian = computeRadian(ball1.getCentrePosition(), ball2.getCentrePosition());

Vector2d horizontalVector = getVector(radian, 1);

// 垂直球心方向单位向量 Vector2d perpendicularVector = getVector(radian + Constant.HALF_PI, 1);

// 速度在球心向量上的分速度投影长度 double ball1SpeedHorizontalProjectionLength = ball1SpeedInitial.dotProduct(horizontalVector);

double ball2SpeedHorizontalProjectionLength = ball2SpeedInitial.dotProduct(horizontalVector);

// 速度在垂直球心向量上的分速度投影长度 double ball1SpeedPerpendicularProjectionLength = ball1SpeedInitial.dotProduct(perpendicularVector);

double ball2SpeedPerpendicularProjectionLength = ball2SpeedInitial.dotProduct(perpendicularVector);

// 碰撞后球心方向上的分速度投影长度 double ball1SpeedHorizontalProjectionFinalLength;

double ball2SpeedHorizontalProjectionFinalLength;

if (ball1.weight == ball2.weight) {

// 质量相等 ball1SpeedHorizontalProjectionFinalLength = ball2SpeedHorizontalProjectionLength;

ball2SpeedHorizontalProjectionFinalLength = ball1SpeedHorizontalProjectionLength;

} else {

// 质量不相等 ball1SpeedHorizontalProjectionFinalLength = (ball1SpeedHorizontalProjectionLength * (ball1.weight - ball2.weight) + 2 * ball2.weight * ball2SpeedHorizontalProjectionLength)

/ (ball1.weight + ball2.weight);

ball2SpeedHorizontalProjectionFinalLength = (ball2SpeedHorizontalProjectionLength * (ball2.weight - ball1.weight) + 2 * ball1.weight * ball1SpeedHorizontalProjectionLength)

/ (ball1.weight + ball2.weight);

}

// 碰撞后球心方向上的分速度向量 Vector2d ball1SpeedHorizontalProjectionFinalVector = horizontalVector.multiply(ball1SpeedHorizontalProjectionFinalLength);

Vector2d ball2SpeedHorizontalProjectionFinalVector = horizontalVector.multiply(ball2SpeedHorizontalProjectionFinalLength);

// 碰撞后垂直球心方向上的分速度向量 Vector2d ball1SpeedPerpendicularProjectionVector = perpendicularVector.multiply(ball1SpeedPerpendicularProjectionLength);

Vector2d ball2SpeedPerpendicularProjectionVector = perpendicularVector.multiply(ball2SpeedPerpendicularProjectionLength);

// 两个球最终的速度向量 Vector2d ball1SpeedFinalVector = ball1SpeedHorizontalProjectionFinalVector.add(ball1SpeedPerpendicularProjectionVector);

Vector2d ball2SpeedFinalVector = ball2SpeedHorizontalProjectionFinalVector.add(ball2SpeedPerpendicularProjectionVector);

// 更新速度 applyVector(ball1SpeedFinalVector, ball1);

applyVector(ball2SpeedFinalVector, ball2);

}

/*** 平面向量工具类*

* 参考链接: https://www.cnblogs.com/vokie/p/3602063.html*/

public class Vector2d {

private double x;

private double y;

public Vector2d() {

x = 0;

y = 0;

}

public Vector2d(double x, double y) {

this.x = x;

this.y = y;

}

//获取弧度 public double getRadian() {

return Math.atan2(y, x);

}

//获取角度 public double getAngle() {

return getRadian() / Math.PI * 180;

}

@Override

public Vector2d clone() {

return new Vector2d(x, y);

}

/*** 获取长度*/

public double getLength() {

return Math.sqrt(getLengthSQ());

}

public double getLengthSQ() {

return x * x + y * y;

}

//向量置零 public Vector2d Zero() {

x = 0;

y = 0;

return this;

}

public boolean isZero() {

return x == 0 && y == 0;

}

//向量的长度设置为我们期待的value public void setLength(double value) {

double _angle = getAngle();

x = Math.cos(_angle) * value;

y = Math.sin(_angle) * value;

}

//向量的标准化(方向不变,长度为1) public Vector2d normalize() {

double length = getLength();

x = x / length;

y = y / length;

return this;

}

//是否已经标准化 public boolean isNormalized() {

return getLength() == 1.0;

}

//向量的方向翻转 public Vector2d reverse() {

x = -x;

y = -y;

return this;

}

//2个向量的数量积(点积) public double dotProduct(Vector2d v) {

return x * v.x + y * v.y;

}

//2个向量的向量积(叉积) public double crossProduct(Vector2d v) {

return x * v.y - y * v.x;

}

//计算2个向量的夹角弧度 //参考点积公式:v1 * v2 = cos * |v1| *|v2| public static double radianBetween(Vector2d v1, Vector2d v2) {

if (!v1.isNormalized()) v1 = v1.clone().normalize(); // |v1| = 1 if (!v2.isNormalized()) v2 = v2.clone().normalize(); // |v2| = 1 return Math.acos(v1.dotProduct(v2));

}

//弧度 = 角度乘以PI后再除以180、 推理可得弧度换算角度的公式 //弧度转角度 public static double radian2Angle(double radian) {

return radian / Math.PI * 180;

}

//向量加 public Vector2d add(Vector2d v) {

return new Vector2d(x + v.x, y + v.y);

}

//向量减 public Vector2d subtract(Vector2d v) {

return new Vector2d(x - v.x, y - v.y);

}

//向量乘 public Vector2d multiply(double value) {

return new Vector2d(x * value, y * value);

}

//向量除 public Vector2d divide(double value) {

return new Vector2d(x / value, y / value);

}

}

java小球与小球碰撞_Java实现小球间的弹性碰撞(考虑小球质量)相关推荐

  1. java编写游戏_java编写小游戏-大球吃小球

    游戏界面: 点击火箭开始游戏 点击Exit退出游戏 左上角显示当前成绩和历史最高分 退出自动保存最高成绩 代码获取 扫码关注微信公众号[程序猿声] 在后台回复[EBG]不包括[]即可获取. 玩法: 玩 ...

  2. java编写一个移动物体_java编写一个可以上下移动的小球:运行后,可以通过上下左右键进行移动...

    /* * 功能:加深对事件处理机制的理解 * 1.通过控制上下左右键,来控制一个小球的位置 */ package com.test1; import java.awt.*; import javax. ...

  3. java做漂亮的游戏界面_java对打小游戏界面漂亮

    [实例简介] 想上传几张图片的发现居然上传不了 第一次用这个 本人也是第一次写java对战小游戏 写着耍了耍 代码中有分层控制逻辑到了后面不是很美丽了,不过总的来说界面还算不错,也不要积分了 ,大家可 ...

  4. java坦克大战互相碰撞_Java课程设计——坦克大战

    坦克大战--坦克类 一. 团队课程设计博客链接 二.个人负责模块和任务说明 模块:坦克类(玩家坦克类+电脑坦克类),代码整合 三.代码的提交记录截图 四.负责模块和任务详细说明 玩家坦克继承Visib ...

  5. java里冒泡排序编程案例_java冒泡排序小实例

    首先我们了解下什么是冒泡排序: 冒泡排序就是把小的元素往前调或者把大的元素往后调.比较是相邻的两个元素比较,交换也发生在这两个元素之间.所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的: ...

  6. Java 丢手绢游戏 求和_java入门小程序—17人游戏(丢手绢问题)

    一.问题描述: 17个人围成一个圈,编号为1~17,从第一号开始报数,报到3的倍数的人离开,一直数下去,直到最后只有一个人,求此人编号. 二.问题提示: 使用一维数组,数组元素初始为1,从1开始把数字 ...

  7. [Java]桌球小游戏(小球任意角度碰撞)

    import javax.swing.*; import java.awt.*; public class BallGame extends JFrame {/*继承swing里面的窗口类*///加载 ...

  8. JAVA编程实战之编写小游戏-大球吃小球(eat ball game)

    游戏界面: 点击火箭开始游戏 点击Exit退出游戏 左上角显示当前成绩和历史最高分 退出自动保存最高成绩 代码获取 扫码关注微信公众号[程序猿声] 在后台回复[EBG]不包括[]即可获取. 玩法: 玩 ...

  9. java小游戏实训目的_Java弹球小游戏实验报告.doc

    Java弹球小游戏实验报告 滨江学院 Java程序设计实验报告 题 目 弹球小游戏 姓 名 许浩 学 号 20112346064 学 院 滨江学院 专 业 网络工程 年 级 2011级 指导教师 张舒 ...

  10. js小球与边框碰撞反弹_四叉树在碰撞检测中的应用

    缘起 <你被追尾了>中预告了加速碰撞检测的算法--四叉树(for 2D),所以本文就来学习一下. 分析 首先是为什么要使用四叉树进行优化,其实<你被追尾了>中已经说了,这里简单 ...

最新文章

  1. java轻量级IOC框架Guice
  2. 电脑如何进入bios模式_如何进入BIOS设置U盘启动盘
  3. Mac使用sdkmanager从官网下载新版android SDK
  4. C++代码 快速排序总结
  5. MFC学习笔记(1)
  6. PN5321(PN5321A3HN/C106)国产替代,FSVP532软硬件兼容,支持A卡,B卡,FeliCa卡,支持ISO/IEC18092,ECM340点对点
  7. DICOM笔记-使用DCMTK读取DICOM文件保存DICOM文件
  8. 论文阅读-Social Fingerprinting:detection of spambot groups through DNA-inspired behavioral modelingCCFA
  9. html怎么设置文字竖排,CSS文字竖排
  10. Python之字体反爬详细操作
  11. 从0写USB摄像头驱动程序
  12. android回传数据实验报告,传热综合实验实验报告.doc
  13. 语句摘抄——第26周
  14. 2021年中国影院行业发展现状:院线影院规模集中度持续增强,票房前五名排名保持稳固[图]
  15. matlab bsxfun memory,matlab – BSXFUN关于关系操作的内存效率
  16. Python的re库和正则表达式
  17. (C++)1~10000质数表
  18. python求素数(质数)及其优化
  19. 三星s10更新Android10,经历了三星s10的最近一次升级,我对安卓对三星有了新的认知...
  20. IBM MQ运维常用命令

热门文章

  1. 解析xml的四种方式
  2. 山上有一口缸可以装50升水,现在有15升水。老和尚叫小和尚下山挑水,每次可以挑5升。问:小和尚要挑几次水才可以把水缸挑满?通过编程解决这个问题。
  3. PrepareStatement对象
  4. pymysql长时间连接自动断开解决方案
  5. 【PhotoShop基础A篇】磨皮/图层/液化
  6. 网站速度这样优化,让你的网站飞起来
  7. [BZOJ2906] 分块
  8. 解决耳机插入电脑没声音问题
  9. 台式计算机如何组装,怎样组装基本台式机
  10. win10删除微软拼音