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 } } }
复制