mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-04-05 20:55:01 +08:00
add IntersectsWith(PdfRectangle, PdfLine) and Intersect(PdfRectangle, PdfLine)
This commit is contained in:
parent
d29cc52973
commit
46b183f564
@ -13,7 +13,7 @@
|
||||
/// </summary>
|
||||
internal static class ClippingExtensions
|
||||
{
|
||||
private const double Factor = 10_000.0;
|
||||
public const double Factor = 10_000.0;
|
||||
|
||||
/// <summary>
|
||||
/// Number of lines to use when transforming bezier curve to polyline.
|
||||
@ -220,5 +220,10 @@
|
||||
{
|
||||
return new ClipperIntPoint(point.X * Factor, point.Y * Factor);
|
||||
}
|
||||
|
||||
internal static List<ClipperIntPoint> ToClipperIntPoint(this PdfLine line)
|
||||
{
|
||||
return new List<ClipperIntPoint>() { line.Point1.ToClipperIntPoint(), line.Point2.ToClipperIntPoint() };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -475,6 +475,65 @@
|
||||
var points = new[] { rectangle.BottomLeft, rectangle.BottomRight, rectangle.TopLeft, rectangle.TopRight };
|
||||
return new PdfRectangle(points.Min(p => p.X), points.Min(p => p.Y), points.Max(p => p.X), points.Max(p => p.Y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the rectangle and the line intersect.
|
||||
/// </summary>
|
||||
/// <param name="rectangle"></param>
|
||||
/// <param name="line"></param>
|
||||
public static bool IntersectsWith(this PdfRectangle rectangle, PdfLine line)
|
||||
{
|
||||
return IntersectsWith(rectangle, line.Point1, line.Point2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="PdfLine"/> that is the intersection of the rectangle and the line.
|
||||
/// </summary>
|
||||
/// <param name="rectangle"></param>
|
||||
/// <param name="line"></param>
|
||||
public static PdfLine? Intersect(this PdfRectangle rectangle, PdfLine line)
|
||||
{
|
||||
var i = Intersect(rectangle, line.Point1, line.Point2);
|
||||
if (i != null)
|
||||
{
|
||||
return new PdfLine(i[0], i[1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="PdfLine"/>s that are the intersection of the rectangle and the lines.
|
||||
/// </summary>
|
||||
/// <param name="rectangle"></param>
|
||||
/// <param name="lines"></param>
|
||||
/// <returns></returns>
|
||||
public static List<PdfLine> Intersect(this PdfRectangle rectangle, List<PdfLine> lines)
|
||||
{
|
||||
var clipper = new Clipper();
|
||||
clipper.AddPath(rectangle.ToClipperPolygon().ToList(), ClipperPolyType.Clip, true);
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
clipper.AddPath(line.ToClipperIntPoint(), ClipperPolyType.Subject, false);
|
||||
}
|
||||
|
||||
var solutions = new ClipperPolyTree();
|
||||
if (clipper.Execute(ClipperClipType.Intersection, solutions))
|
||||
{
|
||||
List<PdfLine> rv = new List<PdfLine>();
|
||||
foreach (var solution in solutions.Children)
|
||||
{
|
||||
rv.Add(new PdfLine(new PdfPoint(solution.Contour[0].X / ClippingExtensions.Factor, solution.Contour[0].Y / ClippingExtensions.Factor),
|
||||
new PdfPoint(solution.Contour[1].X / ClippingExtensions.Factor, solution.Contour[1].Y / ClippingExtensions.Factor)));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<PdfLine>();
|
||||
}
|
||||
// clipper.clear() ??
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PdfLine
|
||||
@ -533,6 +592,26 @@
|
||||
{
|
||||
return ParallelTo(line.Point1, line.Point2, other.From, other.To);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="PdfLine"/> that is the intersection of the rectangle and the line.
|
||||
/// </summary>
|
||||
/// <param name="rectangle"></param>
|
||||
/// <param name="line"></param>
|
||||
public static PdfLine? Intersect(this PdfLine line, PdfRectangle rectangle)
|
||||
{
|
||||
return rectangle.Intersect(line);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the rectangle and the line intersect.
|
||||
/// </summary>
|
||||
/// <param name="rectangle"></param>
|
||||
/// <param name="line"></param>
|
||||
public static bool IntersectsWith(this PdfLine line, PdfRectangle rectangle)
|
||||
{
|
||||
return rectangle.IntersectsWith(line);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Path Line
|
||||
@ -657,6 +736,65 @@
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The intersection of the line formed by <paramref name="pl1"/> and <paramref name="pl2"/>
|
||||
/// intersects the rectangle.
|
||||
/// </summary>
|
||||
private static PdfPoint[] Intersect(PdfRectangle rectangle, PdfPoint pl1, PdfPoint pl2)
|
||||
{
|
||||
var clipper = new Clipper();
|
||||
clipper.AddPath(rectangle.ToClipperPolygon().ToList(), ClipperPolyType.Clip, true);
|
||||
|
||||
clipper.AddPath(new List<ClipperIntPoint>() { pl1.ToClipperIntPoint(), pl2.ToClipperIntPoint() }, ClipperPolyType.Subject, false);
|
||||
|
||||
var solutions = new ClipperPolyTree();
|
||||
if (clipper.Execute(ClipperClipType.Intersection, solutions))
|
||||
{
|
||||
if (solutions.Children.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (solutions.Children.Count == 1)
|
||||
{
|
||||
var solution = solutions.Children[0];
|
||||
|
||||
return new[]
|
||||
{
|
||||
new PdfPoint(solution.Contour[0].X / ClippingExtensions.Factor, solution.Contour[0].Y / ClippingExtensions.Factor),
|
||||
new PdfPoint(solution.Contour[1].X / ClippingExtensions.Factor, solution.Contour[1].Y / ClippingExtensions.Factor)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("GeometryExtensions.Intersect(PdfRectangle, PdfPoint, PdfPoint): more than one solution found.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// clipper.clear() ??
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the line formed by <paramref name="pl1"/> and <paramref name="pl2"/>
|
||||
/// intersects the rectangle.
|
||||
/// </summary>
|
||||
public static bool IntersectsWith(PdfRectangle rectangle, PdfPoint pl1, PdfPoint pl2)
|
||||
{
|
||||
var clipper = new Clipper();
|
||||
clipper.AddPath(rectangle.ToClipperPolygon().ToList(), ClipperPolyType.Clip, true);
|
||||
|
||||
clipper.AddPath(new List<ClipperIntPoint>() { pl1.ToClipperIntPoint(), pl2.ToClipperIntPoint() }, ClipperPolyType.Subject, false);
|
||||
|
||||
var solutions = new ClipperPolyTree();
|
||||
if (clipper.Execute(ClipperClipType.Intersection, solutions))
|
||||
{
|
||||
return solutions.Children.Count > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool ParallelTo(PdfPoint p11, PdfPoint p12, PdfPoint p21, PdfPoint p22)
|
||||
{
|
||||
return Math.Abs((p12.Y - p11.Y) * (p22.X - p21.X) - (p22.Y - p21.Y) * (p12.X - p11.X)) < epsilon;
|
||||
|
Loading…
Reference in New Issue
Block a user