using GrxCAD.ApplicationServices; using GrxCAD.DatabaseServices; using GrxCAD.EditorInput; using GrxCAD.Geometry; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HCTools { class Dgxinters { public struct Dgx_ct { public Polyline pll; public double elevation; } public struct Angles { public double angle; public int xh; } public static int dgj; public void Interdgx() { Line jigl1 = Fzx(); Line jigl2 = Fzx(); List ptonline = new List();//两辅助拉线之间的线段上的点 Point3dCollection ptcoll = new Point3dCollection(); var plane = new Plane(Point3d.Origin, Vector3d.ZAxis); ptcoll.Add(jigl1.StartPoint); ptcoll.Add(jigl1.EndPoint); Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; TypedValue[] value = new TypedValue[] { new TypedValue((int)DxfCode.Start,"LWPOLYLINE"), };//设置筛选条件 SelectionFilter filter = new SelectionFilter(value); // 要求在图形区域中手动选择对象 PromptSelectionResult psr = ed.SelectFence(ptcoll, filter); if (psr.Status == PromptStatus.OK) { SelectionSet ss = psr.Value; ObjectIdCollection idcoll = new ObjectIdCollection(ss.GetObjectIds()); List dgx_ct = new List(); for (int i = 0; i < idcoll.Count; i++) { Dgx_ct temp = getpll(idcoll[i]); dgx_ct.Add(temp); } dgx_ct.OrderByDescending(x => x.elevation); for (int i = 0; i < dgx_ct.Count - 1; i++) { Point3dCollection itsresult1 = new Point3dCollection(); Point3dCollection itsresult2 = new Point3dCollection(); dgx_ct[i].pll.IntersectWith(jigl1, Intersect.OnBothOperands, plane, itsresult1, IntPtr.Zero, IntPtr.Zero); dgx_ct[i].pll.IntersectWith(jigl2, Intersect.OnBothOperands, plane, itsresult2, IntPtr.Zero, IntPtr.Zero); Point3d start = itsresult1[0]; Point3d end = itsresult2[0]; List pts1 = GetPtsBetweenpts(dgx_ct[i].pll, start, end); itsresult1 = new Point3dCollection(); itsresult2 = new Point3dCollection(); dgx_ct[i + 1].pll.IntersectWith(jigl1, Intersect.OnBothOperands, plane, itsresult1, IntPtr.Zero, IntPtr.Zero); dgx_ct[i + 1].pll.IntersectWith(jigl2, Intersect.OnBothOperands, plane, itsresult2, IntPtr.Zero, IntPtr.Zero); Point3d start1 = itsresult1[0]; Point3d end1 = itsresult2[0]; List pts2 = GetPtsBetweenpts(dgx_ct[i + 1].pll, start1, end1); List linearinterpt = new List(); double gcc = dgx_ct[i + 1].pll.Elevation - dgx_ct[i].pll.Elevation; for (int ii = 0; ii < gcc / dgj; ii++) { double targetgc = dgx_ct[i].pll.Elevation + dgj * (ii + 1); Interpolationpts(pts1, pts2, targetgc); } } ed.WriteMessage("\n等高线内插完成"); } } private static Line Fzx() { Document doc = Application.DocumentManager.MdiActiveDocument; Line jigl = new Line(); ObjectId jigid = new ObjectId(); PromptPointResult pPtRes; PromptPointOptions pPtOpts = new PromptPointOptions(""); pPtOpts.Message = "选择起点\n "; pPtRes = doc.Editor.GetPoint(pPtOpts); Point3d ptStart = pPtRes.Value; if (pPtRes.Status == PromptStatus.OK) { LineJig lJig = new LineJig(ptStart); PromptResult PR = doc.Editor.Drag(lJig); if (PR.Status == PromptStatus.OK) { jigid = BasicFunction.AddObj(doc, lJig.line_1); jigl = (Line)BasicFunction.GetDBObject(jigid); } } return jigl; } private static Dgx_ct getpll(ObjectId id) { Dgx_ct dgx_ct = new Dgx_ct(); Polyline temp = (Polyline)BasicFunction.GetDBObject(id); dgx_ct.pll = temp; dgx_ct.elevation = Convert.ToDouble(temp.Elevation.ToString("0.00")); return dgx_ct; } private static List GetPtsBetweenpts(Polyline pll, Point3d start, Point3d end) { List allvertex = new List(); List vertexbt = new List(); vertexbt.Add(start); for (int i = 0; i < pll.NumberOfVertices; i++) { allvertex.Add(pll.GetPoint3dAt(i)); } double dist1 = double.MaxValue; int start_index = 0; double dist2 = double.MaxValue; int end_index = 0; bool sort = false; for (int i = 0; i < allvertex.Count; i++) { if (start.DistanceTo(allvertex[i]) < dist1) { dist1 = start.DistanceTo(allvertex[i]); start_index = i; } if (end.DistanceTo(allvertex[i]) < dist2) { dist2 = end.DistanceTo(allvertex[i]); end_index = i; } } if (start_index > end_index) { int temp = start_index; start_index = end_index; end_index = temp; sort = true; } for (int i = start_index; i < end_index + 1; i++) { if (!vertexbt.Contains(allvertex[i])) { vertexbt.Add(allvertex[i]); if (i == end_index && !vertexbt.Contains(end)) vertexbt.Add(end); } } if (sort) vertexbt.Reverse(); return vertexbt; } private static double CalculateAngles(Point3d pt1, Point3d pt2, Point3d pt3) { //计算角度 Vector3d vectorAB = pt1.GetVectorTo(pt2); Vector3d vectorBC = pt2.GetVectorTo(pt3); double dotProduct = vectorAB.DotProduct(vectorBC); // 计算两个向量的长度 double lengthAB = vectorAB.Length; double lengthBC = vectorBC.Length; double angleDegrees = new double(); // 防止除以零的错误 if (lengthAB > 0 && lengthBC > 0) { // 计算两个向量之间夹角的余弦值 double cosAngle = dotProduct / (lengthAB * lengthBC); // 使用反余弦函数计算夹角(以弧度为单位) double angleRadians = Math.Acos(cosAngle); // 将弧度转换为度 angleDegrees = angleRadians * (180.0 / Math.PI); } return angleDegrees; } private static bool LineIntersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { double d1x = x2 - x1; double d1y = y2 - y1; double d2x = x4 - x3; double d2y = y4 - y3; // 计算点1和点2相对于线段CD的叉积 double cp1 = d2x * (y1 - y3) - (x1 - x3) * d2y; double cp2 = d2x * (y2 - y3) - (x2 - x3) * d2y; // 如果点1和点2相对于线段CD的叉积符号相反,则它们跨立在CD的两侧 if (cp1 * cp2 < 0) { // 计算点3和点4相对于线段AB的叉积 double cp3 = d1x * (y3 - y1) - (x3 - x1) * d1y; double cp4 = d1x * (y4 - y1) - (x4 - x1) * d1y; // 如果点3和点4相对于线段AB的叉积符号也相反,则它们跨立在AB的两侧 if (cp3 * cp4 < 0) { // 根据跨立实验,如果以上条件都满足,则线段一定相交 return true; } } // 线段不相交 return false; } private static Point3d Interpolation(Point3d p1, Point3d p2, double targetZ) { double t = (targetZ - p1.Z) / dgj; double x = p1.X + t * (p2.X - p1.X); double y = p1.Y + t * (p2.Y - p1.Y); return new Point3d(x, y, targetZ); } public static void Interpolationpts(List pts1, List pts2, double targetgc) { Point3d pt1 = pts1[0]; Point3d pt2 = pts2[0]; List itspt = new List(); int index1 = 0; int index2 = 0; List interplpts = new List(); for (int i = 0; i < pts1.Count; i++) { List angle1 = new List();//等高线1上的点 List angle2 = new List();//等高线2上的点 List errindex1 = new List(); List errindex2 = new List(); bool flag = false; for (int j = i; j < pts1.Count - 1; j++) { if (errindex1.Contains(j)) continue; else { double angle = CalculateAngles(pt1, pts1[j + 1], pt2); Angles temp = new Angles(); temp.angle = angle; temp.xh = j; angle1.Add(temp); } } for (int j = i; j < pts2.Count - 1; j++) { if (errindex2.Contains(j)) continue; else { double angle = CalculateAngles(pt1, pts2[j + 1], pt2); Angles temp = new Angles(); temp.angle = angle; temp.xh = j; angle2.Add(temp); } } angle1.OrderByDescending(x => x.angle); angle2.OrderByDescending(x => x.angle); while (flag) { double px = pts1[angle1[0].xh].X; double py = pts1[angle1[0].xh].Y; double qx = pts1[angle2[0].xh].X; double qy = pts1[angle2[0].xh].Y; double dx1 = pt1.X - px; double dy1 = pt1.Y - py; double dx2 = pt2.X - qx; double dy2 = pt2.Y - qy; bool interck1 = LineIntersect(pt1.X, pt1.Y, pts1[index1].X, pts1[index1].Y, pt2.X, pt2.Y, px, py); bool interck2 = LineIntersect(pt1.X, pt1.Y, px, py, pt2.X, pt2.Y, pts2[index2].X, pts2[index2].Y); bool interck3 = LineIntersect(pt1.X, pt1.Y, qx, qy, pt2.X, pt2.Y, pts2[index2].X, pts2[index2].Y); bool interck4 = LineIntersect(pt1.X, pt1.Y, pts1[index1].X, pts1[index1].Y, pt2.X, pt2.Y, qx, qy); if (interck1 & interck2) { if (interck3 & interck4) { if (angle1[0].angle > angle2[0].angle) { for (int ii = index1 + 1; ii < angle1[0].xh; ii++) { Point3d pt = Interpolation(pt2, pts1[ii], targetgc); itspt.Add(pt); if(ii) pt1 = pts1[ii]; } flag = true; } else { } } else { angle2.RemoveAt(0); continue; } } else { angle1.RemoveAt(0); continue; } } } Database db = HostApplicationServices.WorkingDatabase; Document doc = Application.DocumentManager.MdiActiveDocument; DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockTable blocktable = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord blctablerecord = trans.GetObject(blocktable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; Polyline pll = new Polyline(); for (int i = 0; i < itspt.Count; i++) { pll.AddVertexAt(i, new Point2d(itspt[i].X, itspt[i].Y), 0, 0, 0); } blctablerecord.AppendEntity(pll); trans.AddNewlyCreatedDBObject(pll, true); trans.Commit(); } doclock.Dispose(); } } }