124 lines
3.2 KiB
C#
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
|
|
}
|
|
}
|