Buckets:
| // | |
| // (C) Copyright 2003-2019 by Autodesk, Inc. | |
| // | |
| // Permission to use, copy, modify, and distribute this software in | |
| // object code form for any purpose and without fee is hereby granted, | |
| // provided that the above copyright notice appears in all copies and | |
| // that both that copyright notice and the limited warranty and | |
| // restricted rights notice below appear in all supporting | |
| // documentation. | |
| // | |
| // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. | |
| // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF | |
| // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. | |
| // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE | |
| // UNINTERRUPTED OR ERROR FREE. | |
| // | |
| // Use, duplication, or disclosure by the U.S. Government is subject to | |
| // restrictions set forth in FAR 52.227-19 (Commercial Computer | |
| // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) | |
| // (Rights in Technical Data and Computer Software), as applicable. | |
| // | |
| namespace Revit.SDK.Samples.CreateBeamSystem.CS | |
| { | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Text; | |
| using System.Drawing; | |
| using Autodesk.Revit.DB; | |
| /// <summary> | |
| /// utility class contains some methods deal with 3D arithmetic | |
| /// </summary> | |
| public class GeometryUtil | |
| { | |
| /// <summary> | |
| /// The Application Creation object is used to create new instances of utility objects. | |
| /// </summary> | |
| public static Autodesk.Revit.Creation.Application CreApp; | |
| /// <summary> | |
| /// judge whether two XYZs are equal | |
| /// </summary> | |
| /// <param name="pnt1">first XYZ</param> | |
| /// <param name="pnt2">second XYZ</param> | |
| /// <returns>is equal</returns> | |
| public static bool CompareXYZ(Autodesk.Revit.DB.XYZ pnt1, Autodesk.Revit.DB.XYZ pnt2) | |
| { | |
| return (MathUtil.CompareDouble(pnt1.X, pnt2.X) && | |
| MathUtil.CompareDouble(pnt1.Y, pnt2.Y) && | |
| MathUtil.CompareDouble(pnt1.Z, pnt2.Z)); | |
| } | |
| /// <summary> | |
| /// sorted lines end to end to make a closed loop profile | |
| /// if input lines can't make a profile, null will return | |
| /// </summary> | |
| /// <param name="originLines">lines to be sorted</param> | |
| /// <returns>sorted lines which can make a closed loop profile</returns> | |
| public static List<Line> SortLines(List<Line> originLines) | |
| { | |
| // at least 3 lines to form the profile | |
| if (originLines.Count < 3) | |
| { | |
| return null; | |
| } | |
| List<Line> lines = new List<Line>(originLines); | |
| List<Line> result = new List<Line>(); | |
| // sorted line end to end in order | |
| result.Add(lines[0]); | |
| Autodesk.Revit.DB.XYZ intersectPnt = lines[0].GetEndPoint(1); | |
| lines[0] = null; | |
| for (int i = 0; i < lines.Count; i++) | |
| { | |
| for (int j = 1; j < lines.Count; j++) | |
| { | |
| if (null == lines[j]) | |
| { | |
| continue; | |
| } | |
| if (CompareXYZ(lines[j].GetEndPoint(0), intersectPnt)) | |
| { | |
| result.Add(lines[j]); | |
| intersectPnt = lines[j].GetEndPoint(1); | |
| lines[j] = null; | |
| break; | |
| } | |
| else if (CompareXYZ(lines[j].GetEndPoint(1), intersectPnt)) | |
| { | |
| Autodesk.Revit.DB.XYZ startPnt = lines[j].GetEndPoint(1); | |
| Autodesk.Revit.DB.XYZ endPnt = lines[j].GetEndPoint(0); | |
| lines[j] = null; | |
| Line inversedLine = Line.CreateBound(startPnt, endPnt); | |
| result.Add(inversedLine); | |
| intersectPnt = inversedLine.GetEndPoint(1); | |
| break; | |
| } | |
| } | |
| } | |
| // there is line doesn't included in the closed loop | |
| if (result.Count != lines.Count) | |
| { | |
| return null; | |
| } | |
| // the last point in the sorted loop is same to the firs point | |
| if (!CompareXYZ(intersectPnt, result[0].GetEndPoint(0))) | |
| { | |
| return null; | |
| } | |
| // make sure there is only one closed region enclosed by the closed loop | |
| for (int i = 0; i < result.Count - 2; i++) | |
| { | |
| for (int j = i + 2; j < result.Count; j++) | |
| { | |
| if (i == 0 && j == (result.Count - 1)) | |
| { | |
| continue; | |
| } | |
| Line2D line1 = ConvertTo2DLine(result[i]); | |
| Line2D line2 = ConvertTo2DLine(result[j]); | |
| int count = Line2D.FindIntersection(line1, line2); | |
| // line shouldn't intersect with lines which not adjoin to it | |
| if (count > 0) | |
| { | |
| return null; | |
| } | |
| } | |
| } | |
| return result; | |
| } | |
| /// <summary> | |
| /// judge whether the lines are in the same horizontal plane | |
| /// </summary> | |
| /// <param name="lines">lines to be judged</param> | |
| /// <returns>is in the same horizontal plane</returns> | |
| public static bool InSameHorizontalPlane(List<Line> lines) | |
| { | |
| // all the Z coordinate of lines' start point and end point should be equal | |
| Autodesk.Revit.DB.XYZ firstPnt = lines[0].GetEndPoint(0); | |
| for (int i = 0; i < lines.Count; i++) | |
| { | |
| if (!MathUtil.CompareDouble(lines[i].GetEndPoint(0).Z, firstPnt.Z) || | |
| !MathUtil.CompareDouble(lines[i].GetEndPoint(1).Z, firstPnt.Z)) | |
| { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| /// <summary> | |
| /// use the X and Y coordinate of 3D Line to new a Line2D instance | |
| /// </summary> | |
| /// <param name="line">3D Line</param> | |
| /// <returns>2D Line</returns> | |
| private static Line2D ConvertTo2DLine(Line line) | |
| { | |
| PointF pnt1 = new PointF((float)line.GetEndPoint(0).X, (float)line.GetEndPoint(0).Y); | |
| PointF pnt2 = new PointF((float)line.GetEndPoint(1).X, (float)line.GetEndPoint(1).Y); | |
| return new Line2D(pnt1, pnt2); | |
| } | |
| } | |
| /// <summary> | |
| /// utility class contains some methods deal with some general arithmetic | |
| /// </summary> | |
| public class MathUtil | |
| { | |
| /// <summary> | |
| /// the minimum double used to compare | |
| /// </summary> | |
| public const double Double_Epsilon = 0.00001; | |
| /// <summary> | |
| /// the minimum positive float used to compare to as zero | |
| /// </summary> | |
| public const float Float_Epsilon = 0.00001f; | |
| /// <summary> | |
| /// forbidden default constructor | |
| /// </summary> | |
| private MathUtil() | |
| { | |
| } | |
| /// <summary> | |
| /// compare whether 2 double is equal using internal precision | |
| /// </summary> | |
| /// <param name="d1">first value</param> | |
| /// <param name="d2">second value</param> | |
| /// <returns>is Equal</returns> | |
| public static bool CompareDouble(double d1, double d2) | |
| { | |
| return Math.Abs(d1 - d2) < Double_Epsilon; | |
| } | |
| /// <summary> | |
| /// dot multiply two vector | |
| /// </summary> | |
| /// <param name="pnt1">first vector</param> | |
| /// <param name="pnt2">second vector</param> | |
| /// <returns>result</returns> | |
| public static float Dot(PointF pnt1, PointF pnt2) | |
| { | |
| return pnt1.X * pnt2.X + pnt1.Y * pnt2.Y; | |
| } | |
| /// <summary> | |
| /// multiply a float with a vector | |
| /// </summary> | |
| /// <param name="f">float value</param> | |
| /// <param name="pnt">vector</param> | |
| /// <returns>result</returns> | |
| public static PointF Multiply(float f, PointF pnt) | |
| { | |
| return new PointF(f * pnt.X, f * pnt.Y); | |
| } | |
| /// <summary> | |
| /// add 2 vector | |
| /// </summary> | |
| /// <param name="f1">first vector</param> | |
| /// <param name="f2">second vector</param> | |
| /// <returns>result</returns> | |
| public static PointF Add(PointF f1, PointF f2) | |
| { | |
| return new PointF(f1.X + f2.X, f1.Y + f2.Y); | |
| } | |
| /// <summary> | |
| /// subtract 2 vector | |
| /// </summary> | |
| /// <param name="f1">first vector</param> | |
| /// <param name="f2">second vector</param> | |
| /// <returns>result</returns> | |
| public static PointF Subtract(PointF f1, PointF f2) | |
| { | |
| return new PointF(f1.X - f2.X, f1.Y - f2.Y); | |
| } | |
| /// <summary> | |
| /// find and calculate the intersection of two interval [u0, u1] and [v0, v1] | |
| /// </summary> | |
| /// <param name="u0">first interval</param> | |
| /// <param name="u1">first interval</param> | |
| /// <param name="v0">second interval</param> | |
| /// <param name="v1">second interval</param> | |
| /// <param name="w">2 intersections</param> | |
| /// <returns>number of intersection</returns> | |
| public static int FindIntersection(float u0, float u1, float v0, float v1, ref float[] w) | |
| { | |
| if (u1 < v0 || u0 > v1) | |
| { | |
| return 0; | |
| } | |
| if (u1 == v0) | |
| { | |
| w[0] = u1; | |
| return 1; | |
| } | |
| if (u0 == v1) | |
| { | |
| w[0] = u0; | |
| return 1; | |
| } | |
| if (u1 > v0) | |
| { | |
| if (u0 < v1) | |
| { | |
| if (u0 < v0) | |
| { | |
| w[0] = v0; | |
| } | |
| else | |
| { | |
| w[0] = u0; | |
| } | |
| if (u1 > v1) | |
| { | |
| w[1] = v1; | |
| } | |
| else | |
| { | |
| w[1] = u1; | |
| } | |
| return 2; | |
| } | |
| else | |
| { | |
| w[0] = u0; | |
| return 1; | |
| } | |
| } | |
| else | |
| { | |
| w[0] = u1; | |
| return 1; | |
| } | |
| } | |
| /// <summary> | |
| /// get the minimum value of 2 float | |
| /// </summary> | |
| /// <param name="f1">first float</param> | |
| /// <param name="f2">second float</param> | |
| /// <returns>minimum float</returns> | |
| public static float GetMin(float f1, float f2) | |
| { | |
| if (f1 < f2) | |
| { | |
| return f1; | |
| } | |
| return f2; | |
| } | |
| /// <summary> | |
| /// get the maximum value of 2 float | |
| /// </summary> | |
| /// <param name="f1">first float</param> | |
| /// <param name="f2">second float</param> | |
| /// <returns>maximum float</returns> | |
| public static float GetMax(float f1, float f2) | |
| { | |
| if (f1 > f2) | |
| { | |
| return f1; | |
| } | |
| return f2; | |
| } | |
| } | |
| } | |
Xet Storage Details
- Size:
- 11 kB
- Xet hash:
- 14000b7f9dc15835ed5b7cd06f67e65674b90a65a89f5fedea0896fe6efcac22
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.