LineExtend.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. using System;
  2. using System.Collections.Generic;
  3. using Autodesk.Revit.DB;
  4. using SAGA.DotNetUtils;
  5. using SAGA.DotNetUtils.Extend;
  6. using SAGA.RevitAPI;
  7. using SAGA.RevitUtils.Infrastructure;
  8. namespace SAGA.RevitUtils.Extends
  9. {
  10. public static class LineExtend
  11. {
  12. /// <summary>
  13. /// 增加z值
  14. /// </summary>
  15. /// <param name="line"></param>
  16. /// <param name="dZ"></param>
  17. /// <returns></returns>
  18. public static Line AddZ(this Line line, double dZ)
  19. {
  20. XYZ ptS = line.StartPoint().AddZ(dZ);
  21. XYZ ptE = line.EndPoint().AddZ(dZ);
  22. return Line.CreateBound(ptS, ptE);
  23. }
  24. /// <summary>
  25. /// 修改z值
  26. /// </summary>
  27. /// <param name="line"></param>
  28. /// <param name="dZ"></param>
  29. /// <returns></returns>
  30. public static Line NewZ(this Line line, double dZ=0)
  31. {
  32. XYZ ptS = line.StartPoint().NewZ(dZ);
  33. XYZ ptE = line.EndPoint().NewZ(dZ);
  34. if (ptS.IsEqual(ptE))
  35. {
  36. return null;
  37. }
  38. return Line.CreateBound(ptS, ptE);
  39. }
  40. /// <summary>
  41. /// 绕起点旋转
  42. /// </summary>
  43. /// <param name="line"></param>
  44. /// <param name="angle">旋转角度(弧度)</param>
  45. /// <returns></returns>
  46. public static Line RotateByStart(this Line line, double angle)
  47. {
  48. Transform tranform = Transform.CreateRotationAtPoint(XYZ.BasisZ, angle, line.StartPoint());
  49. Line result = (Line)line.CreateTransformed(tranform);
  50. return result;
  51. }
  52. /// <summary>
  53. /// 过点pt与line垂直的射线
  54. /// </summary>
  55. /// <param name="line"></param>
  56. /// <param name="pt"></param>
  57. /// <returns></returns>
  58. public static Line GetVUnboundLine(this Line line, XYZ pt)
  59. {
  60. double dAngle = Math.PI / 2;
  61. XYZ vecDir = line.Direction.VectorRotate(dAngle);
  62. return Line.CreateUnbound(pt, vecDir);
  63. }
  64. /// <summary>
  65. /// 三维中直线与其XY平面投影线所成夹角,就是坡度
  66. /// </summary>
  67. /// <param name="line"></param>
  68. /// <returns></returns>
  69. public static double GetSlopeAngleZ(this Line line)
  70. {
  71. double dRtn = 0;
  72. double dH = Math.Abs(line.StartPoint().Z - line.EndPoint().Z);
  73. double dL = line.Length;
  74. dRtn = Math.Asin(dH / dL);
  75. return dRtn;
  76. }
  77. /// <summary>
  78. /// 坡度的起点,即檐口处理点
  79. /// </summary>
  80. /// <param name="line"></param>
  81. /// <returns></returns>
  82. public static XYZ GetSlopeStartPoint(this Line line)
  83. {
  84. XYZ ptRtn = null;
  85. double dAngle = line.GetSlopeAngleZ();
  86. if (dAngle.IsEqual(0))
  87. {
  88. ptRtn = line.StartPoint();
  89. }
  90. else
  91. {
  92. if (line.StartPoint().Z < line.EndPoint().Z)
  93. {
  94. ptRtn = line.StartPoint();
  95. }
  96. else
  97. {
  98. ptRtn = line.EndPoint();
  99. }
  100. }
  101. return ptRtn;
  102. }
  103. /// <summary>
  104. /// 以直线中点为基点,向两边延展n个直线单位向量做新直线
  105. /// </summary>
  106. /// <param name="line"></param>
  107. /// <param name="n"></param>
  108. /// <returns></returns>
  109. public static Line ExtendLengthByMiddle(this Line line, uint n)
  110. {
  111. XYZ direction = line.Direction;
  112. XYZ m = line.MiddlePoint();
  113. return Line.CreateBound(m - direction * n, m + direction * n);
  114. }
  115. /// <summary>
  116. /// 偏移到点
  117. /// </summary>
  118. /// <param name="line"></param>
  119. /// <param name="pt">过某一点</param>
  120. /// <returns></returns>
  121. public static Line OffsetPoint(this Line line, XYZ pt)
  122. {
  123. XYZ ptV = line.VerticalPoint(pt);
  124. XYZ vec = pt.Subtract(ptV);
  125. return line.OffsetVector(vec).GetLine();
  126. }
  127. /// <summary>
  128. /// 两直线平行
  129. /// </summary>
  130. /// <param name="line1"></param>
  131. /// <param name="line2"></param>
  132. /// <param name="tolerance"></param>
  133. /// <param name="hasDirection">是否区分方向</param>
  134. /// <returns></returns>
  135. public static bool IsParallel(this Line line1, Line line2, double tolerance = 0.0, bool hasDirection = false)
  136. {
  137. if (hasDirection)
  138. {
  139. return line1.Direction.IsEqual(line2.Direction, tolerance);
  140. }
  141. if (!line1.Direction.IsEqual(line2.Direction, tolerance))
  142. {
  143. return line1.Direction.IsEqual(-line2.Direction, tolerance);
  144. }
  145. return true;
  146. }
  147. /// <summary>
  148. /// 偏移,区分正负值
  149. /// </summary>
  150. /// <param name="line"></param>
  151. /// <param name="dValue">大于零、小于零</param>
  152. /// <returns></returns>
  153. public static Line Offset(this Line line, double dValue)
  154. {
  155. XYZ vec = line.Direction.Normalize().VectorRotate(Math.PI / 2) * dValue;
  156. return line.OffsetVector(vec).GetLine();
  157. }
  158. /// <summary>
  159. /// 相等
  160. /// </summary>
  161. /// <param name="line1"></param>
  162. /// <param name="line2"></param>
  163. /// <param name="useDirection">考虑方向</param>
  164. /// <param name="tolerance"></param>
  165. /// <returns></returns>
  166. public static bool IsEqual(this Line line1, Line line2, bool useDirection = false, double tolerance = 0)
  167. {
  168. if (useDirection)
  169. {
  170. return line1.StartPoint().IsEqual(line2.StartPoint(), tolerance) &&
  171. line1.EndPoint().IsEqual(line2.EndPoint(), tolerance);
  172. }
  173. else
  174. {
  175. return ((line1.StartPoint().IsEqual(line2.StartPoint(), tolerance) &&
  176. line1.EndPoint().IsEqual(line2.EndPoint(), tolerance)) ||
  177. (line1.StartPoint().IsEqual(line2.EndPoint(), tolerance) &&
  178. line1.EndPoint().IsEqual(line2.StartPoint(), tolerance)));
  179. }
  180. }
  181. /// <summary>
  182. /// 相等,不考虑Z坐标
  183. /// </summary>
  184. /// <param name="line1"></param>
  185. /// <param name="line2"></param>
  186. /// <param name="useDirection"></param>
  187. /// <param name="tolerance"></param>
  188. /// <returns></returns>
  189. public static bool IsEqual2(this Line line1, Line line2, bool useDirection = false, double tolerance = 0)
  190. {
  191. return line1.NewZ().IsEqual(line2.NewZ(), useDirection, tolerance);
  192. }
  193. /// <summary>
  194. /// 反向
  195. /// </summary>
  196. /// <param name="line"></param>
  197. /// <returns></returns>
  198. public static Line Reverse(this Line line)
  199. {
  200. return line.IsBound
  201. ? Line.CreateBound(line.EndPoint(), line.StartPoint())
  202. : Line.CreateUnbound(line.Origin, -line.Direction);
  203. }
  204. /// <summary>
  205. /// 水平线
  206. /// </summary>
  207. /// <param name="line"></param>
  208. /// <returns></returns>
  209. public static bool IsHorizontal(this Line line)
  210. {
  211. return line.StartPoint().Y.IsEqual(line.EndPoint().Y);
  212. }
  213. /// <summary>
  214. /// 垂直线
  215. /// </summary>
  216. /// <param name="line"></param>
  217. /// <returns></returns>
  218. public static bool IsVertical(this Line line, double tolerance = 0.0)
  219. {
  220. return line.StartPoint().X.IsEqual(line.EndPoint().X, tolerance);
  221. }
  222. /// <summary>
  223. /// 获取相对X轴倾斜角度
  224. /// </summary>
  225. /// <param name="line"></param>
  226. /// <returns></returns>
  227. public static double GetSlopeAngle(this Line line)
  228. {
  229. return line.GetSlopeRadian().ToAngle();
  230. }
  231. /// <summary>
  232. /// 获取相对X轴倾斜弧度
  233. /// </summary>
  234. /// <param name="line">直线</param>
  235. /// <returns></returns>
  236. public static double GetSlopeRadian(this Line line)
  237. {
  238. XYZ vec = line.UnitVector();
  239. return vec.QuadrantAngle();
  240. }
  241. /// <summary>
  242. /// 直线垂直
  243. /// </summary>
  244. /// <param name="line1"></param>
  245. /// <param name="line2"></param>
  246. /// <returns></returns>
  247. public static bool IsVertical(this Line line1, Line line2, double tolerance = 0.0)
  248. {
  249. return line1.Direction.IsVertical(line2.Direction, tolerance);
  250. }
  251. /// <summary>
  252. /// 判断线段是否在多边形内,注意Z坐标
  253. /// </summary>
  254. /// <param name="line"></param>
  255. /// <param name="listProfile"></param>
  256. /// <returns></returns>
  257. public static bool LineInPolygon(this Line line, List<Curve> listProfile)
  258. {
  259. //if 线端PQ的端点不都在多边形内
  260. // then return false;
  261. XYZ ptSl = line.StartPoint();
  262. XYZ ptEl = line.EndPoint();
  263. if (!ptSl.PointInPolygon2(listProfile) && !ptSl.PointInPoly(listProfile))
  264. return false;
  265. //bool blnRtn = ptSL.PointInPolygon2(listProfile);
  266. //if (!blnRtn)
  267. //{
  268. // return false;
  269. //}
  270. if (!ptEl.PointInPolygon2(listProfile) && !ptEl.PointInPoly(listProfile))
  271. return false;
  272. //blnRtn = ptEL.PointInPolygon2(listProfile);
  273. //if (!blnRtn)
  274. //{
  275. // return false;
  276. //}
  277. //点集pointSet初始化为空;
  278. List<XYZ> listPt = new List<XYZ>();
  279. //for 多边形的每条边s
  280. foreach (Curve curve in listProfile)
  281. {
  282. // do if 线段的某个端点在s上
  283. // then 将该端点加入pointSet;
  284. bool blnTmep1 = curve.IsOnCurve(ptSl);
  285. bool blnTmep2 = curve.IsOnCurve(ptEl);
  286. if (blnTmep1 || blnTmep2)
  287. {
  288. if (blnTmep1)
  289. {
  290. if (!ptSl.ExsitsInlist(listPt))
  291. {
  292. listPt.Add(ptSl);
  293. }
  294. }
  295. if (blnTmep2)
  296. {
  297. if (!ptEl.ExsitsInlist(listPt))
  298. {
  299. listPt.Add(ptEl);
  300. }
  301. }
  302. }
  303. else
  304. {
  305. // else if s的某个端点在线段PQ上
  306. // then 将该端点加入pointSet;
  307. XYZ ptSs = curve.StartPoint();
  308. XYZ ptEs = curve.EndPoint();
  309. blnTmep1 = line.IsOnCurve(ptSs);
  310. blnTmep2 = line.IsOnCurve(ptEs);
  311. if (blnTmep1 || blnTmep2)
  312. {
  313. if (blnTmep1)
  314. {
  315. if (!ptSs.ExsitsInlist(listPt))
  316. {
  317. listPt.Add(ptSs);
  318. }
  319. }
  320. if (blnTmep2)
  321. {
  322. if (!ptEs.ExsitsInlist(listPt))
  323. {
  324. listPt.Add(ptEs);
  325. }
  326. }
  327. }
  328. else
  329. {
  330. //else if s和线段PQ相交 // 这时候已经可以肯定是内交了
  331. //then return false;
  332. if (curve.IsIntersection(line))
  333. {
  334. return false;
  335. }
  336. }
  337. }
  338. }
  339. //将pointSet中的点按照X-Y坐标排序;
  340. listPt.Sort(new XyzComparer());
  341. //for pointSet中每两个相邻点 pointSet[i] , pointSet[ i+1]
  342. //do if pointSet[i] , pointSet[ i+1] 的中点不在多边形中
  343. //then return false;
  344. for (int i = 0; i < listPt.Count - 1; i++)
  345. {
  346. XYZ ptMid = listPt[i].MiddlePoint(listPt[i + 1]);
  347. if (!ptMid.PointInPolygon2(listProfile) && !ptMid.PointInPoly(listProfile))
  348. return false;
  349. //blnRtn = ptMid.PointInPolygon2(listProfile);
  350. //if (!blnRtn)
  351. //{
  352. // return false;
  353. //}
  354. }
  355. return true;
  356. }
  357. /// <summary>
  358. /// 线与多边型相交,注意Z坐标
  359. /// </summary>
  360. /// <param name="line"></param>
  361. /// <param name="listProfile"></param>
  362. /// <returns></returns>
  363. public static bool LineIntersectPolygon(this Line line, List<Curve> listProfile)
  364. {
  365. bool blnRtn = false;
  366. foreach (Curve curve in listProfile)
  367. {
  368. if (curve == null) return false;
  369. blnRtn = curve.IsIntersection(line);
  370. if (blnRtn)
  371. {
  372. break;
  373. }
  374. }
  375. return blnRtn;
  376. }
  377. /// <summary>
  378. /// 等分点的中点
  379. /// </summary>
  380. /// <param name="line"></param>
  381. /// <param name="intCount"></param>
  382. /// <returns></returns>
  383. public static List<XYZ> GetCountPoints(this Line line, int intCount)
  384. {
  385. List<XYZ> listRtn = new List<XYZ>();
  386. XYZ[] pts = line.GetDividePoints(intCount);
  387. for (int i = 0; i < pts.Length - 1; i++)
  388. {
  389. listRtn.Add(pts[i].MiddlePoint(pts[i + 1]));
  390. }
  391. return listRtn;
  392. }
  393. /// <summary>
  394. /// 共线下,IsUnite=true,返回合并曲线;IsUnite=false 返回相离曲线
  395. /// </summary>
  396. public static Line CombinDisjiont(this Line curve1, Line curve2, bool isUnite, double tolerance = 0)
  397. {
  398. isUnite = !isUnite;
  399. if (null == curve2 || !curve1.IsBound || !curve2.IsBound || !curve1.IsOnCurve(curve2)) return null;
  400. Curve temp = curve1.SameDirection(curve2) ? curve2 : curve2.Reverse();
  401. if (curve1.IsOnCurve(temp.StartPoint())) return null; //两曲线不相离返回null
  402. XYZ startPoint1 = curve1.StartPoint(), endPoint1 = curve1.EndPoint();
  403. XYZ startPoint2 = temp.StartPoint(), endPoint2 = temp.EndPoint();
  404. XYZ start, end;
  405. if (endPoint1.DistanceTo(startPoint2) > endPoint1.DistanceTo(endPoint2)) //curve2在curve1顺方向
  406. {
  407. start = isUnite ? startPoint1 : endPoint1;
  408. end = isUnite ? endPoint2 : startPoint2;
  409. }
  410. else //curve2在curve1逆方向
  411. {
  412. start = isUnite ? startPoint2 : endPoint2;
  413. end = isUnite ? endPoint1 : startPoint1;
  414. }
  415. return Line.CreateBound(start, end);
  416. }
  417. /// <summary>
  418. /// 合并两条线段
  419. /// </summary>
  420. /// <param name="line1"></param>
  421. /// <param name="line2"></param>
  422. /// <param name="tolerance"></param>
  423. /// <returns></returns>
  424. public static Line CombineLine(this Line line1, Line line2, double tolerance = 0.0)
  425. {
  426. return line1.CombineLineNew(line2, true, tolerance);
  427. }
  428. /// <summary>
  429. /// 合并两条线段,IsUnite=false时,仅返回重叠部分曲线,
  430. /// </summary>
  431. /// <param name="line1"></param>
  432. /// <param name="line2"></param>
  433. /// <param name="isUnite"></param>
  434. /// <param name="tolerance"></param>
  435. /// <returns></returns>
  436. public static Line CombineLine(this Line line1, Line line2, bool isUnite, double tolerance = 0.0)
  437. {
  438. if ((line1.IsBound && line2.IsBound) && line1.IsParallel(line2, 0.0, false))
  439. {
  440. Line curve = line1.Direction.IsEqual(line2.Direction, 0.0) ? line2 : line2.Reverse().GetLine();
  441. XYZ first = null;
  442. if (line1.IsContain(curve.StartPoint(), tolerance))
  443. {
  444. first = isUnite ? line1.StartPoint() : curve.StartPoint();
  445. }
  446. else if (curve.IsContain(line1.StartPoint(), tolerance))
  447. {
  448. first = isUnite ? curve.StartPoint() : line1.StartPoint();
  449. }
  450. XYZ second = null;
  451. if (line1.IsContain(curve.EndPoint(), tolerance))
  452. {
  453. second = isUnite ? line1.EndPoint() : curve.EndPoint();
  454. }
  455. else if (curve.IsContain(line1.EndPoint(), tolerance))
  456. {
  457. second = isUnite ? curve.EndPoint() : line1.EndPoint();
  458. }
  459. if (((first != null) && (second != null)) && !first.IsEqual(second, 0.0))
  460. {
  461. return CreateBoundExt(first, second);
  462. }
  463. }
  464. return null;
  465. }
  466. /// <summary>
  467. /// 合并两条线段(共线,不相交也可合并)
  468. /// </summary>
  469. /// <param name="line1"></param>
  470. /// <param name="line2"></param>
  471. /// <param name="tolerance"></param>
  472. /// <returns></returns>
  473. public static Line CombineLine2(this Line line1, Line line2, double tolerance = 0.0)
  474. {
  475. if ((line1.IsBound && line2.IsBound) && line1.IsParallel(line2, 0.0, false))
  476. {
  477. List<XYZ> list = new List<XYZ> {
  478. line1.StartPoint(),
  479. line1.EndPoint(),
  480. line2.StartPoint(),
  481. line2.EndPoint()
  482. };
  483. list.Sort(new XyzComparer(false));
  484. return CreateBoundExt(list[0], list[list.Count - 1]);
  485. }
  486. return null;
  487. }
  488. public static Line CombineLineNew(this Line line1, Line line2, bool isUnite, double tolerance = 0.0)
  489. {
  490. Predicate<Line> match = null;
  491. Predicate<Line> predicate2 = null;
  492. if ((!line1.IsBound || !line2.IsBound) || !line1.IsParallel(line2, 0.0, false))
  493. {
  494. return null;
  495. }
  496. if ((!line2.IsContain(line1.StartPoint(), tolerance) && !line2.IsContain(line1.EndPoint(), tolerance)) && (!line1.IsContain(line2.StartPoint(), tolerance) && !line1.IsContain(line2.EndPoint(), tolerance)))
  497. {
  498. return null;
  499. }
  500. if (line1.IsInLine(line2, tolerance))
  501. {
  502. return line2;
  503. }
  504. if (line2.IsInLine(line1, tolerance))
  505. {
  506. return line1;
  507. }
  508. List<Line> list = new List<Line>();
  509. Line item = CreateBoundExt(line1.StartPoint(), line2.StartPoint());
  510. if (item != null)
  511. {
  512. list.Add(item);
  513. }
  514. Line line3 = CreateBoundExt(line1.StartPoint(), line2.EndPoint());
  515. if (line3 != null)
  516. {
  517. list.Add(line3);
  518. }
  519. Line line4 = CreateBoundExt(line1.EndPoint(), line2.StartPoint());
  520. if (line4 != null)
  521. {
  522. list.Add(line4);
  523. }
  524. Line line5 = CreateBoundExt(line1.EndPoint(), line2.EndPoint());
  525. if (line5 != null)
  526. {
  527. list.Add(line5);
  528. }
  529. if (!isUnite)
  530. {
  531. if (match == null)
  532. {
  533. match = p => p.IsInLine(line1, tolerance) && p.IsInLine(line2, tolerance);
  534. }
  535. Line line = list.Find(match);
  536. if ((line != null) && !line.SameDirection(line1))
  537. {
  538. line = line.Reverse().GetLine();
  539. }
  540. return (line ?? line1);
  541. }
  542. if (predicate2 == null)
  543. {
  544. predicate2 = p => line1.IsInLine(p, tolerance) && line2.IsInLine(p, tolerance);
  545. }
  546. Line line7 = list.Find(predicate2);
  547. if ((line7 != null) && !line7.SameDirection(line1))
  548. {
  549. line7 = line7.Reverse().GetLine();
  550. }
  551. return (line7 ?? line1);
  552. }
  553. /// <summary>
  554. /// Line1包含line2
  555. /// </summary>
  556. /// <param name="line1"></param>
  557. /// <param name="line2"></param>
  558. /// <param name="tolerance"></param>
  559. /// <returns></returns>
  560. public static bool IsInLine(this Line line1, Line line2, double tolerance = 0.0)
  561. {
  562. return (line2.IsContain(line1.StartPoint(), tolerance) && line2.IsContain(line1.EndPoint(), tolerance));
  563. }
  564. /// <summary>
  565. /// 创建直线
  566. /// </summary>
  567. /// <param name="pt1"></param>
  568. /// <param name="pt2"></param>
  569. /// <returns></returns>
  570. public static Line CreateBoundExt(XYZ pt1, XYZ pt2)
  571. {
  572. if (!pt1.IsEqual(pt2, ExternalDataWrapper.Current.App.ShortCurveTolerance))
  573. {
  574. return Line.CreateBound(pt1, pt2);
  575. }
  576. return null;
  577. }
  578. /// <summary>
  579. /// 射线转直线
  580. /// </summary>
  581. /// <param name="line"></param>
  582. /// <returns></returns>
  583. public static Line LineToBound(this Line line)
  584. {
  585. if (line.IsBound)
  586. {
  587. return line;
  588. }
  589. return line.Origin.PointToLine(line.Direction, 1000 * 1000);
  590. }
  591. /// <summary>
  592. /// 创建模型线
  593. /// </summary>
  594. /// <param name="line"></param>
  595. /// <returns></returns>
  596. public static ModelCurve NewModelCurve(this Line line, SketchPlane sp = null)
  597. {
  598. line = line.LineToBound();
  599. if (sp == null)
  600. {
  601. XYZ axis = XYZ.BasisZ;
  602. XYZ vecX = line.Direction;
  603. if (axis.IsEqual(vecX) || axis.IsEqual(-vecX))
  604. {
  605. axis = XYZ.BasisY;
  606. }
  607. XYZ normal = vecX.CrossProduct(vecX.VectorRotate(axis, Math.PI / 2));
  608. Plane p = RevitApiBaseDll.NewPlane(normal, line.StartPoint());
  609. sp = SketchPlane.Create(ExternalDataWrapper.Current.Doc, p);
  610. }
  611. return ExternalDataWrapper.Current.DocCreater.NewModelCurve(line, sp);
  612. }
  613. /// <summary>
  614. /// 返回共平面
  615. /// </summary>
  616. public static Plane Plane(this Line line, Curve curve, Document doc)
  617. {
  618. Plane plane = null;
  619. if (curve is Line)
  620. {
  621. Line line1 = line.Clone() as Line;
  622. line1.MakeUnbound();
  623. Line line2 = curve.Clone() as Line;
  624. line2.MakeUnbound();
  625. if (line1.GetIntersections(line2).Count > 0)
  626. {
  627. XYZ xVec = line1.Direction;
  628. XYZ yVec = line2.Direction.CrossProduct(xVec).CrossProduct(xVec);
  629. plane = RevitApiBaseDll.NewPlane(xVec, yVec, line1.Origin);
  630. }
  631. }
  632. else if (curve is Arc)
  633. {
  634. Arc arc = curve as Arc;
  635. plane = RevitApiBaseDll.NewPlane(arc.Normal, arc.Center);
  636. if (!(line.Direction.AngleTo(arc.Normal).IsEqual(Math.PI / 2) && plane.IsInside(line.Origin)))
  637. {
  638. plane = null;
  639. }
  640. }
  641. return plane;
  642. }
  643. /// <summary>
  644. /// 消除revit的轴网偏差警告
  645. /// </summary>
  646. /// <param name="line"></param>
  647. /// <returns></returns>
  648. public static Line AdjustLine(this Line line)
  649. {
  650. if (line == null)
  651. {
  652. return null;
  653. }
  654. double tolerance = 0.01;
  655. XYZ xyz = line.StartPoint();
  656. XYZ xyz2 = line.EndPoint();
  657. XYZ vec = line.UnitVector();
  658. double num2 = Math.PI/4;
  659. double num3 = Math.PI/2;
  660. double num4 = vec.QuadrantAngle(null);
  661. double num5 = num4 % num2;
  662. double num6 = num4 % num3;
  663. if (!num6.IsZero(0.0) && !num6.IsEqual(num3, tolerance))
  664. {
  665. if (!num5.IsZero(0.0) && !num5.IsEqual(num2, tolerance))
  666. {
  667. goto Label_012F;
  668. }
  669. for (int i = 0; i < 4; i++)
  670. {
  671. double num10 = (num3 * i) + num2;
  672. if (num4.IsEqual(num10, tolerance))
  673. {
  674. num4 = num10;
  675. break;
  676. }
  677. }
  678. }
  679. else
  680. {
  681. for (int j = 0; j < 5; j++)
  682. {
  683. double num8 = num3 * j;
  684. if (num4.IsEqual(num8, tolerance))
  685. {
  686. num4 = num8;
  687. break;
  688. }
  689. }
  690. xyz2 = xyz + ((XYZ)(XYZ.BasisX.VectorRotate(num4) * line.Length));
  691. goto Label_012F;
  692. }
  693. xyz2 = xyz + ((XYZ)(XYZ.BasisX.VectorRotate(num4) * line.Length));
  694. Label_012F:
  695. return Line.CreateBound(xyz, xyz2);
  696. }
  697. /// <summary>
  698. /// 两条线所在直线是否共线
  699. /// </summary>
  700. /// <param name="line"></param>
  701. /// <param name="line2"></param>
  702. /// <returns></returns>
  703. public static bool IsSameLine(this Line line, Line line2)
  704. {
  705. Line tempLine = line.Clone() as Line;
  706. tempLine.MakeUnbound();
  707. return tempLine.Distance(line2.StartPoint()).IsEqual(0) &&
  708. tempLine.Distance(line2.EndPoint()).IsEqual(0, 0.02);
  709. }
  710. /// <summary>
  711. /// 两条线所在直线是否共线
  712. /// </summary>
  713. /// <param name="line"></param>
  714. /// <param name="line2"></param>
  715. /// <returns></returns>
  716. public static bool IsSameLine(this Curve line, Line line2)
  717. {
  718. line.MakeUnbound();
  719. return line.Distance(line2.StartPoint()).IsEqual(0) && line.Distance(line2.EndPoint()).IsEqual(0);
  720. }
  721. /// <summary>
  722. /// 直线打断于一点
  723. /// </summary>
  724. /// <returns></returns>
  725. public static List<Line> BreakOnPoint(this Line line, XYZ pt, double dTol)
  726. {
  727. List<Line> list = new List<Line>();
  728. if (pt.IsEndPoint(line, dTol))
  729. {
  730. list.Add(line);
  731. return list;
  732. }
  733. if (pt.IsInLine(line, dTol))
  734. {
  735. XYZ second = line.StartPoint();
  736. XYZ xyz2 = line.EndPoint();
  737. list.Add(pt.NewLine(second));
  738. list.Add(pt.NewLine(xyz2));
  739. return list;
  740. }
  741. list.Add(line);
  742. return list;
  743. }
  744. /// <summary>
  745. /// 相交的类型
  746. /// </summary>
  747. /// <param name="line"></param>
  748. /// <param name="line2"></param>
  749. /// <param name="dTol"></param>
  750. /// <returns></returns>
  751. public static int GetInterCrossStyle(this Line line, Line line2, double dTol = 0)
  752. {
  753. int intRtn = 0;
  754. XYZ pt = line.GetIntersection(line2, dTol);
  755. if (pt != null)
  756. {
  757. List<Line> listLine1 = line.BreakOnPoint(pt, dTol);
  758. List<Line> listLine2 = line2.BreakOnPoint(pt, dTol);
  759. if (listLine1.Count == 1 && listLine2.Count == 1 && listLine1[0].Direction.IsEqual(listLine2[0].Direction))
  760. {
  761. //一型
  762. intRtn = 1;
  763. }
  764. else
  765. {
  766. //2-L型、3-T型、4-十字型
  767. intRtn = listLine1.Count + listLine2.Count;
  768. }
  769. }
  770. return intRtn;
  771. }
  772. /// <summary>
  773. /// 相交的类型
  774. /// </summary>
  775. /// <param name="line"></param>
  776. /// <param name="line2"></param>
  777. /// <param name="line3"></param>
  778. /// <param name="dTol"></param>
  779. /// <returns></returns>
  780. public static int GetInterCrossStyle(this Line line, Line line2, Line line3, double dTol = 0)
  781. {
  782. int intRtn = 0;
  783. XYZ pt1 = line.GetIntersection(line2);
  784. XYZ pt2 = line.GetIntersection(line3);
  785. if (pt1 != null && pt2 != null && pt1.IsEqual(pt2, dTol))
  786. {
  787. List<Line> listLine1 = line.BreakOnPoint(pt1, dTol);
  788. List<Line> listLine2 = line2.BreakOnPoint(pt1, dTol);
  789. List<Line> listLine3 = line3.BreakOnPoint(pt1, dTol);
  790. //3-T型、4-十字型
  791. intRtn = listLine1.Count + listLine2.Count + listLine3.Count;
  792. }
  793. return intRtn;
  794. }
  795. /// <summary>
  796. /// 返回交点
  797. /// </summary>
  798. /// <param name="line1"></param>
  799. /// <param name="line2"></param>
  800. /// <param name="tolerance"></param>
  801. /// <returns></returns>
  802. public static XYZ GetIntersection(this Line line1, Line line2, bool isToUnBound = false)
  803. {
  804. XYZ pt = null;
  805. if (isToUnBound)
  806. {
  807. Curve lineClone1 = line1.Clone();
  808. lineClone1.MakeUnbound();
  809. Curve lineClone2 = line2.Clone();
  810. lineClone2.MakeUnbound();
  811. lineClone1.GetIntersection(lineClone2, out pt, 0);
  812. }
  813. else
  814. {
  815. line1.GetIntersection(line2, out pt, 0);
  816. }
  817. return pt;
  818. }
  819. }
  820. public enum SysLineStyles
  821. {
  822. Unknown,
  823. /// <summary>
  824. /// 超出
  825. /// </summary>
  826. LinesBeyond,
  827. /// <summary>
  828. /// 架空线
  829. /// </summary>
  830. OverheadLines,
  831. /// <summary>
  832. /// 已拆除
  833. /// </summary>
  834. DemolishedLines,
  835. /// <summary>
  836. /// 隐藏
  837. /// </summary>
  838. HiddenLines,
  839. /// <summary>
  840. /// 中心线
  841. /// </summary>
  842. CenterLines,
  843. /// <summary>
  844. /// 宽线
  845. /// </summary>
  846. CurvesWideLines,
  847. /// <summary>
  848. /// 细线
  849. /// </summary>
  850. CurvesThinLines,
  851. /// <summary>
  852. /// 线
  853. /// </summary>
  854. GenericLines,
  855. /// <summary>
  856. /// 隐藏线
  857. /// </summary>
  858. LinesHiddenLines,
  859. /// <summary>
  860. /// 中粗线
  861. /// </summary>
  862. CurvesMediumLines
  863. }
  864. }