private Point FindBestNeighbour(Point point, int index) { Point bestNeighbour = point; double area = BoundaryPolygon.Area(); for (int x = -1; x < 2; x++) { for (int y = -1; y < 2; y++) { Point neighbour = new Point(point.X + x, point.Y + y); Polygon copy = new Polygon(BoundaryPolygon); if (!copy.Vertices.Any(v => v.Equals(neighbour))) { copy.ExchangeVertexAt(index, neighbour); double ar = copy.Area(); if (0 < ar && ar < area && copy.IsPolygon() && copy.Encloses(PointsToEnclose)) { if (copy.Encloses(PointsToEnclose)) { bestNeighbour = neighbour; area = copy.Area(); } } } } } return(bestNeighbour); }
public HillClimbingAlgorithm(Polygon boundaryPolygon) { BoundaryPolygon = boundaryPolygon; var sth = BoundaryPolygon.GetVisualSides(); CurrentArea = boundaryPolygon.Area(); }
public override void Execute() { if (building != null) { building.gfa = 0; building.footPrint = 0; building.floorCount = Mathf.RoundToInt(building.height / 4); //Debug.Log("Shape Count="+inputs.shapes.Count); foreach (ShapeObject so in inputs.shapes) { Extrusion ext = null; Polygon pg = null; try { ext = (Extrusion)so.meshable; pg = ext.polygon; } catch { } float area = pg.Area(); if (ext != null) { if (so.Position.y == building.ground) building.footPrint += area; } int count = Mathf.RoundToInt(ext.height / 4); building.gfa += count * area; } //Debug.Log("post cal gfa=" + building.gfa); } outputs.shapes = inputs.shapes; }
public void TransformSegment_UnitSquare_LastSegment() { var s = 0.5; var square = new Polygon(new List <Vector3>() { new Vector3(s, s, 0), new Vector3(-s, s, 0), new Vector3(-s, -s, 0), new Vector3(s, -s, 0) }); var t = new Transform(1, 0, 0); square.TransformSegment(t, 3); var segment = square.Segments()[3]; // Confirm vertices are correctly moved Assert.Equal(s + 1, segment.Start.X); Assert.Equal(-s, segment.Start.Y); Assert.Equal(s + 1, segment.End.X); Assert.Equal(s, segment.End.Y); // Confirm area has been correctly modified Assert.True(square.Area().ApproximatelyEquals(2)); }
public void CorrectPolygon() { Point[] points = { new Point(0, 0), new Point(100, 0), new Point(100, 100), new Point(0, 100) }; Polygon polygon = new Polygon(points); Assert.Equal(10000, polygon.Area()); }
/// <summary> /// Calculates measurements - length/perimeter, area, latitude, and/or longitude - /// for the input geometry /// </summary> /// <param name="geometry"></param> private void MeasureGeometry(Geometry geometry) { if (geometry is MapPoint) // Update latitude and longitude { // If necessary, transform the point to WGS 84 to get latitude // and longitude in decimal degrees MapPoint point = (MapPoint)geometry; if (point.SpatialReference.IsWebMercator()) { point = new WebMercator().ToGeographic(geometry) as MapPoint; } point = (MapPoint)Geometry.NormalizeCentralMeridian(point); Latitude = point.Y; Longitude = point.X; } else if (geometry is Polyline) // Update length { Length = ((Polyline)geometry).Length(); } else if (geometry is Polygon || geometry is Envelope) // Update area { // If geometry is an envelope, convert it to a polygon Polygon polygon = geometry is Polygon ? (Polygon)geometry : ((Envelope)geometry).ToPolygon(); Length = polygon.Perimeter(); Area = polygon.Area(); } else { throw new Exception(Strings.MeasureUnsupportedGeometryType); } }
public static void Main() { Console.WriteLine(@"Program that calculates the perimeter and the area of given polygon (not necessarily convex) consisting of n floating-point coordinates in the 2D plane."); Console.WriteLine("Write n = "); int n = int.Parse(Console.ReadLine()); List <Point> listOfPoints = new List <Point> { }; for (int i = 0; i < n; i++) { Console.WriteLine("Write coordinates of point {0}:", i + 1); string line = Console.ReadLine(); string[] list = line.Split(' '); double x = double.Parse(list[0]); double y = double.Parse(list[1]); Point p = new Point(x, y); listOfPoints.Add(p); } Polygon polygon = new Polygon(listOfPoints); double perimeter = polygon.Perimeter(); double area = polygon.Area(); Console.WriteLine("The area is {0:0.00} and the perimeter is {1:0.00}.", area, perimeter); }
public void FitMost() { var polygon = new Polygon ( new[] { Vector3.Origin, new Vector3(4.0, 0.0), new Vector3(4.0, 4.0), new Vector3(0.0, 4.0) } ); var within = new Polygon( new[] { new Vector3(3.0, 3.0), new Vector3(5.0, 3.0), new Vector3(5.0, 6.0), new Vector3(3.0, 6.0), }); polygon = polygon.FitMost(within); Assert.Equal(4.0, polygon.Vertices.Count); Assert.Equal(1.0, polygon.Area()); }
public void ComputePowerDiagram(int maxIterations, float threashold = 1f) { completedIterations = 0; float num = 0f; foreach (Site site in sites) { if (site.poly == null) { throw new Exception("site poly is null for [" + site.id + "]" + site.position); } site.position = site.poly.Centroid(); } int num2 = 0; while (true) { if (num2 > maxIterations) { return; } try { UpdateWeights(sites); ComputePD(); } catch (Exception ex) { Debug.LogError("Error [" + num + "] iters " + completedIterations + "/" + maxIterations + " Exception:" + ex.Message + "\n" + ex.StackTrace); return; } num = 0f; foreach (Site site2 in sites) { float num3 = (site2.poly != null) ? site2.poly.Area() : 0.1f; float num4 = site2.weight / weightSum * bounds.Area(); num = Mathf.Max(Mathf.Abs(num3 - num4) / num4, num); } if (num < threashold) { break; } completedIterations++; num2++; } completedIterations = num2; }
public SmSpace FindClosestUnitType(Polygon poly, List <SmSpace> distinctSpaces) { if (poly != null && distinctSpaces != null) { return(distinctSpaces.OrderBy(s => Math.Abs(s.designArea - poly.Area())).First()); } return(null); }
/// <summary> /// Attempts to scale up a Polygon until coming within the tolerance percentage of the target area. /// </summary> /// <param name="polygon">Polygon to scale.</param> /// <param name="area">Target area of the Polygon.</param> /// <param name="tolerance">Area total tolerance.</param> /// <param name="origin">Alignment location for final Polygon.</param> /// <param name="within">Polygon acting as a constraining outer boundary.</param> /// <param name="among">List of Polygons to avoid intersecting.</param> /// <returns> /// A new Polygon. /// </returns> public static Polygon ExpandToArea(this Polygon polygon, double area, double ratio, double tolerance = 0.1, Orient origin = Orient.C, Polygon within = null, List <Polygon> among = null) { if (polygon.IsClockWise()) { polygon = polygon.Reversed(); } if (Math.Abs(polygon.Area() - area) <= Math.Abs(tolerance * area)) { return(polygon); } var position = polygon.Compass().PointBy(origin); Polygon tryPoly = Shaper.RectangleByArea(area, ratio); tryPoly = tryPoly.MoveFromTo(tryPoly.Compass().PointBy(origin), position); double tryArea = tryPoly.Area(); do { var t = new Transform(); t.Scale(tryArea / area, tryPoly.Compass().PointBy(origin)); tryPoly = tryPoly.TransformedPolygon(t); if (within != null && tryPoly.Intersects(within)) { var tryPolys = within.Intersection(tryPoly); if (tryPolys != null && tryPolys.Count > 0) { tryPoly = tryPolys.First(); } } if (among != null && tryPoly.Intersects(among)) { var tryPolys = Shaper.Differences(tryPoly.ToList(), among); if (tryPolys != null && tryPolys.Count > 0) { tryPoly = tryPolys.First(); } } tryArea = tryPoly.Area(); }while (!Shaper.NearEqual(tryPoly.Area(), area, tolerance * area) && !Shaper.NearEqual(tryPoly.Area(), tryArea, tolerance)); return(tryPoly); }
public void PolygonComplexArea() { Polygon hat = new Polygon(new[] { new Point(1, 1), new Point(0, 2), new Point(-1, 1) }); Assert.AreEqual(1 * 1 * 1, hat.Area()); Polygon roof = new Polygon(new[] { new Point(0, 0), new Point(0, 100), new Point(100, 100), new Point(0, 200), new Point(-100, 100) }); Assert.AreEqual(1.5 * 100 * 100, roof.Area()); }
static public List <float> getLightIntensity(List <Vector2> localSp, float radius, bool doOffset) { if (doOffset) { radius *= 2; } Voronoi voronoi = new Voronoi(localSp, null, new Rect(0, 0, radius, radius), out List <bool> removeIndex); List <Site> siteList = voronoi._sites._sites; List <float> areas = new List <float>(); float totalArea = 0; foreach (Site site in siteList) { List <Vector2> vertices = new List <Vector2>(); for (int i = 0; i < site.edges.Count; i++) { Edge edge = site.edges[i]; if (edge.visible) { LineSegment lineSeg = edge.VoronoiEdge(); if (lineSeg.p0 == null || lineSeg.p1 == null) { continue; } vertices.Add(lineSeg.p0.Value); } } Polygon voronoiRegion = new Polygon(vertices); float tmpArea = voronoiRegion.Area(); areas.Add(tmpArea); totalArea += tmpArea; } if (totalArea == 0) { return(null); } List <float> intensityList = new List <float>(); for (int i = 0, j = 0; i < removeIndex.Count; i++) { if (removeIndex[i]) { intensityList.Add(0); } else { intensityList.Add(areas[j] / totalArea); j++; } } return(intensityList); }
public void TestPoly() { //var poly = new Polygon(new[] { new Point(1, 1), new Point(2, 1), new Point(2, 2), new Point(1, 2) }); //Assert.AreEqual(1, poly.Area()); //Assert.AreEqual(-1,poly.Area(true)); var poly2 = new Polygon((new[] { new Point(1, 2), new Point(2, 2), new Point(2, 1), new Point(1, 1) })); Assert.AreEqual(1, poly2.Area()); Assert.AreEqual(1, poly2.Area(true)); var poly3 = new Polygon((new[] { new Point(1, 2), new Point(1.5, 3.0), new Point(2, 2), new Point(2, 1), new Point(1, 1) }).Reverse()); Assert.AreEqual(1.5, poly3.Area()); Assert.AreEqual(1.5, poly3.Area(true)); poly2.points.Insert(1, new Point(1.5, 3.0)); Assert.AreEqual(1.5, poly2.Area()); Assert.AreEqual(1.5, poly2.Area(true)); }
public override void Execute() { //outMeshables.Clear(); int rqEdgeCount = (int)(((ParameterGroup)paramGroups["EdgeCount"]).parameters[0].Value); int rqArea = (int)(((ParameterGroup)paramGroups["Area"]).parameters[0].Value); //outputs.shapes.Clear(); List <ShapeObject> pass = new List <ShapeObject>(); List <ShapeObject> fail = new List <ShapeObject>(); foreach (ShapeObject so in inputs.shapes) { Meshable m = so.meshable; int edgeCount; float area; if (m.GetType() == typeof(SGGeometry.Extrusion)) { Extrusion etx = (Extrusion)m; edgeCount = etx.polygon.vertices.Length; area = etx.polygon.Area(); } else if (m.GetType() == typeof(SGGeometry.Polygon)) { Polygon pg = (Polygon)m; edgeCount = pg.vertices.Length; area = pg.Area(); } else { area = -1; edgeCount = -1; } bool meetEdgeCount = false; if (rqEdgeCount < 0) { meetEdgeCount = true; } if (rqEdgeCount == edgeCount) { meetEdgeCount = true; } if (area >= rqArea && meetEdgeCount) { pass.Add(so); } else { fail.Add(so); } } UpdateOutputShapes(pass); }
static void Main() { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; int numberOfPoints = int.Parse(Console.ReadLine()); Polygon p = new Polygon(); for (int i = 0; i < numberOfPoints; i++) { string[] pair = Console.ReadLine().Split(); p.Points.Add(new Point(double.Parse(pair[0]), double.Parse(pair[1]))); } Console.WriteLine("perimeter = {0:F2}\narea = {1:F2}", p.Perimeter(), p.Area()); }
void Update() { if (trans.Count > 2) { List <Vector2> vertices = new List <Vector2>(); foreach (Transform tran in trans) { vertices.Add(new Vector2(tran.position.x, tran.position.y)); } Polygon voronoiRegion = new Polygon(vertices); print(voronoiRegion.Area()); } }
public static void Initialization_Empty_Creates_Empty_Object() { Polygon polygon = new Polygon(); Assert.AreEqual(0, polygon.Angles.Count); Assert.AreEqual(0, polygon.Points.Count); Assert.AreEqual(0, polygon.Sides.Count); Assert.AreEqual(GeometryLibrary.ZeroTolerance, polygon.Tolerance); Assert.IsNull(polygon.Name); Assert.IsFalse(polygon.IsHole); Assert.AreEqual(0, polygon.Centroid.X); Assert.AreEqual(0, polygon.Centroid.Y); Assert.AreEqual(0, polygon.Area()); Assert.AreEqual(0, polygon.Xo()); Assert.AreEqual(0, polygon.Yo()); }
public void Area() { var a = Polygon.Rectangle(1.0, 1.0); Assert.Equal(1.0, a.Area()); var b = Polygon.Rectangle(2.0, 2.0); Assert.Equal(4.0, b.Area()); var p1 = Vector3.Origin; var p2 = Vector3.XAxis; var p3 = new Vector3(1.0, 1.0); var p4 = new Vector3(0.0, 1.0); var pp = new Polygon(new[] { p1, p2, p3, p4 }); Assert.Equal(1.0, pp.Area()); }
public void PolygonConvexArea() { Polygon square = new Polygon(new[] { new Point(0, 0), new Point(0, 100), new Point(100, 100), new Point(100, 0) }); Assert.AreEqual(100 * 100, square.Area()); Polygon kickedRect = new Polygon(new[] { new Point(0, 0), new Point(0, 200), new Point(150, 300), new Point(150, 100) }); Assert.AreEqual(150 * 200, kickedRect.Area()); Polygon triangle = new Polygon(new[] { new Point(0, 0), new Point(0, 100), new Point(100, 100) }); Assert.AreEqual(100 * 100 / 2, triangle.Area()); Polygon rectMorePoints = new Polygon(new[] { new Point(0, 0), new Point(100, 0), new Point(200, 0), new Point(200, 100), new Point(100, 100), new Point(0, 100) }); Assert.AreEqual(200 * 100, rectMorePoints.Area()); }
public void TransformSegment_UnitSquare_OutOfRange() { var s = 0.5; var square = new Polygon(new List <Vector3>() { new Vector3(s, s, 0), new Vector3(-s, s, 0), new Vector3(-s, -s, 0), new Vector3(s, -s, 0) }); var t = new Transform(1, 1, 0); square.TransformSegment(t, 100); // Confirm area has remained the same Assert.True(square.Area().ApproximatelyEquals(1)); }
private static IEnumerable <Polygon> CreateAlleys(Polygon block, float minArea, float gridChaos, float sizeChaos, Func <Polygon, float> emptyProbabilityFunc, bool split, int levels = 0) { Vector2 point = Vector2.Zero; var length = float.MinValue; block.ForEachEdge((p1, p2, index) => { var len = (p1 - p2).Length; if (len > length) { length = len; point = p1; } }); var spread = 0.8f * gridChaos; var ratio = (1 - spread) / 2 + (float)Rnd.NextDouble() * spread; // Trying to keep buildings rectangular even in chaotic wards var angleSpread = (float)(Math.PI / 6 * gridChaos * (block.Area() < minArea * 4 ? 0 : 1)); var angle = ((float)Rnd.NextDouble() - 0.5f) * angleSpread; var halves = block.Bisect(point, ratio, angle, split ? Alley : 0f); var buildings = new List <Polygon>(); foreach (var half in halves) { if (half.Area() < minArea * Math.Pow(2, 4 * sizeChaos * (Rnd.NextDouble() - 0.5f)) || levels > 5) { if (!Rnd.NextBool(emptyProbabilityFunc(half))) { buildings.Add(half); } } else { buildings.AddRange(CreateAlleys(half, minArea, gridChaos, sizeChaos, emptyProbabilityFunc, half.Area() > minArea / (Rnd.NextDouble() * Rnd.NextDouble()), levels + 1)); } } return(buildings); }
public void TestCountArea_FromDataSource() { // Access the data String[] rawPoints = Convert.ToString(TestContext.DataRow["PointPosition"]).Split(';'); List <Point2D> points = new List <Point2D>(); foreach (String point in rawPoints) { String[] position = point.Split('|'); int x = Convert.ToInt32(position[0]); int y = Convert.ToInt32(position[1]); points.Add(new Point2D(x, y)); } double expectedArea = Convert.ToDouble(TestContext.DataRow["ExpectedArea"]); Polygon p = new Polygon(points.ToArray()); double actual = p.Area(); Assert.AreEqual(expectedArea, actual, 0.001); }
/// <summary> /// Constructor creates a Room by a Polygon and a positive height. /// </summary> public Room(Polygon polygon, double height) { polygon = polygon.IsClockWise() ? polygon.Reversed() : polygon; height = height.NearEqual(0.0) ? 1.0 : Math.Round(Math.Abs(height), PRECISION); Color = Palette.White; Department = ""; DesignArea = polygon.Area(); var compass = polygon.Compass(); DesignRatio = compass.SizeX / compass.SizeY; Height = height; Name = ""; Number = ""; Perimeter = polygon; Elevation = Math.Round(polygon.Vertices.First().Z, PRECISION); Placed = false; Suite = ""; SuiteID = ""; UniqueID = Guid.NewGuid().ToString(); }
public static void param70() { Console.WriteLine("Введите количество вершин: "); int n = readNum(); Console.WriteLine("Введите попарно значения координат для вершин: "); TPoint[] mas = new TPoint[n]; for (int i = 0; i < mas.Length; i++) { Console.Write("X: "); mas[i].X = readNum(); Console.Write("Y: "); mas[i].Y = readNum(); } Polygon p = new Polygon(mas); Console.WriteLine("Площадь фигуры: " + p.Area()); Console.WriteLine("Нажмите любую клавишу для продолжения..."); Console.ReadKey(); }
public void polygonTest(int xform_code) { Polygon test_path = new Polygon(); for (int i = 0; i < N_test_poly; i++) { test_path.Add(transformPoint(new IntPoint(test_poly_points[i][0], test_poly_points[i][1]), xform_code)); } Polygon tpoly = new Polygon(test_path); // check area // double found_area = tpoly.Area(); double ref_area = RefArea * transform_area_factor[xform_code & 15]; Assert.IsTrue(found_area == ref_area); // check center of mass IntPoint found_com = tpoly.CenterOfMass(); IntPoint ref_com = transformPoint(RefCenterOfMass, xform_code); Assert.IsTrue(Math.Abs(found_com.X - ref_com.X) <= 1); Assert.IsTrue(Math.Abs(found_com.Y - ref_com.Y) <= 1); // check 'inside' points. for (int i = 0; i < test_points_inside.Length / test_points_inside[0].Length; i++) { IntPoint tpt = transformPoint(new IntPoint(test_points_inside[i][0], test_points_inside[i][1]), xform_code); Assert.IsTrue(tpoly.Inside(tpt)); } for (int i = 0; i < test_points_outside.Length / test_points_outside[0].Length; i++) { IntPoint tpt = transformPoint(new IntPoint(test_points_outside[i][0], test_points_outside[i][1]), xform_code); Assert.IsFalse(tpoly.Inside(tpt)); } }
private static Polygon AddRoomFromCell(Grid2d cell, string department, Material material, Model model, double circulationWidth, double height) { var polygons = cell.GetTrimmedCellGeometry(); if (polygons.Count() == 0) { return(null); } var polygon = (Polygon)polygons.First(); var newPoints = polygon.Vertices.ToList().ToArray().Shrink(circulationWidth); var newPolygon = new Polygon(newPoints); var solid = new Elements.Geometry.Solids.Extrude(newPolygon, height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); var room = new Room((Polygon)newPolygon, Vector3.ZAxis, "Section 1", "100", department, "100", newPolygon.Area(), 1.0, 0, 0, 10, newPolygon.Area(), new Transform(), material, geomRep, false, System.Guid.NewGuid(), "Section 1"); model.AddElement(room); return(newPolygon); }
public static void Main() { // changing the culture of the program in American standard so the decimal point character is . Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Console.Write("Enter number of points: "); int n = int.Parse(Console.ReadLine()); Console.WriteLine("Enter point coordinates on a line, separated by a space -> x y"); Point[] point = new Point[n]; for (int i = 0; i < n; i++) { Console.Write("Enter point[{0}]: ", i + 1); string[] pointCoordinates = Console.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); point[i] = new Point() { X = double.Parse(pointCoordinates[0]), Y = double.Parse(pointCoordinates[1]) }; } double calcPerimeter = Polygon.Perimeter(point, n); double calcArea = Polygon.Area(point, n); Console.WriteLine("\nperimeter = {0:F2}", calcPerimeter); Console.WriteLine("area = {0:F2}", calcArea); }
private static List <Polygons> AccumulateDownPolygons(ConfigSettings config, List <Polygons> inputPolys, List <Polygons> allPartOutlines) { int numLayers = inputPolys.Count; long nozzleSize = config.ExtrusionWidth_um; long areaToTryAndBe = 20 * 20 * nozzleSize * nozzleSize; // 10 x 10 mm approximately (assuming .5 nozzle) List <Polygons> allDownOutlines = CreateEmptyPolygons(numLayers); for (int layerIndex = numLayers - 2; layerIndex >= 0; layerIndex--) { Polygons aboveRequiredSupport = inputPolys[layerIndex + 1]; // get all the polygons above us Polygons accumulatedAbove = allDownOutlines[layerIndex + 1].CreateUnion(aboveRequiredSupport); // experimental and not working well enough yet if (config.MinimizeSupportColumns) { // reduce the amount of support material used for (int i = accumulatedAbove.Count - 1; i >= 0; i--) { Polygon polygon = accumulatedAbove[i]; double polyArea = polygon.Area(); if (polyArea > areaToTryAndBe) { Polygons offsetPolygons = new Polygons() { polygon }.Offset(-config.ExtrusionWidth_um / 2); accumulatedAbove.RemoveAt(i); foreach (Polygon polyToAdd in offsetPolygons) { accumulatedAbove.Insert(i, polyToAdd); } } else if (polyArea < areaToTryAndBe * .9) { Polygons offsetPolygons = new Polygons() { polygon }.Offset(config.ExtrusionWidth_um / 2); accumulatedAbove.RemoveAt(i); foreach (Polygon polyToAdd in offsetPolygons) { accumulatedAbove.Insert(i, polyToAdd); } } } } // add in the support on this level Polygons curRequiredSupport = inputPolys[layerIndex]; Polygons totalSupportThisLayer = accumulatedAbove.CreateUnion(curRequiredSupport); // remove the solid polygons on this level Polygons remainingAbove = totalSupportThisLayer.CreateDifference(allPartOutlines[layerIndex]); allDownOutlines[layerIndex] = Clipper.CleanPolygons(remainingAbove, cleanDistance_um); } return(allDownOutlines); }
/// <summary> /// The ViewRadius function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A ViewRadiusOutputs instance containing computed results and the model with any new elements.</returns> public static ViewRadiusOutputs Execute(Dictionary <string, Model> inputModels, ViewRadiusInputs input) { inputModels.TryGetValue("Envelope", out Model envelopeModel); inputModels.TryGetValue("location", out Model contextBuildingsModel); if (envelopeModel == null) { throw new Exception("Unable to find envelope model."); } if (contextBuildingsModel == null) { throw new Exception("Unable to find Location model."); } var allEnvelopes = envelopeModel.AllElementsOfType <Envelope>(); var allContextBuildings = contextBuildingsModel.AllElementsOfType <Mass>(); if (!allEnvelopes.Any()) { throw new Exception("No envelopes in model."); } if (!allContextBuildings.Any()) { throw new Exception("No context buildings in model."); } var height = input.Height; var envelopesAtHeight = allEnvelopes.Where(env => height > env.Elevation && height < env.Height + env.Elevation); var model = new Model(); int rayCount = 170; var allFaces = allContextBuildings.SelectMany(b => b.Representation.SolidOperations.Select(s => s.Solid.Faces)); var maxTotalScore = 0.0; var totalScore = 0.0; foreach (var envelope in envelopesAtHeight) { var perimeter = envelope.Profile.Perimeter; var vertexAverage = perimeter.Vertices.Average(); var minRadius = perimeter.Vertices.Select(v => v.DistanceTo(vertexAverage)).Max(); var circle = Polygon.Circle(minRadius, rayCount); var rayDirections = circle.Vertices; var totalRadius = input.MaxRadius + minRadius; maxTotalScore += Math.PI * totalRadius * totalRadius; var heightTransform = new Transform(vertexAverage.X, vertexAverage.Y, height); circle = heightTransform.OfPolygon(circle); var maxCircle = new Circle(heightTransform.Origin, totalRadius); var filteredFaces = filterFaces(allFaces.SelectMany(f => f.Values).ToList(), maxCircle); var rays = rayDirections.Select(i => new Ray(maxCircle.Center, i)); List <Vector3> finalIsovistPoints = new List <Vector3>(); foreach (var ray in rays) { List <Vector3> allResults = new List <Vector3>(); foreach (var face in filteredFaces) { if (Intersects(ray, face, out Vector3 result)) { allResults.Add(result); } } if (allResults.Count > 0) { var resultsOrdered = allResults.OrderBy(r => r.DistanceTo(ray.Origin)); finalIsovistPoints.Add(resultsOrdered.First()); } else { finalIsovistPoints.Add(ray.Origin + ray.Direction.Unitized() * totalRadius); } } var isovist = new Polygon(finalIsovistPoints); totalScore += isovist.Area(); Mesh mesh = CreateMeshFromRays(finalIsovistPoints, maxCircle, rayCount); var isovistElement = new Isovist(mesh); model.AddElement(isovistElement); } var outputs = new ViewRadiusOutputs((totalScore / maxTotalScore) * 100); outputs.model = model; return(outputs); }