/// <summary>
        /// Add extruded point(s) based on two neighbouring line segments.
        /// </summary>
        /// <param name="linePointAndForwardSegment">A line point and its corresponding segment.</param>
        /// <param name="previousLinePointAndForwardSegment">The previous line point and its corresponding segment.</param>
        /// <param name="nextLinePoint">The next line point (since its parameter, uv etc will be needed).</param>
        /// <param name="lineSegmentIndexToAssign">Line segment index to assign the extruded point coming from.</param>
        /// <param name="extrusionAmount">The extrusion amount.</param>
        /// <param name="extrudedLinePoints">The list of all extruded line points.</param>
        /// <param name="findParameter">Delegate for determining altered point parameter.</param>
        private static void AddPointExtrusionFromPreviousNextSegments(LinePointUVAndSegment linePointAndForwardSegment, LinePointUVAndSegment previousLinePointAndForwardSegment, LinePointUV nextLinePoint, int lineSegmentIndexToAssign, float extrusionAmount, List <ExtrudedPointUV> extrudedLinePoints, GetShiftedScaledParameter findParameter)
        {
            double extrusionMagnitudeFractionFirstTangent;
            bool   segmentIntersection = LineSegmentUtil.DoNeighbouringSegmentTangentsFromCommonPointIntersect(previousLinePointAndForwardSegment.SegmentTangent, linePointAndForwardSegment.SegmentTangent, Mathf.Sign(extrusionAmount), out extrusionMagnitudeFractionFirstTangent);

            if (segmentIntersection)
            {
                //Concave section; expect intersection of neighbouring line segments around this point
                var  extrusionDistanceAlongTangents = Mathf.Abs((float)extrusionMagnitudeFractionFirstTangent * extrusionAmount);
                bool intersectionOccursOutOfSegment = extrusionDistanceAlongTangents >= Mathf.Min(previousLinePointAndForwardSegment.SegmentLength, linePointAndForwardSegment.SegmentLength);
                if (intersectionOccursOutOfSegment)
                {
                    AttemptAddNaiveExtrudedPointsWhenTheirExtrudedSegmentsDoNotIntersect(linePointAndForwardSegment, previousLinePointAndForwardSegment, lineSegmentIndexToAssign, extrusionAmount, extrudedLinePoints, findParameter, extrusionDistanceAlongTangents);
                }
                else
                {
                    var intersection = LineSegmentUtil.GetExtrudedSegmentNeighbouringIntersectionPoint(linePointAndForwardSegment.Point, previousLinePointAndForwardSegment.SegmentTangent, extrusionMagnitudeFractionFirstTangent, extrusionAmount);
                    var linePointOfThisIntersection = new LinePointUV(findParameter(linePointAndForwardSegment.Parameter), intersection, linePointAndForwardSegment.UV);
                    extrudedLinePoints.Add(new ExtrudedPointUV(linePointOfThisIntersection, lineSegmentIndexToAssign, lineSegmentIndexToAssign - 1));
                }
            }
            else
            {
                //Convex section, expect a circular fan of points around this point.
                RangeF rangeFromPreviousPoints = new RangeF(findParameter(previousLinePointAndForwardSegment.Parameter), findParameter(linePointAndForwardSegment.Parameter));
                RangeF rangeFromNextPoints     = new RangeF(findParameter(linePointAndForwardSegment.Parameter), findParameter(nextLinePoint.Parameter));
                RangeF parameterRangeToUse     = new RangeF(rangeFromPreviousPoints.FromFractionUnclamped(0.6f), rangeFromNextPoints.FromFractionUnclamped(0.4f));

                var   extrudedFromPreviousNormal     = linePointAndForwardSegment.Point + extrusionAmount * previousLinePointAndForwardSegment.SegmentNormal;
                var   extrudedFromNextNormal         = linePointAndForwardSegment.Point + extrusionAmount * linePointAndForwardSegment.SegmentNormal;
                var   diffBetweenExtrusion           = (extrudedFromNextNormal - extrudedFromPreviousNormal).magnitude;
                var   minNeighbouringSegmentDistance = Mathf.Min(previousLinePointAndForwardSegment.SegmentLength, linePointAndForwardSegment.SegmentLength);
                float absExtrusionAmount             = Mathf.Abs(extrusionAmount);
                var   comparisonDistance             = Mathf.Min(minNeighbouringSegmentDistance, absExtrusionAmount);

                var angleBetweenSegmentNormals = Mathf.Acos(Mathf.Clamp(Vector3.Dot(previousLinePointAndForwardSegment.SegmentNormal, linePointAndForwardSegment.SegmentNormal), -1f, 1f));

                int numPointsFromDistance = Mathf.CeilToInt(diffBetweenExtrusion / comparisonDistance);
                if (numPointsFromDistance <= 2)
                {
                    numPointsFromDistance++;
                }                                                           //NB Want at least the end-points, and if distance is large enough to need 2 naturally, 3 seems to looks better.
                int numPointsFromAngle = Mathf.CeilToInt(angleBetweenSegmentNormals / _convexExtrusionMinimumAngleRadians);
                int numPoints          = Mathf.Max(numPointsFromDistance, numPointsFromAngle);

                for (int i = 0; i < numPoints; i++)
                {
                    float fraction       = numPoints == 1 ? 0.5f : i / (numPoints - 1.0f);
                    var   averageTangent = previousLinePointAndForwardSegment.SegmentTangent.AverageDirectionVector(linePointAndForwardSegment.SegmentTangent, fraction);
                    var   averageNormal  = NormalUtil.NormalFromTangent(averageTangent);
                    var   extrudedVector = linePointAndForwardSegment.Point + averageNormal * extrusionAmount;
                    var   parameter      = parameterRangeToUse.FromFractionUnclamped(fraction);

                    Vector2 newUV = GetUVParameterOfFanPoint(linePointAndForwardSegment, previousLinePointAndForwardSegment, nextLinePoint, absExtrusionAmount, angleBetweenSegmentNormals, fraction);

                    var newLinePointInFan = new LinePointUV(parameter, extrudedVector, newUV);
                    extrudedLinePoints.Add(new ExtrudedPointUV(newLinePointInFan, lineSegmentIndexToAssign, lineSegmentIndexToAssign - 1));
                }
            }
        }
Ejemplo n.º 2
0
        private void btnIntersection_Click(object sender, EventArgs e)
        {
            string line1point1x = line1Point1X.Text;
            string line1point1y = line1Point1Y.Text;
            string line1point2x = line1Point2X.Text;
            string line1point2y = line1Point2Y.Text;

            string line2point1x = line2Point1X.Text;
            string line2point1y = line2Point1Y.Text;
            string line2point2x = line2Point2X.Text;
            string line2point2y = line2Point2Y.Text;

            bool success = areAllPointsValid(line1point1x, line1point1y, line1point2x, line1point2y, line2point1x, line2point1y, line2point2x, line2point2y);

            if (success)
            {
                int l2point1X = int.Parse(line2point1x);
                int l2point1Y = int.Parse(line2point1y);
                int l2point2X = int.Parse(line2point2x);
                int l2point2Y = int.Parse(line2point2y);

                int l1point1X = int.Parse(line1point1x);
                int l1point1Y = int.Parse(line1point1y);
                int l1point2X = int.Parse(line1point2x);
                int l1point2Y = int.Parse(line1point2y);

                LineSegment line1 = new LineSegment(l1point1X, l1point1Y, l1point2X, l1point2Y);
                LineSegment line2 = new LineSegment(l2point1X, l2point1Y, l2point2X, l2point2Y);

                bool intersection = LineSegmentUtil.SegIntersect(line1, line2);

                if (intersection)
                {
                    labelResult.Text = "Lines are intersecting";
                }
                else
                {
                    labelResult.Text = "Lines are not intersecting";
                }
            }
            else
            {
                MessageBox.Show("Enter valid numbers in all boxes");
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns if an intersection with a further segment exists, and has been added to the list of intersections.
        /// </summary>
        /// <param name="extrudedPointList">List of extruded points.</param>
        /// <param name="startExtrudedIndex">Index of extruded points at which to begin looking for intersections later in the list.</param>
        /// <param name="intersections">List of all intersections</param>
        private static bool AddFurtherSegmentIntersection(SegmentwiseExtrudedPointListUV extrudedPointList, int startExtrudedIndex, List <Intersection> intersections)
        {
            intersections.Clear();
            bool ret      = false;
            int  numSteps = 1;
            var  extrudedMaxSegmentDistance = extrudedPointList.MaxSegmentDistance;
            var  extrudedPoints             = extrudedPointList.Points;

            for (int j = startExtrudedIndex + 2; j < extrudedPoints.Count - 1; j += numSteps)
            {
                Vector2 intersectionVector; float firstSegmentFraction, secondSegmentFraction;
                bool    isCurrentIntersection = LineSegmentUtil.GetLineSegmentIntersection(extrudedPoints[startExtrudedIndex].Point, extrudedPoints[startExtrudedIndex + 1].Point, extrudedPoints[j].Point, extrudedPoints[j + 1].Point, out intersectionVector, out firstSegmentFraction, out secondSegmentFraction);
                if (isCurrentIntersection)
                {
                    ret = true;
                    int secondIntersectionIndex = j;
                    intersections.Add(new Intersection(startExtrudedIndex, secondIntersectionIndex, firstSegmentFraction, secondSegmentFraction));
                    //Do not break; there can be more than one intersection further from this startExtrudedIndex
                }
                var distanceDiff = (extrudedPoints[j].Point - extrudedPoints[startExtrudedIndex].Point).magnitude;
                numSteps = Mathf.FloorToInt(Mathf.Max(1f, distanceDiff / extrudedMaxSegmentDistance));
            }
            return(ret);
        }
        /// <summary>
        /// Determines if a chunk between intersection points that contains no other extruded points (ie. the chunk is a single line segment of beginning and ending with two intersection points) is closer than the extrusion distance to the original line.
        /// Calculates based on the original line segmentwise.
        /// </summary>
        /// <param name="intersectionSegmentStart">Intersection point comprising the start of the segment.</param>
        /// <param name="intersectionSegmentEnd">Intersection point comprising the end of the segment.</param>
        /// <param name="originalLinePointList">List of original line points</param>
        /// <param name="extrusionAmount">The extrusion amount.</param>
        private static bool IsIntersectionPointChunkSegmentCloserThanExtrusionDistance_OriginalLineSegmentwise(IntersectionPoint intersectionSegmentStart, IntersectionPoint intersectionSegmentEnd, SegmentwiseLinePointListUV originalLinePointList, float extrusionAmount)
        {
            var linePoints             = originalLinePointList.Points;
            var linePointsMaximumDelta = originalLinePointList.MaxSegmentDistance;

            var numSegments = linePoints.Count - 1;

            var  segmentIndex1      = Math.Max(0, Math.Min(numSegments - 1, intersectionSegmentStart.FirstPointSegmentIndex));
            var  segmentIndex2      = Math.Max(0, Math.Min(numSegments - 1, intersectionSegmentStart.FirstPointSegmentIndex2));
            var  segmentIndex3      = Math.Max(0, Math.Min(numSegments - 1, intersectionSegmentStart.SecondPointSegmentIndex));
            var  segmentIndex4      = Math.Max(0, Math.Min(numSegments - 1, intersectionSegmentStart.SecondPointSegmentIndex2));
            var  segmentIndex5      = Math.Max(0, Math.Min(numSegments - 1, intersectionSegmentEnd.FirstPointSegmentIndex));
            var  segmentIndex6      = Math.Max(0, Math.Min(numSegments - 1, intersectionSegmentEnd.FirstPointSegmentIndex2));
            var  segmentIndex7      = Math.Max(0, Math.Min(numSegments - 1, intersectionSegmentEnd.SecondPointSegmentIndex));
            var  segmentIndex8      = Math.Max(0, Math.Min(numSegments - 1, intersectionSegmentEnd.SecondPointSegmentIndex2));
            var  distanceExtruded1  = LineSegmentUtil.DistanceToSegment(linePoints[segmentIndex1].Point, linePoints[segmentIndex1 + 1].Point, intersectionSegmentStart.Point);
            var  distanceExtruded2  = LineSegmentUtil.DistanceToSegment(linePoints[segmentIndex2].Point, linePoints[segmentIndex2 + 1].Point, intersectionSegmentStart.Point);
            var  distanceExtruded3  = LineSegmentUtil.DistanceToSegment(linePoints[segmentIndex3].Point, linePoints[segmentIndex3 + 1].Point, intersectionSegmentStart.Point);
            var  distanceExtruded4  = LineSegmentUtil.DistanceToSegment(linePoints[segmentIndex4].Point, linePoints[segmentIndex4 + 1].Point, intersectionSegmentStart.Point);
            var  distanceExtruded5  = LineSegmentUtil.DistanceToSegment(linePoints[segmentIndex5].Point, linePoints[segmentIndex5 + 1].Point, intersectionSegmentEnd.Point);
            var  distanceExtruded6  = LineSegmentUtil.DistanceToSegment(linePoints[segmentIndex6].Point, linePoints[segmentIndex6 + 1].Point, intersectionSegmentEnd.Point);
            var  distanceExtruded7  = LineSegmentUtil.DistanceToSegment(linePoints[segmentIndex7].Point, linePoints[segmentIndex7 + 1].Point, intersectionSegmentEnd.Point);
            var  distanceExtruded8  = LineSegmentUtil.DistanceToSegment(linePoints[segmentIndex8].Point, linePoints[segmentIndex8 + 1].Point, intersectionSegmentEnd.Point);
            bool isCloser           = false;
            var  extrusionAmountAbs = Mathf.Abs(extrusionAmount);

            int numSteps = 1;//We'll look every numSteps points to see what's closest, moving more steps when possible.

            for (int i = 0; i < numSegments; i += numSteps)
            {
                var  distanceBetweenSegments   = LineSegmentUtil.DistanceBetweenSegments(intersectionSegmentStart.Point, intersectionSegmentEnd.Point, linePoints[i].Point, linePoints[i + 1].Point);
                bool useDefaultExtrusionAmount = true;
                var  comparisonDistance        = float.PositiveInfinity;
                if (i == segmentIndex1)
                {
                    comparisonDistance = Math.Min(comparisonDistance, distanceExtruded1); useDefaultExtrusionAmount = false;
                }
                if (i == segmentIndex2)
                {
                    comparisonDistance = Math.Min(comparisonDistance, distanceExtruded2); useDefaultExtrusionAmount = false;
                }
                if (i == segmentIndex3)
                {
                    comparisonDistance = Math.Min(comparisonDistance, distanceExtruded3); useDefaultExtrusionAmount = false;
                }
                if (i == segmentIndex4)
                {
                    comparisonDistance = Math.Min(comparisonDistance, distanceExtruded4); useDefaultExtrusionAmount = false;
                }
                if (i == segmentIndex5)
                {
                    comparisonDistance = Math.Min(comparisonDistance, distanceExtruded5); useDefaultExtrusionAmount = false;
                }
                if (i == segmentIndex6)
                {
                    comparisonDistance = Math.Min(comparisonDistance, distanceExtruded6); useDefaultExtrusionAmount = false;
                }
                if (i == segmentIndex7)
                {
                    comparisonDistance = Math.Min(comparisonDistance, distanceExtruded7); useDefaultExtrusionAmount = false;
                }
                if (i == segmentIndex8)
                {
                    comparisonDistance = Math.Min(comparisonDistance, distanceExtruded8); useDefaultExtrusionAmount = false;
                }
                if (useDefaultExtrusionAmount)
                {
                    comparisonDistance = extrusionAmountAbs;
                }

                isCloser = distanceBetweenSegments < comparisonDistance;

                if (!useDefaultExtrusionAmount)
                {
                    if ((i == segmentIndex1 || i == segmentIndex2) && segmentIndex1 == segmentIndex3 && segmentIndex2 == segmentIndex4 ||
                        (i == segmentIndex5 || i == segmentIndex6) && segmentIndex5 == segmentIndex7 && segmentIndex6 == segmentIndex8)
                    {
                        isCloser = false;
                    }
                }

                if (isCloser)
                {
                    break;
                }
                else
                {
                    var distanceDiff = distanceBetweenSegments - extrusionAmountAbs;
                    numSteps = Mathf.FloorToInt(Mathf.Max(1f, distanceDiff / linePointsMaximumDelta));
                }
            }

            return(isCloser);
        }