Boprs/Contour.cs

124 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;
using AcAp = Bricscad.ApplicationServices;
#endif
using System;
using System.Collections.Generic;
namespace Boprs
{
/// <summary>
/// Simple closed polygon.
/// </summary>
public class Contour : ICloneable
{
public object Clone()
{
return new Contour(new List<Point2d>(Vertices));
}
/// <summary>
/// Vertices of the contour.
/// </summary>
private List<Point2d> Vertices { get; }
/// <summary>
/// Signed area of the contour.
/// </summary>
public double SignedArea { get; private set; }
/// <summary>
/// Are the vertices of the contour arranged in clockwise manner?
/// </summary>
/// <returns><c>true</c> if the contour is clockwise, <c>false</c> if counter-clockwise.</returns>
public bool IsClockwise { get => SignedArea < 0; }
/// <summary>
/// Get a copy of the list of the vertices of this contour.
/// </summary>
/// <returns>List of vertices defining this region.</returns>
public List<Point2d> GetVertexCopies()
{
return new List<Point2d>(Vertices);
}
/// <summary>
/// Compute the signed area of the contour
/// </summary>
private void ComputeArea()
{
double areaSum = 0;
// Go through all the vertices.
for (int i = 0; i < Vertices.Count; i++)
{
// Get current vertex
Point2d p0 = Vertices[i];
// Get the next vertex
Point2d p1 = Vertices[(i + 1) % Vertices.Count];
// Compute the area under the trapezoid made by the current segment.
// Note that this is actually double the proper value.
areaSum += (p1.X - p0.X) * (p1.Y + p0.Y);
}
// The above algorithm deems clockwise area to be positive,
// however we consider ccw contours to be positive, so we flip the value.
SignedArea = - areaSum / 2;
}
/// <summary>
/// Reverse the orientation of the contour.
/// </summary>
internal void Reverse()
{
Vertices.Reverse();
SignedArea *= -1;
}
/// <summary>
/// Constructor.
/// </summary>
public Contour(List<Point2d> vertices)
{
Vertices = vertices;
ComputeArea();
}
#if DEBUG
internal void Draw(Color color = null)
{
AcAp.Document acDoc = AcAp.Application.DocumentManager.MdiActiveDocument;
Database acDb = acDoc.Database;
using (Transaction acTrans = acDb.TransactionManager.StartTransaction())
{
// Open the BlockTableRecord
BlockTable acBlkTbl = (BlockTable)acTrans.GetObject(acDb.BlockTableId, OpenMode.ForRead);
BlockTableRecord acBlkTblRec =
(BlockTableRecord)acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
for(int i = 0; i < Vertices.Count; i++)
{
Line asLine = new Line(Vertices[i].To3d(), Vertices[(i + 1) % Vertices.Count].To3d());
asLine.Color = IsClockwise ? Color.FromRgb(255, 32, 32) : Color.FromRgb(32, 255, 32);
acBlkTblRec.AppendEntity(asLine);
acTrans.AddNewlyCreatedDBObject(asLine, true);
}
acTrans.Commit();
}
}
#endif
}
}