public void TryClipLiangBarsky_SegmentsOutsideCorners_Q1( RectDecimal rect, SegmentDecimal seg1) { var actual = GridUtils.TryClipLiangBarsky( rect, seg1, out var clippedSegment); Assert.That(actual, Is.False); }
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)); }
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); }