cocos creator画线绕圈的实现方式,包括绕圈和回退

1. 当圆和直线相交时,直线起点和终点为p1,p2,o为圆心,r为半径,根据以下方式获得切点p3,把p1-p3画一条直线,计算新的直线p3-p2。以此循环即可绕圆

    //p2与圆的切点p3()
	getTangentPoint(p1:cc.Vec2,p2:cc.Vec2,O:cc.Vec2,r:number){
		var px = p2.x
		var py = p2.y
		var cx = O.x
		var cy = O.y
		var p3 = new cc.Vec2()
		//求点到圆心的距离
		var distance = Math.sqrt((px-cx)*(px-cx)+(py-cy)*(py-cy))
		//点到切点的距离
		var length = Math.sqrt(distance*distance-r*r)
		if (distance <= r){
			cc.log("点在圆内,无切点")
			return null
		}
		//点到圆心的单位向量
		var ux = (cx-px)/distance
		var uy = (cy-py)/distance
		//计算切线与圆心连线的夹角
		var angle = Math.asin(r/distance)
		//向正反两个方向旋转单位向量
		var q1x = ux * Math.cos(angle)  -  uy * Math.sin(angle)
		var q1y = ux * Math.sin(angle)  +  uy * Math.cos(angle)
		var q2x = ux * Math.cos(-angle) -  uy * Math.sin(-angle)
		var q2y = ux * Math.sin(-angle) +  uy * Math.cos(-angle)
		//得到新座标y
		q1x = q1x * length + px
		q1y = q1y * length + py
		q2x = q2x * length + px
		q2y = q2y * length + py
		//哪个离p1近返回哪个?
		var p1x = p1.x
		var p1y = p1.y
		var distance1 = Math.sqrt((p1x-q1x)*(p1x-q1x)+(p1y-q1y)*(p1y-q1y))
		var distance2 = Math.sqrt((p1x-q2x)*(p1x-q2x)+(p1y-q2y)*(p1y-q2y))
		if(distance1 < distance2){
			p3.x = q1x
			p3.y = q1y
		}else{
			p3.x = q2x
			p3.y = q2y
		}
		return p3
	}

2. 解开直线绕圆的思路:                

每当有切点的时候,记下当前起点p1',圆心o。

判断直线的两个点p1p2,以及圆心组成的∠p2p1o,判断角度是否>90,当>90度时,可以回退,即清除p1p2直线,重新赋值p1 = p1',并且画线。

//两直线夹角
	jiajiao(p, p1, p2) {
		var x1 = p1.x;
		var y1 = p1.y;
		var x2 = p2.x;
		var y2 = p2.y;
		var x3 = p.x;
		var y3 = p.y;
		const getAngle = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => {
			const dot = x1 * x2 + y1 * y2
			const det = x1 * y2 - y1 * x2
			const angle = Math.atan2(det, dot) / Math.PI * 180
			return Math.abs(angle)
		}
		const angle = getAngle({
			x: x1 - x3,
			y: y1 - y3,
		}, {
			x: x2 - x3,
			y: y2 - y3,
		});
		return angle
	}
if (window.circleDotArr && window.circleDotArr.length > 0) {
				//p1起始点,圆心o,p2移动的点,当角度>90度就是撤回折点
				var angle = this.jiajiao(p1, cc.v2(window.circleDotArr[window.circleDotArr.length - 1].x, window.circleDotArr[window.circleDotArr.length - 1].y), p2)
				var flag = angle > 90
				while (flag) {
					p1 = window.p1Arr[window.p1Arr.length - 1]
					this.prePoint = p1
					window.p1Arr.pop()
					window.circleDotArr.pop()
					window.graphicsNodeArr[window.graphicsNodeArr.length - 1].destroy()
					window.graphicsNodeArr.pop()

					if (window.circleDotArr.length > 0) {
						var angle = this.jiajiao(p1, cc.v2(window.circleDotArr[window.circleDotArr.length - 1].x, window.circleDotArr[window.circleDotArr.length - 1].y), p2)
						var flag = angle > 90
					} else {
						flag = null
					}
				}
			}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值