示例#1
0
        public void TryClipLiangBarsky_SegmentsOutsideCorners_Q1(
            RectDecimal rect, SegmentDecimal seg1)
        {
            var actual = GridUtils.TryClipLiangBarsky(
                rect,
                seg1,
                out var clippedSegment);

            Assert.That(actual, Is.False);
        }
示例#2
0
        public void TryClipLiangBarsky_CollinearSegmentsInsideCorrect_Q1(
            RectDecimal rect, SegmentDecimal seg1, SegmentDecimal expected, decimal eps)
        {
            var actual = GridUtils.TryClipLiangBarsky(
                rect,
                seg1,
                out var clippedSegment);

            Assert.That(actual, Is.True);
            Assert.That(clippedSegment.X1, Is.EqualTo(expected.X1).Within(eps));
            Assert.That(clippedSegment.Y1, Is.EqualTo(expected.Y1).Within(eps));
            Assert.That(clippedSegment.X2, Is.EqualTo(expected.X2).Within(eps));
            Assert.That(clippedSegment.Y2, Is.EqualTo(expected.Y2).Within(eps));
        }
示例#3
0
        public static bool TryClipLiangBarsky(RectDecimal rect, SegmentDecimal segment, out SegmentDecimal result)
        {
            result = new SegmentDecimal();

            // defining variables
            var p1 = -(segment.X2 - segment.X1);
            var p2 = -p1;
            var p3 = -(segment.Y2 - segment.Y1);
            var p4 = -p3;

            var q1 = segment.X1 - rect.X;
            var q2 = rect.XMax - segment.X1;
            var q3 = segment.Y1 - rect.Y;
            var q4 = rect.YMax - segment.Y1;

            var posArr = new decimal[5];
            var negArr = new decimal[5];
            var posInd = 1;
            var negInd = 1;

            posArr[0] = 1;
            negArr[0] = 0;

            if ((p1 == 0 && q1 < 0) || (p2 == 0 && q2 < 0) || (p3 == 0 && q3 < 0) || (p4 == 0 && q4 < 0))
            {
                // Line is parallel to clipping window!
                return(false);
            }

            if (p1 != 0)
            {
                var r1 = q1 / p1;
                var r2 = q2 / p2;
                if (p1 < 0)
                {
                    negArr[negInd++] = r1; // for negative p1, add it to negative array
                    posArr[posInd++] = r2; // and add p2 to positive array
                }
                else
                {
                    negArr[negInd++] = r2;
                    posArr[posInd++] = r1;
                }
            }

            if (p3 != 0)
            {
                var r3 = q3 / p3;
                var r4 = q4 / p4;
                if (p3 < 0)
                {
                    negArr[negInd++] = r3;
                    posArr[posInd++] = r4;
                }
                else
                {
                    negArr[negInd++] = r4;
                    posArr[posInd++] = r3;
                }
            }

            var rn1 = MaxI(negArr, negInd);
            var rn2 = MinI(posArr, posInd);

            if (rn1 > rn2)
            {
                // reject
                // Line is outside the clipping window!
                return(false);
            }

            var xn1 = segment.X1 + p2 * rn1;
            var yn1 = segment.Y1 + p4 * rn1;

            var xn2 = segment.X1 + p2 * rn2;
            var yn2 = segment.Y1 + p4 * rn2;

            result = new SegmentDecimal(
                new Vector2Decimal(xn1, yn1),
                new Vector2Decimal(xn2, yn2)
                );
            return(true);
        }