工具箱相关
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

Dgxinters.cs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. using GrxCAD.ApplicationServices;
  2. using GrxCAD.DatabaseServices;
  3. using GrxCAD.EditorInput;
  4. using GrxCAD.Geometry;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace HCTools
  11. {
  12. class Dgxinters
  13. {
  14. public struct Dgx_ct
  15. {
  16. public Polyline pll;
  17. public double elevation;
  18. }
  19. public struct Angles
  20. {
  21. public double angle;
  22. public int xh;
  23. }
  24. public static int dgj;
  25. public void Interdgx()
  26. {
  27. Line jigl1 = Fzx();
  28. Line jigl2 = Fzx();
  29. List<Point3d> ptonline = new List<Point3d>();//两辅助拉线之间的线段上的点
  30. Point3dCollection ptcoll = new Point3dCollection();
  31. var plane = new Plane(Point3d.Origin, Vector3d.ZAxis);
  32. ptcoll.Add(jigl1.StartPoint);
  33. ptcoll.Add(jigl1.EndPoint);
  34. Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  35. TypedValue[] value = new TypedValue[]
  36. {
  37. new TypedValue((int)DxfCode.Start,"LWPOLYLINE"),
  38. };//设置筛选条件
  39. SelectionFilter filter = new SelectionFilter(value);
  40. // 要求在图形区域中手动选择对象
  41. PromptSelectionResult psr = ed.SelectFence(ptcoll, filter);
  42. if (psr.Status == PromptStatus.OK)
  43. {
  44. SelectionSet ss = psr.Value;
  45. ObjectIdCollection idcoll = new ObjectIdCollection(ss.GetObjectIds());
  46. List<Dgx_ct> dgx_ct = new List<Dgx_ct>();
  47. for (int i = 0; i < idcoll.Count; i++)
  48. {
  49. Dgx_ct temp = getpll(idcoll[i]);
  50. dgx_ct.Add(temp);
  51. }
  52. dgx_ct.OrderByDescending(x => x.elevation);
  53. for (int i = 0; i < dgx_ct.Count - 1; i++)
  54. {
  55. Point3dCollection itsresult1 = new Point3dCollection();
  56. Point3dCollection itsresult2 = new Point3dCollection();
  57. dgx_ct[i].pll.IntersectWith(jigl1, Intersect.OnBothOperands, plane, itsresult1, IntPtr.Zero, IntPtr.Zero);
  58. dgx_ct[i].pll.IntersectWith(jigl2, Intersect.OnBothOperands, plane, itsresult2, IntPtr.Zero, IntPtr.Zero);
  59. Point3d start = itsresult1[0];
  60. Point3d end = itsresult2[0];
  61. List<Point3d> pts1 = GetPtsBetweenpts(dgx_ct[i].pll, start, end);
  62. itsresult1 = new Point3dCollection();
  63. itsresult2 = new Point3dCollection();
  64. dgx_ct[i + 1].pll.IntersectWith(jigl1, Intersect.OnBothOperands, plane, itsresult1, IntPtr.Zero, IntPtr.Zero);
  65. dgx_ct[i + 1].pll.IntersectWith(jigl2, Intersect.OnBothOperands, plane, itsresult2, IntPtr.Zero, IntPtr.Zero);
  66. Point3d start1 = itsresult1[0];
  67. Point3d end1 = itsresult2[0];
  68. List<Point3d> pts2 = GetPtsBetweenpts(dgx_ct[i + 1].pll, start1, end1);
  69. List<Point3d> linearinterpt = new List<Point3d>();
  70. double gcc = dgx_ct[i + 1].pll.Elevation - dgx_ct[i].pll.Elevation;
  71. for (int ii = 0; ii < gcc / dgj; ii++)
  72. {
  73. double targetgc = dgx_ct[i].pll.Elevation + dgj * (ii + 1);
  74. Interpolationpts(pts1, pts2, targetgc);
  75. }
  76. }
  77. ed.WriteMessage("\n等高线内插完成");
  78. }
  79. }
  80. private static Line Fzx()
  81. {
  82. Document doc = Application.DocumentManager.MdiActiveDocument;
  83. Line jigl = new Line();
  84. ObjectId jigid = new ObjectId();
  85. PromptPointResult pPtRes;
  86. PromptPointOptions pPtOpts = new PromptPointOptions("");
  87. pPtOpts.Message = "选择起点\n ";
  88. pPtRes = doc.Editor.GetPoint(pPtOpts);
  89. Point3d ptStart = pPtRes.Value;
  90. if (pPtRes.Status == PromptStatus.OK)
  91. {
  92. LineJig lJig = new LineJig(ptStart);
  93. PromptResult PR = doc.Editor.Drag(lJig);
  94. if (PR.Status == PromptStatus.OK)
  95. {
  96. jigid = BasicFunction.AddObj(doc, lJig.line_1);
  97. jigl = (Line)BasicFunction.GetDBObject(jigid);
  98. }
  99. }
  100. return jigl;
  101. }
  102. private static Dgx_ct getpll(ObjectId id)
  103. {
  104. Dgx_ct dgx_ct = new Dgx_ct();
  105. Polyline temp = (Polyline)BasicFunction.GetDBObject(id);
  106. dgx_ct.pll = temp;
  107. dgx_ct.elevation = Convert.ToDouble(temp.Elevation.ToString("0.00"));
  108. return dgx_ct;
  109. }
  110. private static List<Point3d> GetPtsBetweenpts(Polyline pll, Point3d start, Point3d end)
  111. {
  112. List<Point3d> allvertex = new List<Point3d>();
  113. List<Point3d> vertexbt = new List<Point3d>();
  114. vertexbt.Add(start);
  115. for (int i = 0; i < pll.NumberOfVertices; i++)
  116. {
  117. allvertex.Add(pll.GetPoint3dAt(i));
  118. }
  119. double dist1 = double.MaxValue;
  120. int start_index = 0;
  121. double dist2 = double.MaxValue;
  122. int end_index = 0;
  123. bool sort = false;
  124. for (int i = 0; i < allvertex.Count; i++)
  125. {
  126. if (start.DistanceTo(allvertex[i]) < dist1)
  127. {
  128. dist1 = start.DistanceTo(allvertex[i]);
  129. start_index = i;
  130. }
  131. if (end.DistanceTo(allvertex[i]) < dist2)
  132. {
  133. dist2 = end.DistanceTo(allvertex[i]);
  134. end_index = i;
  135. }
  136. }
  137. if (start_index > end_index)
  138. {
  139. int temp = start_index;
  140. start_index = end_index;
  141. end_index = temp;
  142. sort = true;
  143. }
  144. for (int i = start_index; i < end_index + 1; i++)
  145. {
  146. if (!vertexbt.Contains(allvertex[i]))
  147. {
  148. vertexbt.Add(allvertex[i]);
  149. if (i == end_index && !vertexbt.Contains(end))
  150. vertexbt.Add(end);
  151. }
  152. }
  153. if (sort)
  154. vertexbt.Reverse();
  155. return vertexbt;
  156. }
  157. private static double CalculateAngles(Point3d pt1, Point3d pt2, Point3d pt3)
  158. {
  159. //计算角度
  160. Vector3d vectorAB = pt1.GetVectorTo(pt2);
  161. Vector3d vectorBC = pt2.GetVectorTo(pt3);
  162. double dotProduct = vectorAB.DotProduct(vectorBC);
  163. // 计算两个向量的长度
  164. double lengthAB = vectorAB.Length;
  165. double lengthBC = vectorBC.Length;
  166. double angleDegrees = new double();
  167. // 防止除以零的错误
  168. if (lengthAB > 0 && lengthBC > 0)
  169. {
  170. // 计算两个向量之间夹角的余弦值
  171. double cosAngle = dotProduct / (lengthAB * lengthBC);
  172. // 使用反余弦函数计算夹角(以弧度为单位)
  173. double angleRadians = Math.Acos(cosAngle);
  174. // 将弧度转换为度
  175. angleDegrees = angleRadians * (180.0 / Math.PI);
  176. }
  177. return angleDegrees;
  178. }
  179. private static bool LineIntersect(double x1, double y1, double x2, double y2,
  180. double x3, double y3, double x4, double y4)
  181. {
  182. double d1x = x2 - x1;
  183. double d1y = y2 - y1;
  184. double d2x = x4 - x3;
  185. double d2y = y4 - y3;
  186. // 计算点1和点2相对于线段CD的叉积
  187. double cp1 = d2x * (y1 - y3) - (x1 - x3) * d2y;
  188. double cp2 = d2x * (y2 - y3) - (x2 - x3) * d2y;
  189. // 如果点1和点2相对于线段CD的叉积符号相反,则它们跨立在CD的两侧
  190. if (cp1 * cp2 < 0)
  191. {
  192. // 计算点3和点4相对于线段AB的叉积
  193. double cp3 = d1x * (y3 - y1) - (x3 - x1) * d1y;
  194. double cp4 = d1x * (y4 - y1) - (x4 - x1) * d1y;
  195. // 如果点3和点4相对于线段AB的叉积符号也相反,则它们跨立在AB的两侧
  196. if (cp3 * cp4 < 0)
  197. {
  198. // 根据跨立实验,如果以上条件都满足,则线段一定相交
  199. return true;
  200. }
  201. }
  202. // 线段不相交
  203. return false;
  204. }
  205. private static Point3d Interpolation(Point3d p1, Point3d p2, double targetZ)
  206. {
  207. double t = (targetZ - p1.Z) / dgj;
  208. double x = p1.X + t * (p2.X - p1.X);
  209. double y = p1.Y + t * (p2.Y - p1.Y);
  210. return new Point3d(x, y, targetZ);
  211. }
  212. public static void Interpolationpts(List<Point3d> pts1, List<Point3d> pts2, double targetgc)
  213. {
  214. Point3d pt1 = pts1[0];
  215. Point3d pt2 = pts2[0];
  216. List<Point3d> itspt = new List<Point3d>();
  217. int index1 = 0;
  218. int index2 = 0;
  219. List<Point3d> interplpts = new List<Point3d>();
  220. for (int i = 0; i < pts1.Count; i++)
  221. {
  222. List<Angles> angle1 = new List<Angles>();//等高线1上的点
  223. List<Angles> angle2 = new List<Angles>();//等高线2上的点
  224. List<int> errindex1 = new List<int>();
  225. List<int> errindex2 = new List<int>();
  226. bool flag = false;
  227. for (int j = i; j < pts1.Count - 1; j++)
  228. {
  229. if (errindex1.Contains(j))
  230. continue;
  231. else
  232. {
  233. double angle = CalculateAngles(pt1, pts1[j + 1], pt2);
  234. Angles temp = new Angles();
  235. temp.angle = angle;
  236. temp.xh = j;
  237. angle1.Add(temp);
  238. }
  239. }
  240. for (int j = i; j < pts2.Count - 1; j++)
  241. {
  242. if (errindex2.Contains(j))
  243. continue;
  244. else
  245. {
  246. double angle = CalculateAngles(pt1, pts2[j + 1], pt2);
  247. Angles temp = new Angles();
  248. temp.angle = angle;
  249. temp.xh = j;
  250. angle2.Add(temp);
  251. }
  252. }
  253. angle1.OrderByDescending(x => x.angle);
  254. angle2.OrderByDescending(x => x.angle);
  255. while (flag)
  256. {
  257. double px = pts1[angle1[0].xh].X;
  258. double py = pts1[angle1[0].xh].Y;
  259. double qx = pts1[angle2[0].xh].X;
  260. double qy = pts1[angle2[0].xh].Y;
  261. double dx1 = pt1.X - px;
  262. double dy1 = pt1.Y - py;
  263. double dx2 = pt2.X - qx;
  264. double dy2 = pt2.Y - qy;
  265. bool interck1 = LineIntersect(pt1.X, pt1.Y, pts1[index1].X, pts1[index1].Y, pt2.X, pt2.Y, px, py);
  266. bool interck2 = LineIntersect(pt1.X, pt1.Y, px, py, pt2.X, pt2.Y, pts2[index2].X, pts2[index2].Y);
  267. bool interck3 = LineIntersect(pt1.X, pt1.Y, qx, qy, pt2.X, pt2.Y, pts2[index2].X, pts2[index2].Y);
  268. bool interck4 = LineIntersect(pt1.X, pt1.Y, pts1[index1].X, pts1[index1].Y, pt2.X, pt2.Y, qx, qy);
  269. if (interck1 & interck2)
  270. {
  271. if (interck3 & interck4)
  272. {
  273. if (angle1[0].angle > angle2[0].angle)
  274. {
  275. for (int ii = index1 + 1; ii < angle1[0].xh; ii++)
  276. {
  277. Point3d pt = Interpolation(pt2, pts1[ii], targetgc);
  278. itspt.Add(pt);
  279. if(ii)
  280. pt1 = pts1[ii];
  281. }
  282. flag = true;
  283. }
  284. else
  285. {
  286. }
  287. }
  288. else
  289. {
  290. angle2.RemoveAt(0);
  291. continue;
  292. }
  293. }
  294. else
  295. {
  296. angle1.RemoveAt(0);
  297. continue;
  298. }
  299. }
  300. }
  301. Database db = HostApplicationServices.WorkingDatabase;
  302. Document doc = Application.DocumentManager.MdiActiveDocument;
  303. DocumentLock doclock = GrxCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
  304. using (Transaction trans = db.TransactionManager.StartTransaction())
  305. {
  306. BlockTable blocktable = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  307. BlockTableRecord blctablerecord = trans.GetObject(blocktable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  308. Polyline pll = new Polyline();
  309. for (int i = 0; i < itspt.Count; i++)
  310. {
  311. pll.AddVertexAt(i, new Point2d(itspt[i].X, itspt[i].Y), 0, 0, 0);
  312. }
  313. blctablerecord.AppendEntity(pll);
  314. trans.AddNewlyCreatedDBObject(pll, true);
  315. trans.Commit();
  316. }
  317. doclock.Dispose();
  318. }
  319. }
  320. }