/// <summary> /// 求外部点到圆的切线 /// </summary> /// <param name="outPoint">在圆上/圆内不计算切线</param> /// <param name="leftTangent">逆时针切线</param> /// <param name="rightTangent">顺时针切线</param> /// <returns></returns> public bool GetTangent(Double2 outPoint, ref Double2 leftTangent, ref Double2 rightTangent) { Double2 diff = this.circleCenter - outPoint; double sqrDiff = diff.sqrMagnitude; double sqrRadius = this.radius * this.radius; // 先求切线的长度sqr double sqrtLen = sqrDiff - sqrRadius; if (sqrtLen <= 0) { return(false); } else { // 再求斜边的高度平方 double sqrHeight = sqrtLen * sqrRadius / sqrDiff; // 求垂线。 Double2 aix = -Double2.Perpendicular(diff); // 再求斜边的垂足。 double value = (sqrtLen - sqrHeight) / sqrDiff; Double2 aixPos = System.Math.Sqrt((float)value) * diff + outPoint; // 再求2个切点。 double height = System.Math.Sqrt((float)sqrHeight); leftTangent = aixPos - aix.normalized * height - outPoint; rightTangent = aixPos + aix.normalized * height - outPoint; return(true); } }
/// <summary> /// 创建外接圆 /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="p3"></param> /// <returns></returns> public static Circle2D CreateCircumCircle(Double2 p1, Double2 p2, Double2 p3) { // 排除三点共线 Double2 diff1 = p2 - p1; Double2 diff2 = p3 - p1; if (diff1 == Double2.zero || diff2 == Double2.zero) { return(null); } double value = Double2.Cross(diff1, diff2); if (System.Math.Abs(value) < MathUtil.kEpsilon) { return(null); } // 2垂直平分线就是圆心。 Double2 mid1 = p1 + diff1 * 0.5f; Double2 mid2 = p1 + diff2 * 0.5f; Line2D line1 = new Line2D(mid1, Double2.Perpendicular(diff1)); Line2D line2 = new Line2D(mid2, Double2.Perpendicular(diff2)); Double2 center = Double2.zero; if (line1.GetIntersectPoint(line2, ref center) == true) { double radius = (center - p1).magnitude; return(new Circle2D(center, radius)); } else { return(null); } }
/// <summary> /// DrawGizmos /// </summary> public void DrawGizmos() { startPoint.DrawGizmos(); Double2 v1 = Double2.Perpendicular(normalizedDir).normalized * 0.2f; Double2 diff = 9.8f * normalizedDir; UnityEngine.Gizmos.DrawLine((startPoint + diff + v1).V3, EndPoint); UnityEngine.Gizmos.DrawLine((startPoint + diff - v1).V3, EndPoint); }
/// <summary> /// 初始化数据 /// </summary> /// <param name="points"></param> private void Init(Double2[] points) { if (points == null || points.Length < 3) { return; } this.pointArr = new Double2[points.Length]; this.normalAttr = new Double2[points.Length]; this.distancArr = new double[points.Length + 1]; Double2 min = points[0]; Double2 max = points[0]; int i; for (i = 0; i < points.Length; i++) { this.pointArr[i] = points[i]; if (i > 0) { min = Double2.Min(min, points[i]); max = Double2.Max(max, points[i]); totalDistance += MathUtil.GetNearDistance(points[i - 1], points[i]); this.distancArr[i] = totalDistance; } else { min = points[i]; max = points[i]; this.distancArr[i] = 0; totalDistance = 0; } // Double2 dir; if (i < points.Length - 1) { dir = (points[i + 1] - points[i]).normalized; } else { dir = (points[0] - points[i]).normalized; } this.normalAttr[i] = Double2.Perpendicular(dir); } totalDistance += MathUtil.GetNearDistance(points[points.Length - 1], points[0]); this.distancArr[i] = totalDistance; this.SetAABB(min, max); }