using System;
using System.Collections.Generic;
using System.Linq;
using ZwSoft.ZwCAD.ApplicationServices;
using ZwSoft.ZwCAD.DatabaseServices;
using ZwSoft.ZwCAD.EditorInput;
using ZwSoft.ZwCAD.Geometry;
using ZwSoft.ZwCAD.Runtime;
using ZWApp = ZwSoft.ZwCAD.ApplicationServices.Application;
//最后结果为{{k,b,p1,p2},{k,b,p1,p2}}
namespace CADToExcel
{
public static class Class1
{
public static Document doc = ZWApp.DocumentManager.MdiActiveDocument;
public static Database db = HostApplicationServices.WorkingDatabase;
public static Editor ed = doc.Editor;
[CommandMethod("CTE", CommandFlags.Session | CommandFlags.UsePickSet)]
public static void CTE()
{
List<Entity> linelst = new List<Entity>();
List<LInfo> linfo = new List<LInfo>();
using (DocumentLock dloc = doc.LockDocument())
{
TypedValue[] value = new TypedValue[] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE,LINE") };
SelectionFilter filter = new SelectionFilter(value);
PromptSelectionResult psr = ed.GetSelection(filter);
ObjectId[] ids = psr.Value.GetObjectIds();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
//打开块表记录
BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
linelst = ids.Cast<ObjectId>().Select(id => (Entity)id.GetObject(OpenMode.ForWrite)).ToList();
}
foreach (Entity lent in linelst)
{
if ("Line".Equals(lent.GetType().Name, StringComparison.CurrentCultureIgnoreCase))
{
Line l = (Line)lent;
linfo.Add(Line_Data(l.StartPoint, l.EndPoint));
}
else
{
Polyline pl = (Polyline)lent;
int ptn = pl.NumberOfVertices - 1;
for (int i = 0; i < ptn; i++)
{
linfo.Add(Line_Data(pl.GetPoint3dAt(i), pl.GetPoint3dAt(i + 1)));
}
if (pl.Closed) linfo.Add(Line_Data(pl.GetPoint3dAt(ptn), pl.GetPoint3dAt(0)));
}
}
//rowLine = rowLine.OrderByDescending(linept => linept.Value).ToList();
//colLine = colLine.OrderBy(linept => linept.Value).ToList();
linfo.Sort((e1, e2) =>
{
if (e1.K.EqOfDis(e2.K))
{
if (e1.B.EqOfDis(e2.B))
{
if (e1.P1.X.EqOfDis(e2.P2.X)) return e1.P1.Y.CompareTo(e1.P2.Y);
else return e1.P1.X.CompareTo(e1.P2.X);
}
else return e1.B.CompareTo(e2.B);
}
else return e1.K.CompareTo(e2.K);
});
linfo = linfo.HB_Line();
}
}
#region MyRegion 合并使用函数
public struct LInfo
{
public LInfo(double value, double k, double b, Point3d p1, Point3d p2)
{
Value = value;
K = k;
B = b;
P1 = p1;
P2 = p2;
}
public double Value { set; get; }
public double K { set; get; }
public double B { set; get; }
public Point3d P1 { set; get; }
public Point3d P2 { set; get; }
}
//容差比较两个数
public static bool EqOfDis(this double value1, double value2, double dis = 1e-06) => Math.Abs(value1 - value2) <= dis;
//容差比较两个点的距离
public static bool EqOfDis(this Point3d pt1, Point3d pt2, double dis = 1e-06) => Math.Abs(pt1.X - pt2.X) < dis && Math.Abs(pt1.Y - pt2.Y) < dis && Math.Abs(pt1.Z - pt2.Z) < dis;
public static LInfo Line_Data(Point3d pt1, Point3d pt2)
{
double k, b;
if (pt1.X.EqOfDis(pt2.X))
{
k = double.NaN;
b = pt1.X;
}
else
{
k = (pt2.Y - pt1.Y) / (pt2.X - pt1.X);
b = pt1.Y - (pt1.X * k);
}
return pt1.X.EqOfDis(pt2.X)
? pt1.Y > pt2.Y ? new LInfo(k, b, pt2, pt1) : new LInfo(k, b, pt1, pt2)
: pt1.X > pt2.X ? new LInfo(k, b, pt2, pt1) : new LInfo(k, b, pt1, pt2);
}
public static List<LInfo> HB_Line(this List<LInfo> linelst)
{
List<LInfo> newlst = new List<LInfo>();
int count = linelst.Count, i = 0, index = 0;
double k, b;
Point3d p1, p2, p3, p4;
while (linelst.Count > 0)
{
index++;
LInfo lia = linelst[0];
linelst.Remove(lia);
bool mark = true;
k = lia.K;
b = lia.B;
p1 = lia.P1;
p2 = lia.P2;
while (mark && linelst.Count > 0)
{
LInfo lib = linelst[0];
if (k.EqOfDis(lib.K) && b.EqOfDis(lib.B))
{
p3 = lib.P1;
p4 = lib.P2;
List<Point3d> plst = new List<Point3d> { p1, p2, p3, p4 };
plst.Sort((pa, pb) =>
{
return pa.X.EqOfDis(pb.X) ? pa.Y.CompareTo(pb.Y) : pa.X.CompareTo(pb.X);
});
p4 = plst[1];
if (p1.EqOfDis(p4) || p3.EqOfDis(p4))
{
p1 = plst.First();
p2 = plst.Last();
linelst.Remove(lib);
index++;
i++;
}
else mark = false;
}
else mark = false;
}
newlst.Add(new LInfo(lia.Value, lia.K, lia.B, p1, p2));
}
return newlst;
}
#endregion
}
}