127 lines
3.2 KiB
C#
127 lines
3.2 KiB
C#
|
#if ACAD24
|
|||
|
using Autodesk.AutoCAD.EditorInput;
|
|||
|
using Autodesk.AutoCAD.Geometry;
|
|||
|
using Autodesk.AutoCAD.DatabaseServices;
|
|||
|
using Autodesk.AutoCAD.Colors;
|
|||
|
using AcAp = Autodesk.AutoCAD.ApplicationServices;
|
|||
|
#elif BCAD
|
|||
|
using Bricscad.EditorInput;
|
|||
|
using Teigha.Geometry;
|
|||
|
using Teigha.DatabaseServices;
|
|||
|
using Teigha.Colors;
|
|||
|
#endif
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
|
|||
|
namespace Boprs
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// End point of an edge used while sweep line is processing a boolean operation.
|
|||
|
/// </summary>
|
|||
|
internal class SweepVertex : IComparable
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// String representation of the vertex.
|
|||
|
/// </summary>
|
|||
|
public override string ToString()
|
|||
|
{
|
|||
|
return ($"({Point.X}, {Point.Y})");
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Comparison of vertices.
|
|||
|
/// </summary>
|
|||
|
/// <param name="obj">Vertex to compare.</param>
|
|||
|
/// <returns>
|
|||
|
/// <c>-1</c> if this is to the left of obj, <c>1</c> if this is to the right of obj, <c>0</c> if same.
|
|||
|
/// </returns>
|
|||
|
public int CompareTo(object obj)
|
|||
|
{
|
|||
|
if (obj is SweepVertex other)
|
|||
|
{
|
|||
|
// Different x coordinates
|
|||
|
if (Point.X > other.Point.X)
|
|||
|
{
|
|||
|
return 1;
|
|||
|
}
|
|||
|
// Different x coordinates
|
|||
|
if (Point.X < other.Point.X)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
// Different points, but same x-coordinate. The event with lower y-coordinate is processed first.
|
|||
|
if (Point.Y != other.Point.Y)
|
|||
|
{
|
|||
|
return Point.Y > other.Point.Y ? 1 : -1;
|
|||
|
}
|
|||
|
// Same point, but one is a left endpoint and the other a right endpoint.
|
|||
|
// The right endpoint is processed first.
|
|||
|
if (IsLeft() != other.IsLeft())
|
|||
|
{
|
|||
|
return IsLeft() ? 1 : -1;
|
|||
|
}
|
|||
|
// One of our edges is vertical, the non-vertical one gets processed first.
|
|||
|
if (Edge.IsVertical() != other.Edge.IsVertical())
|
|||
|
{
|
|||
|
return Edge.IsVertical() ? 1 : -1;
|
|||
|
}
|
|||
|
// Left vertex common, the downward leading edge gets processed first.
|
|||
|
if (IsLeft())
|
|||
|
{
|
|||
|
if (Utils.SignedArea(Point, Edge.RightVertex.Point, other.Edge.RightVertex.Point) < 0)
|
|||
|
{
|
|||
|
return 1;
|
|||
|
}
|
|||
|
if (Utils.SignedArea(Point, Edge.RightVertex.Point, other.Edge.RightVertex.Point) > 0)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
}
|
|||
|
// Right vertex is common, the upward leading edge gets processed first.
|
|||
|
if (!IsLeft())
|
|||
|
{
|
|||
|
if (Utils.SignedArea(Point, Edge.RightVertex.Point, other.Edge.RightVertex.Point) < 0)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
if (Utils.SignedArea(Point, Edge.RightVertex.Point, other.Edge.RightVertex.Point) > 0)
|
|||
|
{
|
|||
|
return 1;
|
|||
|
}
|
|||
|
}
|
|||
|
// Colinear edges
|
|||
|
return 0;
|
|||
|
}
|
|||
|
throw new ArgumentException("obj is not SweepEvent.");
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Position of the vertex, use
|
|||
|
/// </summary>
|
|||
|
internal Point2d Point { get; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Edge this vertex belongs to.
|
|||
|
/// </summary>
|
|||
|
internal SweepEdge Edge { get; set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Is this the left vertex of my parent edge?
|
|||
|
/// </summary>
|
|||
|
/// <returns><c>true</c> if this is the left(or bottom) edge of my parent, <c>false</c> if not.</returns>
|
|||
|
internal bool IsLeft()
|
|||
|
{
|
|||
|
return this == Edge.LeftVertex;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Constructor.
|
|||
|
/// </summary>
|
|||
|
/// <param name="point">Position of the vertex.</param>
|
|||
|
internal SweepVertex (Point2d point)
|
|||
|
{
|
|||
|
Point = point;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|