HTML5 Canvas 实现 圆环碰撞检测 (方式二)

2023-11-15

【JS】Canvas 圆环碰撞 圆环外与圆环内与圆环上 (方式二)

咦,好像,终于有好东西了~,结合上一篇,这一篇将更简单,推荐

  • 圆与多边形 圆环与多边形 其实和 与多边形碰撞一样,但也有几个不同之处
  • 下面就来看看新实现的 圆环碰撞 列出几个重要部分
  • 点的碰撞有两种常用的判断 一:射线法 、 二 转角发(这个转角叫法很多,就是点按顺序与多边形每个的角点的角度累加)
  • 下面是经过测试的代码,简单,很简单,以前是我想复杂了

页面代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>圆环碰撞</title>
    <style>
        body {
            overflow: hidden;
            background: #000;
        }
        body,
        html {
            height: 100%;
            width: 100%;
            margin: 0;
            padding: 0;
        }
        #backs{
			position: absolute; 
			z-index: 1;
			left:0;
			top:0;
			background-color: #fff;
		}
    </style>
</head>
<body onclick="updPos();">
    <canvas id="backs" width="100%" height="100%"  ></canvas>
</body>
</html>

核心代码 代码看着很长 里面包含了分离轴碰撞检测 还有圆环碰撞检测的实现

		
		var oAnim=document.getElementById('backs');
		oAnim.width = window.innerWidth;
		oAnim.height = window.innerHeight;
		
		var cont = oAnim.getContext("2d");
		
		//前面这些简单 圆环的参数 r 是半径 w 是圆环区域的宽度
		var YH={
			x:180,
			y:200,
			r:100,
			w:10
		}
		//p 是多边形的各个点 顺序连接
		var DBX = {
			p:[{
				x:300,
				y:100
			},{
				x:400,
				y:100
			},{
				x:400,
				y:200,
			},{
				x:300,
				y:200
			}],
			color:"rgba(255,0,0,1)"
		}
		
		//圆环的绘制方法
		function YuanHuan(){
		    var rgbgrad =cont.createRadialGradient(YH.x, YH.y, YH.r-YH.w, YH.x, YH.y, YH.r); //渐变填充器
			rgbgrad.addColorStop(0,'rgba(255,255,0,0)');
			rgbgrad.addColorStop(0,'rgba(255,255,0,1)');
			
			cont.beginPath(); 
			//画圆
			cont.arc(YH.x, YH.y, YH.r, 0, Math.PI * 2);
			cont.fillStyle = rgbgrad; //填充样式 放入 渐变填充器
			cont.fill(); //填充
			
			cont.closePath();
		}
		//多边形的绘制方法
		function DuoBianXin(){
			cont.beginPath();
			cont.lineCap = "square";
			cont.moveTo(DBX.p[0].x,DBX.p[0].y);
			for(var i=1;i<DBX.p.length;i++) {
				cont.lineTo(DBX.p[i].x,DBX.p[i].y);
			}
			
			cont.lineWidth=0.1;
			cont.fillStyle  = DBX.color;
			cont.strokeStyle = DBX.color;
			
            cont.stroke();
            cont.fill();
            
			cont.closePath();
		}
		
		
		function isCollideArc(ring,rect){
			
			// 循环多边形的每个点到圆心的距离
			// 开方 是内部迭代,直到数字无限接近开方后的值
			// 所以 不用开方的地方 与它对比的数用了平方 
			
			let px = ring.x,
	            py = ring.y,
	            list = rect.p,
	            max = 0,
	            min = Math.pow(px-list[0].x,2) + Math.pow(py-list[0].y,2);//不开方
	        //min = Math.sqrt(Math.pow(px-list[0].x,2) + Math.pow(py-list[0].y,2));
	
	        for(let r=1 ,sp ;r<list.length;r++){
	            //sp = Math.sqrt(Math.pow(px-list[r].x,2) + Math.pow(py-list[r].y,2));
	            sp = Math.pow(px-list[r].x,2) + Math.pow(py-list[r].y,2);//不开方
	            if(sp<min) min = sp;
	            else if (sp>max) max = sp;
	        }
	
	        //圆环内 //如果与圆对比 不需要这一行最大值的判断
	        if(max <( ring.r-ring.w)*( ring.r-ring.w)) return false;//最大值 小与 内圆的半径
	        //如果 最小值小与 半径 说明一定重叠
	        if(min <= ring.r*ring.r ) return true;
			
			//以上条件不成立 使用 转角法
			return zhuanjiao(px,py,list);
		}
		
		/*  转角法
			通过判定点与多边形边角点 按顺序 进行角度累加
			累加的角 是以上一次的角点为起点,以判定点当圆心,旋转至当前角点(忽略旋转点到角点的距离)中间的角度
			如果在多边形内,角度和 等于 360 ° 否则就会不等于
		*/
		function zhuanjiao(px,py,list){
			
	        let i, l , j , sx , sy , tx ,ty ,sum = 0,agl = Math.PI * 2 ;
	
	        for(i = 0, l = list.length, j = l - 1; i < l; j = i, i++) {
	            sx = list[i].x;
	            sy = list[i].y;
	            tx = list[j].x;
	            ty = list[j].y;
	
	            // 点与多边形顶点重合或在多边形的边上
	            if((sx - px) * (px - tx) >= 0 && (sy - py) * (py - ty) >= 0 && (px - sx) * (ty - sy) === (py - sy) * (tx - sx)) {
	                return true;
	            }
	
	            // 点与相邻顶点连线的夹角
	            let angle = Math.atan2(sy - py, sx - px) - Math.atan2(ty - py, tx - px);
	
	            // 确保夹角不超出取值范围(-π 到 π)
	            if(angle >= Math.PI) {
	                angle = angle - agl;
	            } else if(angle <= -Math.PI) {
	                angle = angle + agl;
	            }
	
	            sum += angle;
	        }
	
	        // 计算回转数并判断点和多边形的几何关系
	        return  Math.round(sum / Math.PI) !== 0;
		}
        
		//执行碰撞判断与绘制
		function update(){
			
			DBX.color = isCollideArc(YHDBX)?"rgba(255,0,255,1)":"rgba(255,0,0,1)";
			
			cont.clearRect(0, 0, window.innerWidth, window.innerHeight);
			YuanHuan();
			DuoBianXin();
			
			requestAnimationFrame(update);
		}
		
		function updPos(){
			//获取鼠标位置
			
			var e = event || window.event;
			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
			var x = e.pageX || e.clientX + scrollX;
			var y = e.pageY || e.clientY + scrollY;
			
      		YH.x= x;
      		YH.y= y;
      		
      		console.log("click X:"+x+" Y:"+y);
		}
		
		update();

点与多边形碰撞判断 详细说明看下方说明
上面文中提到的 射线法 可以查看下方给出的连接
连接:http://www.html-js.com/article/1528
上面代码中提到的 转角法 可以查看下方给出的连接
连接:http://www.html-js.com/article/1538
以上都是 判断点是否在多边形内部 的相关内容

这次总结,不亏,以前走的弯路,使我又学到了关于线段碰撞的检测,有人会问,点与线段的碰撞是不是也要写一堆,这里就直接对不懂的人简单说下,线段与点的关系:就如同三角形三边的关系,没错,三角形两边之和必定大于第三边 现在根据这个,断言:一点到线段两端点的距离之和等于线段长度就代表相交

如有误导请联系,我会进行修正。
邮箱 hbck_gwx@qq.com

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HTML5 Canvas 实现 圆环碰撞检测 (方式二) 的相关文章

随机推荐

  • 09-1_Qt 5.9 C++开发指南_Qchart概述

    Qt Charts 可以很方便地绘制常见的折线图 柱状图 饼图等图表 不用自己耗费时间和精力开发绘图组件或使用第三方组件了 本章首先介绍 Qt Charts 的基本特点和功能 以画折线图为例详细说明 Qt Charts 各主要部件的操作方法
  • 算法基础课:第一讲——基础算法

    文章目录 前言 排序 1 快速排序 作用 算法思想 模板 例题 AC代码 2 归并排序 作用 算法思想 模板 例题 AC代码 二分 1 整数二分 作用 算法思想 模板 例题 AC代码 总结 2 浮点数二分 算法思想 模板 例题 AC代码 高
  • vue中ref的使用

    今天看了别人写的代码 有些地方不太理解 查阅资料之后真的是受益匪浅 在这里分享给大家
  • 从0到1使用 Webpack5 + React + TS 构建标准化应用

    前言 本篇文章主要讲解如何从一个空目录开始 建立起一个基于webpack react typescript的标准化前端应用 技术栈 webpack5 React18 TS 工程化 eslint prettier husky git hook
  • 田志刚:个人知识管理常用软件、工具介绍

    一把菜刀 厨师可以用来做出可口的美味佳肴 也可以被犯罪分子利用作为伤害人的凶器 这就是工具的特性 个人知识管理的工具 软件也是如此 个人知识管理工具 软件和系统是个人管理自己知识的一个热点问题 我们认为在工具的选择和使用上主要需做到知理 知
  • 文件对象MultipartFile和文件对象File的使用方法

    1 前端上传的文件对象file public String upload MultipartFile file throws IOException String originalFilename file getOriginalFilen
  • 如何轻松实现内网穿透?异地办公?调试微信小程序?

    步骤很简单 只需三步 1 从 https www i996 me 获取获取你的公网域名和访问Token 项目托管在 https github com bugfan i996 2 在Max Linux 环境下 Windows类似 打开一个终端
  • AD20.0.1上手教程——机器狗

    我们假装已经安装好了AD 首先 我们先理一下AD这个软件的逻辑 一个项目包含一个工程 PrjPCB 里面有一个源文件和库文件两类 源文件包括原理图 SchDoc 和印制版图 PcbDoc 库文件包括封装库 PcbLib 和原理图库 SchL
  • [Python微信开发] 一.itchat入门知识及微信自动回复、微信签名词云分析

    最近准备学习微信小程序开发 偶然间看到了python与微信互动的接口itchat 简单学习了下 感觉还挺有意思的 故写了篇基础文章供大家学习 itchat是一个开源的微信个人号接口 使用python调用微信从未如此简单 使用不到三十行的代码
  • Qt5 Alpha Complie in XP with Mingw/vs2008

    根据 http qt project org wiki Qt 5 Alpha building instructions 提示 下载 Perl http www perl org get html python http python or
  • unity中使用tensorflow 深度学习框架 ml-agents v0.8,TFSharpPlugin.unitypackage 0.5最新版 教程(for mac windows)

    unity tensorflow 环境安装 unity tensorflow 官方 教程 unity版本必须经过配置 不像c 那样简单 第一部分 安装tensorflow环境 1 安装anaconda anaconda 是python的包管
  • 动态数组的摊销分析【Python也有数组的类似概念比如list】

    我先说一下数组版的动态数组的摊销分析 我先上C 的代码 没有摊销的 吧 应该都能看懂吧 即使没学过C和C pragma once include
  • 给出一组数删除其中的几个使得剩下的数从左到右最小

    个人感觉是个特别经典的题目 有两个关键点 1 剩下的数最小 2 删除的数小于等于n 1 使剩下的数最小 思路 依次遍历正整数的各位数字 将单调递减区间的的第一个数删掉 如果整个字符串已经单调递增就删除最后的数 代码如下 include
  • 多线程的异步调用(一)

    最近手头做的项目中 用到了多线程的异步调用 在控制线程中实时的检测硬件的变化 如果硬件发生了某些变化 那么需要通知别的模块做一些相应的操作 为了让这些操作不会影响控制线程的继续运行 就在多线程中使用了异步调用的方法 using System
  • 【华为OD机试 2023】优雅子数组(C++ Java JavaScript Python)

    华为od机试题库 华为OD机试2022 2023 C Java JS Py https blog csdn net banxia frontend category 12225173 html 华为OD机试2023最新题库 更新中 C Ja
  • C++关键字入门(小白必看)

    目录 0 C 关键字 1 asm 2 catch throw try 3 inline 4 bool true false 5 cast 6 typeid获取类型信息 7 private protected和public 8 typenam
  • 串口发送到PC端的两种方式

    配置串口的时候要注意 F1系列中 GPIO 配置成输入浮空输入模式 GPIO TX要配置成推挽复用模式 F4系列中 GPIO要配置成复用模式 同时要将端口复用为串口模式 接下来可用两种方式发送到PC端 一 重定义printf函数 注意要使用
  • WebGoat-5.4实验笔记(2)

    webgoat其他项目的学习笔记在我的博客里有 General 总体目标 1 Http Basics HTTP基础知识 点击Http Basics 查看页面信息 显示输入信息后 服务器接收请求后会返回用户的输入信息 并回显给用户 我在Ent
  • MySQL数据库的基本操作--DDL

    文章目录 MySQL数据库的基本操作 对表结构的常用操作 MySQL中的数据类型 对表结构的常用操作 其他操作 对数据库的常用操作 修改表结构格式 MySQL数据库的基本操作 SQL语言分为DDL DML DQL DCL DDL Data
  • HTML5 Canvas 实现 圆环碰撞检测 (方式二)

    JS Canvas 圆环碰撞 圆环外与圆环内与圆环上 方式二 咦 好像 终于有好东西了 结合上一篇 这一篇将更简单 推荐 圆与多边形 圆环与多边形 其实和 点 与多边形碰撞一样 但也有几个不同之处 下面就来看看新实现的 圆环碰撞 列出几个重