public void EllipseArc_Basic() { var o = Point.ByCoordinates(1, 2, 3); var n = Vector.ByCoordinates(2, 3, 4, true); var pl = Autodesk.DesignScript.Geometry.Plane.ByOriginNormal(o, n); var ellipseArc = EllipseArc.ByPlaneRadiiAngles(pl, 10, 5, 45, 90); var revitCurve = ellipseArc.ToRevitType(false); Assert.NotNull(revitCurve); Assert.IsAssignableFrom <Autodesk.Revit.DB.Ellipse>(revitCurve); var revitEllipse = (Autodesk.Revit.DB.Ellipse)revitCurve; revitEllipse.GetEndParameter(0).ToDegrees().ShouldBeApproximately(ellipseArc.StartAngle); revitEllipse.GetEndParameter(1).ToDegrees().ShouldBeApproximately(ellipseArc.StartAngle + ellipseArc.SweepAngle); revitEllipse.GetEndPoint(0).ShouldBeApproximately(ellipseArc.StartPoint); revitEllipse.GetEndPoint(1).ShouldBeApproximately(ellipseArc.EndPoint); revitEllipse.Length.ShouldBeApproximately(ellipseArc.Length); // ClosestPointTo fails in ProtoGeometry var tessPts = revitEllipse.Tessellate().Select(x => x.ToPoint(false)); //assert the tesselation is very close to original curve foreach (var pt in tessPts) { var closestPt = ellipseArc.ClosestPointTo(pt); Assert.Less(closestPt.DistanceTo(pt), 1e-6); } }
private static Autodesk.DesignScript.Geometry.Curve Convert(Autodesk.Revit.DB.Ellipse crv) { var isFullEllipse = !crv.IsBound || Math.Abs(Math.Abs(crv.GetEndParameter(1) - crv.GetEndParameter(0)) - 2 * Math.PI) < 1e-6; if (isFullEllipse) { return (Autodesk.DesignScript.Geometry.Ellipse.ByOriginVectors( crv.Center.ToPoint(false), (crv.XDirection * crv.RadiusX).ToVector(false), (crv.YDirection * crv.RadiusY).ToVector(false))); } double startParam; var span = Math.Abs(crv.GetEndParameter(0) - crv.GetEndParameter(1)).ToDegrees(); startParam = crv.GetEndParameter(0).ToDegrees(); using (var pl = Plane.ByOriginXAxisYAxis(crv.Center.ToPoint(false), crv.XDirection.ToVector(), crv.YDirection.ToVector())) { return(EllipseArc.ByPlaneRadiiAngles(pl, crv.RadiusX, crv.RadiusY, startParam, span)); } }
protected override (Curve boundary, List <Curve> holes) CreateBaseCurves() { Curve boundary = null; Point[] points; if (IsCurved) { var holes = new List <Curve>(); var boundaryCurves = new List <Curve>(); var arcHeight = Math.Min(Length, Width / 2); using (Plane arcCenter = Plane.ByOriginNormal( Point.ByCoordinates(Width / 2, arcHeight), Vector.ZAxis())) { boundaryCurves.Add(EllipseArc.ByPlaneRadiiAngles(arcCenter, Width / 2, arcHeight, 180, 180)); if (UsesDepth) { if (arcHeight < Length) { // Top of U has straight parts. points = new[] { Point.ByCoordinates(Width, arcHeight), Point.ByCoordinates(Width, Length), Point.ByCoordinates(Width - Depth, Length), Point.ByCoordinates(Width - Depth, arcHeight) }; boundaryCurves.Add(PolyCurve.ByPoints(points)); points.ForEach(p => p.Dispose()); } else { points = new[] { Point.ByCoordinates(Width, Length), Point.ByCoordinates(Width - Depth, Length) }; // Top of U has no straight parts. boundaryCurves.Add(Line.ByStartPointEndPoint(points[0], points[1])); points.ForEach(p => p.Dispose()); } boundaryCurves.Add(EllipseArc.ByPlaneRadiiAngles(arcCenter, (Width / 2) - Depth, arcHeight - Depth, 0, -180)); if (arcHeight < Length) { // Top of U has straight parts. points = new[] { Point.ByCoordinates(Depth, arcHeight), Point.ByCoordinates(Depth, Length), Point.ByCoordinates(0, Length), Point.ByCoordinates(0, arcHeight) }; boundaryCurves.Add(PolyCurve.ByPoints(points)); points.ForEach(p => p.Dispose()); } else { // Top of U has no straight parts. points = new[] { Point.ByCoordinates(Depth, Length), Point.ByCoordinates(0, Length) }; boundaryCurves.Add(Line.ByStartPointEndPoint(points[0], points[1])); points.ForEach(p => p.Dispose()); } } else { // U has no interior. if (arcHeight < Length) { points = new[] { Point.ByCoordinates(Width, arcHeight), Point.ByCoordinates(Width, Length), Point.ByCoordinates(0, Length), Point.ByCoordinates(0, arcHeight) }; boundaryCurves.Add(PolyCurve.ByPoints(points)); points.ForEach(p => p.Dispose()); } else { points = new[] { Point.ByCoordinates(Width, Length), Point.ByCoordinates(0, Length) }; boundaryCurves.Add(Line.ByStartPointEndPoint(points[0], points[1])); points.ForEach(p => p.Dispose()); } } } boundary = PolyCurve.ByJoinedCurves(boundaryCurves); } else { // Straight U if (UsesDepth) { points = new[] { Point.ByCoordinates(0, 0), Point.ByCoordinates(Width, 0), Point.ByCoordinates(Width, Length), Point.ByCoordinates(Width - Depth, Length), Point.ByCoordinates(Width - Depth, Depth), Point.ByCoordinates(Depth, Depth), Point.ByCoordinates(Depth, Length), Point.ByCoordinates(0, Length) }; boundary = PolyCurve.ByPoints(points, connectLastToFirst: true); points.ForEach(p => p.Dispose()); } else { // Solid straight U (rectangle) points = new[] { Point.ByCoordinates(0, 0), Point.ByCoordinates(Width, 0), Point.ByCoordinates(Width, Length), Point.ByCoordinates(0, Length) }; boundary = PolyCurve.ByPoints(points, connectLastToFirst: true); points.ForEach(p => p.Dispose()); } } return(boundary, default); }
protected override (Curve boundary, List <Curve> holes) CreateBaseCurves() { // The D is pointing "down" so that it matches with the U. var holes = new List <Curve>(); var boundaryCurves = new List <Curve>(); var arcHeight = Math.Min( Length - (UsesDepth ? Depth : 0), Width / 2); Point[] points; if (IsCurved) { Plane arcCenter = null; using (var point = Point.ByCoordinates(Width / 2, arcHeight)) using (var zAxis = Vector.ZAxis()) { arcCenter = Plane.ByOriginNormal(point, zAxis); } boundaryCurves.Add(EllipseArc.ByPlaneRadiiAngles(arcCenter, Width / 2, arcHeight, 180, 180)); if (arcHeight < Length) { points = new[] { Point.ByCoordinates(Width, arcHeight), Point.ByCoordinates(Width, Length), Point.ByCoordinates(0, Length), Point.ByCoordinates(0, arcHeight) }; // Outside of D has a square back. boundaryCurves.Add(PolyCurve.ByPoints(points)); points.ForEach(p => p.Dispose()); } else { points = new[] { Point.ByCoordinates(Width, Length), Point.ByCoordinates(0, Length) }; // Outside of D is half an ellipse (or circle). boundaryCurves.Add(Line.ByStartPointEndPoint(points[0], points[1])); points.ForEach(p => p.Dispose()); } if (UsesDepth) { var curves = new List <Curve> { EllipseArc.ByPlaneRadiiAngles(arcCenter, (Width / 2) - Depth, arcHeight - Depth, 0, -180) }; if (arcHeight < Length - Depth) { points = new[] { Point.ByCoordinates(Depth, arcHeight), Point.ByCoordinates(Depth, Length - Depth), Point.ByCoordinates(Width - Depth, Length - Depth), Point.ByCoordinates(Width - Depth, arcHeight) }; curves.Add(PolyCurve.ByPoints(points)); points.ForEach(p => p.Dispose()); } else { points = new[] { Point.ByCoordinates(Depth, arcHeight), Point.ByCoordinates(Width - Depth, arcHeight) }; curves.Add(Line.ByStartPointEndPoint(points[0], points[1])); points.ForEach(p => p.Dispose()); } holes.Add(PolyCurve.ByJoinedCurves(curves)); curves.ForEach(x => x.Dispose()); } arcCenter.Dispose(); } else { // Faceted D. double baseWidth = Width * Math.Tan(Math.PI / 8); double sideWidth = baseWidth * arcHeight / (2 * Width); points = new[] { Point.ByCoordinates(Width, Length), Point.ByCoordinates(0, Length), Point.ByCoordinates(0, arcHeight - sideWidth), Point.ByCoordinates((Width - baseWidth) / 2, 0), Point.ByCoordinates((Width + baseWidth) / 2, 0), Point.ByCoordinates(Width, arcHeight - sideWidth) }; boundaryCurves.Add(PolyCurve.ByPoints(points, connectLastToFirst: true)); points.ForEach(p => p.Dispose()); if (UsesDepth) { double angleA = Math.Atan2(2 * (arcHeight - sideWidth), Width - baseWidth); double offsetBaseWidth = baseWidth - (2 * Depth / Math.Tan((Math.PI - angleA) / 2)); double offsetSideWidth = sideWidth - (Depth / Math.Tan((angleA / 2) + (Math.PI / 4))); points = new[] { Point.ByCoordinates(Width - Depth, Length - Depth), Point.ByCoordinates(Width - Depth, arcHeight - offsetSideWidth), Point.ByCoordinates((Width + offsetBaseWidth) / 2, Depth), Point.ByCoordinates((Width - offsetBaseWidth) / 2, Depth), Point.ByCoordinates(Depth, arcHeight - offsetSideWidth), Point.ByCoordinates(Depth, Length - Depth) }; holes.Add(PolyCurve.ByPoints(points, connectLastToFirst: true)); points.ForEach(p => p.Dispose()); } } var boundary = PolyCurve.ByJoinedCurves(boundaryCurves); return(boundary, holes); }