示例#1
0
        private static bool checkRange(ArcLoftPath a, Vector3 bDir, Vector3 center, float bDirLen, Vector3 startRight, float distance, ref float bestOffsetA, ref float bestOffsetB)
        {
            float offsetA;
            float offsetB;

            if (distance > 0 && distance < 1)
            {
                var farPoint = startRight + bDir * distance + center;
                if (a.GetOffsetToPoint(farPoint, out offsetA))
                {
                    Debug.DrawLine(farPoint, farPoint + Vector3.left * 5, Color.green);
                    Debug.DrawLine(farPoint, farPoint + Vector3.forward * 5, Color.green);
                    offsetB = distance * bDirLen;

                    if (offsetA < bestOffsetA)
                    {
                        bestOffsetA = offsetA;
                    }
                    if (offsetB < bestOffsetB)
                    {
                        bestOffsetB = offsetB;
                    }
                    return(true);
                }
            }
            return(false);
        }
示例#2
0
        private static void get2DEllipse(ArcLoftPath a, out Vector3 center, out Vector3 axisX, out Vector3 axisY, out float radiusX, out float radiusY)
        {
            var offset = Vector3.Dot(a.StartPoint, a.Normal) * a.Normal;

            center = a.Center + offset;
            var direction = (a.StartPoint + a.Center - center);

            var radius = direction.magnitude;

            axisX   = a.Normal;
            axisX.y = 0;
            axisX.Normalize();

            axisY   = new Vector3(-axisX.z, 0, axisX.x);
            radiusX = Vector3.Cross(axisX, a.Normal).magnitude *radius;
            radiusY = Vector3.Cross(axisY, a.Normal).magnitude *radius;
            //Debug.DrawLine(center, center + axisX * radiusX, Color.red);
            //Debug.DrawLine(center, center + axisY * radiusY, Color.green);

            //Debug.DrawLine(a.StartPoint + a.Center, a.Center, Color.red);

            //DebugUtils.DrawCircle(center, radius, a.Normal, Color.blue);

            //Debug.DrawLine(center, a.Center, Color.yellow);
        }
示例#3
0
        private static bool intersectsArcArc(ArcLoftPath a, float widthA, ArcLoftPath b, float widthB, IntersectionMode mode, out float offsetA, out float offsetB)
        {
            Vector3 aCenter, aAxisX, aAxisY;
            float   aRadiusX, aRadiusY;

            if (a.Normal.y > 0.99999)
            {
                aCenter   = a.Center;
                aCenter.y = a.StartPoint.y;
                aAxisX    = Vector3.right;
                aAxisY    = Vector3.forward;
                var ray = a.StartPoint;
                ray.y    = 0;
                aRadiusX = aRadiusY = ray.magnitude;
            }
            else
            {
                get2DEllipse(a, out aCenter, out aAxisX, out aAxisY, out aRadiusX, out aRadiusY);
            }

            Vector3 bCenter, bAxisX, bAxisY;
            float   bRadiusX, bRadiusY;

            if (b.Normal.y > 0.99999)
            {
                bCenter   = b.Center;
                bCenter.y = b.StartPoint.y;
                bAxisX    = Vector3.right;
                bAxisY    = Vector3.forward;

                var ray = b.StartPoint;
                ray.y    = 0;
                bRadiusX = bRadiusY = ray.magnitude;
                Debug.DrawLine(bCenter, b.StartPoint, Color.green);
            }
            else
            {
                get2DEllipse(b, out bCenter, out bAxisX, out bAxisY, out bRadiusX, out bRadiusY);
            }


            var aAngle = -Mathf.Atan2(aAxisX.z, aAxisX.x);
            var bAngle = -Mathf.Atan2(bAxisX.z, bAxisX.x);

            var displayOffset = Vector3.right * 50;



            offsetB = offsetA = float.NaN;
            return(false);
        }
示例#4
0
        private static bool intersectEllipseCenter(ArcLoftPath a, out float offsetA, out float offsetB, Vector3 center, float radiusX, float radiusY, float bDirLen, Vector3 bStart, Vector3 bDir)
        {
            float nearDistance;
            float farDistance;

            if (VectorMath2D.IntersectsLineEllipse(t2d(bStart), t2d(bDir), Vector3.zero, radiusX, radiusY, out nearDistance, out farDistance))
            {
                float bestOffsetA = float.PositiveInfinity, bestOffsetB = float.PositiveInfinity;
                if (checkRange(a, bDir, center, bDirLen, bStart, nearDistance, ref bestOffsetA, ref bestOffsetB))
                {
                    offsetA = bestOffsetA;
                    offsetB = bestOffsetB;
                    return(true);
                }
                if (checkRange(a, bDir, center, bDirLen, bStart, farDistance, ref bestOffsetA, ref bestOffsetB))
                {
                    offsetA = bestOffsetA;
                    offsetB = bestOffsetB;
                    return(true);
                }
            }
            offsetA = offsetB = float.NaN;
            return(false);
        }
示例#5
0
        private ILoftPath getArc(Vector3 point, Vector3 tangent, Vector3 pointH, bool reverse)
        {
#if DEBUG
            if (float.IsNaN(point.x))
            {
                throw new InvalidOperationException("point.x is not a number");
            }
            if (float.IsNaN(point.y))
            {
                throw new InvalidOperationException("point.y is not a number");
            }
            if (float.IsNaN(point.z))
            {
                throw new InvalidOperationException("point.z is not a number");
            }
            if (float.IsNaN(tangent.x))
            {
                throw new InvalidOperationException("tangent.x is not a number");
            }
            if (float.IsNaN(tangent.y))
            {
                throw new InvalidOperationException("tangent.y is not a number");
            }
            if (float.IsNaN(tangent.z))
            {
                throw new InvalidOperationException("tangent.z is not a number");
            }
            if (float.IsNaN(pointH.x))
            {
                throw new InvalidOperationException("pointH.x is not a number");
            }
            if (float.IsNaN(pointH.y))
            {
                throw new InvalidOperationException("pointH.y is not a number");
            }
            if (float.IsNaN(pointH.z))
            {
                throw new InvalidOperationException("pointH.z is not a number");
            }
#endif

            //Debug.DrawLine(point, point + tangent * 10);
            var lHP = pointH - point;

            var pHSC = (pointH + point) / 2;

            var pHSn = lHP.normalized;

            var pHSd = Vector3.Dot(pHSn, pHSC);

            var pSn = tangent;
            var pSd = Vector3.Dot(pSn, point);

            //DebugUtils.DrawPlane(pHSC, pHSn, 0.05f, Color.cyan);
            //DebugUtils.DrawPlane(point, pSn, 0.05f, Color.cyan);

            Ray rS;
            if (intersect(pSn, pSd, pHSn, pHSd, out rS))
            {
                var center = rS.GetPoint(Vector3.Dot(rS.direction, point - rS.origin));
                //Debug.DrawLine(rS.origin, center, Color.blue);
                //DebugUtils.DrawCircle(center, (center - point).magnitude, rS.direction, Color.cyan);


                //Debug.DrawLine(point, centerStart, Color.magenta);
                //Debug.DrawLine(pointH, centerStart, Color.magenta);


                // TODO: it isn't always shortest angle

                var side = Vector3.Cross(tangent, Vector3.up);
                var dot  = Vector3.Dot(side, point - center);

                //if (Mathf.Abs(dot) < 0.0001f)
                //{
                //    side = Vector3.Cross(tangent, Vector3.right);
                //    dot = Vector3.Dot(side, point - center);
                //}

                var ccw = dot > 0;
                return(reverse ? ArcLoftPath.Create(center, point, pointH, ccw) : ArcLoftPath.Create(center, pointH, point, ccw));
            }
            return(reverse ? new LinearPath(point, pointH) : new LinearPath(pointH, point));
        }
示例#6
0
        private static bool intersectsEllipseEdge(ArcLoftPath a, Vector3 bStart, Vector3 bDir, Vector3 bTan, Vector3 center, float bDirLen, float widthB, float radiusX, float radiusY, out float offsetA, out float offsetB)
        {
            var startLeft  = bStart - bTan;
            var startRight = bStart + bTan;

            float outerRadiusX = radiusX + widthB;
            float outerRadiusY = radiusY + widthB;
            float innerRadiusX = radiusX - widthB;
            float innerRadiusY = radiusY - widthB;

            float nearDistanceInnerLeft, farDistanceInnerLeft;
            float nearDistanceInnerRight, farDistanceInnerRight;
            float nearDistanceOuterLeft, farDistanceOuterLeft;
            float nearDistanceOuterRight, farDistanceOuterRight;



            bool intersectsInnerLeft  = VectorMath2D.IntersectsLineEllipse(t2d(startLeft), t2d(bDir), Vector3.zero, innerRadiusX, innerRadiusY, out nearDistanceInnerLeft, out farDistanceInnerLeft);
            bool intersectsInnerRight = VectorMath2D.IntersectsLineEllipse(t2d(startRight), t2d(bDir), Vector3.zero, innerRadiusX, innerRadiusY, out nearDistanceInnerRight, out farDistanceInnerRight);

            bool intersectsOuterLeft  = VectorMath2D.IntersectsLineEllipse(t2d(startLeft), t2d(bDir), Vector3.zero, outerRadiusX, outerRadiusY, out nearDistanceOuterLeft, out farDistanceOuterLeft);
            bool intersectsOuterRight = VectorMath2D.IntersectsLineEllipse(t2d(startRight), t2d(bDir), Vector3.zero, outerRadiusX, outerRadiusY, out nearDistanceOuterRight, out farDistanceOuterRight);


            //if (intersectsOuterLeft)
            //    Debug.DrawLine(startLeft + bDir * nearDistanceOuterLeft, startLeft + bDir * farDistanceOuterLeft, Color.green);
            //if (intersectsOuterRight)
            //    Debug.DrawLine(startRight + bDir * nearDistanceOuterRight, startRight + bDir * farDistanceOuterRight, Color.green);

            //if (intersectsInnerLeft)
            //    Debug.DrawLine(startLeft + bDir * nearDistanceInnerLeft, startLeft + bDir * farDistanceInnerLeft, Color.yellow);
            //if (intersectsInnerRight)
            //    Debug.DrawLine(startRight + bDir * nearDistanceInnerRight, startRight + bDir * farDistanceInnerRight, Color.yellow);


            float bestOffsetA = float.PositiveInfinity, bestOffsetB = float.PositiveInfinity;

            bool any = false;

            if (intersectsOuterLeft)
            {
                any |= checkRange(a, bDir, center, bDirLen, startLeft, nearDistanceOuterLeft, ref bestOffsetA, ref bestOffsetB);
                //any |= checkRange(a, bDir, center, bDirLen, startLeft, farDistanceOuterLeft, ref bestOffsetA, ref bestOffsetB);
            }
            if (intersectsOuterRight)
            {
                any |= checkRange(a, bDir, center, bDirLen, startRight, nearDistanceOuterRight, ref bestOffsetA, ref bestOffsetB);
                //any |= checkRange(a, bDir, center, bDirLen, startRight, farDistanceOuterRight, ref bestOffsetA, ref bestOffsetB);
            }
            if (intersectsInnerLeft)
            {
                //any |= checkRange(a, bDir, center, bDirLen, startLeft, nearDistanceInnerLeft, ref bestOffsetA, ref bestOffsetB);
                any |= checkRange(a, bDir, center, bDirLen, startLeft, farDistanceInnerLeft, ref bestOffsetA, ref bestOffsetB);
            }
            if (intersectsInnerRight)
            {
                //any |= checkRange(a, bDir, center, bDirLen, startRight, nearDistanceInnerRight, ref bestOffsetA, ref bestOffsetB);
                any |= checkRange(a, bDir, center, bDirLen, startRight, farDistanceInnerRight, ref bestOffsetA, ref bestOffsetB);
            }

            if (any)
            {
                offsetA = bestOffsetA;
                offsetB = bestOffsetB;
                return(true);
            }


            offsetA = offsetB = float.NaN;
            return(false);
        }
示例#7
0
        private static bool intersectsArcLinear(ArcLoftPath a, float widthA, LinearPath b, float widthB, IntersectionMode mode, out float offsetA, out float offsetB)
        {
            widthA /= 2;
            widthB /= 2;

            if (a.Normal.y > 0.99999f)
            {
                // perfect circle

                var bDirLen = b.Length;
                var bStart  = b.Start - a.Center;
                var bDir    = b.Dir * bDirLen;
                var bTan    = b.Tangent * widthB;

                var center = a.Center;

                center.y = a.StartPoint.y;

                var radius = a.Radius;


                if (mode == IntersectionMode.Edge)
                {
                    if (intersectsEllipseEdge(a, bStart, bDir, bTan, center, bDirLen, widthB, radius, radius, out offsetA, out offsetB))
                    {
                        return(true);
                    }
                }
                else
                {
                    if (intersectEllipseCenter(a, out offsetA, out offsetB, center, radius, radius, bDirLen, bStart, bDir))
                    {
                        return(true);
                    }
                }
            }
            else
            {
                Vector3 center, axisX, axisY;
                float   radiusX, radiusY;
                get2DEllipse(a, out center, out axisX, out axisY, out radiusX, out radiusY);

                var bDirLen = get2DLength(b.Dir.y, b.Length);
                var bStart  = project(b.Start - center, axisX, axisY);
                var bDir    = project(b.Dir * bDirLen, axisX, axisY);
                var bTan    = project(b.Tangent * widthB, axisX, axisY);

                var aStart = project(a.StartPoint, axisX, axisY);

                //DebugUtils.DrawEllipse(Vector3.zero, radiusX + widthA, radiusY + widthA, Color.cyan);
                //DebugUtils.DrawEllipse(Vector3.zero, radiusX, radiusY, Color.yellow);
                //DebugUtils.DrawEllipse(Vector3.zero, radiusX - widthA, radiusY - widthA, Color.magenta);


                if (mode == IntersectionMode.Edge)
                {
                    if (intersectsEllipseEdge(a, bStart, bDir, bTan, center, bDirLen, widthB, radiusX, radiusY, out offsetA, out offsetB))
                    {
                        return(true);
                    }
                }
                else
                {
                    if (intersectEllipseCenter(a, out offsetA, out offsetB, center, radiusX, radiusY, bDirLen, bStart, bDir))
                    {
                        return(true);
                    }
                }
            }

            offsetB = offsetA = float.NaN;
            return(false);
        }