public void AssertThat_FromWorld_ToWorld_AreIdentityFunction() { //Generate a random load of points var rand = new Random(); var points = new List <Vector2>(); for (int i = 0; i < 20; i++) { points.Add(rand.RandomNormalVector().XZ() * (float)rand.NextDouble() * 50); } //Calculate OABR var oabr = OABR.Fit(points); //Draw it var svg = new SvgBuilder(2); var hull = points.ConvexHull().ToArray(); svg.Outline(hull, "green"); svg.Outline((IReadOnlyList <Vector2>)oabr.Points(new Vector2[4])); foreach (var vector2 in points) { svg.Circle(vector2, 1, oabr.Contains(vector2) ? "red" : "blue"); } Console.WriteLine(svg.ToString()); //Assert that every point lies within the bounds foreach (var vector2 in points) { var trans = oabr.FromWorld(vector2); var world = oabr.ToWorld(trans); Assert.IsTrue(vector2.TolerantEquals(world, 0.001f), string.Format("Expected {0} and {1} to be equal", vector2, world)); } }
internal static OABR FitOabb(Parcel parcel, float nonOptimalityChance, float maximumNonOptimality, Func <double> random) { Contract.Requires(parcel != null); Contract.Requires(random != null); //Generate a set of OABBs, order by size var oabbs = OABR.Fittings(parcel.Points()).OrderBy(a => a.Area).ToArray(); //Now select an OABB from this list, with the first (smallest) being the most likely var selected = 0; for (var i = 1; i < oabbs.Length; i++) { //Do not allow the area ratio between optimal and selected to go over the non optimality limit if (oabbs[i].Area / (oabbs[0]).Area > maximumNonOptimality) { break; } //We're not breaking the non optimality limit, so what's the chance of selecting this? var chance = Math.Pow(nonOptimalityChance, i); selected = random() < chance ? i : selected; } return(oabbs[selected]); }
public void AssertThat_AllPointsLiesInBounds_WithRandomShape() { //Generate a random load of points var rand = new Random(); var points = new List <Vector2>(); for (int i = 0; i < 20; i++) { points.Add(rand.RandomNormalVector().XZ() * (float)rand.NextDouble() * 50); } //Calculate OABR var oabr = OABR.Fit(points); //Draw it var svg = new SvgBuilder(2); var hull = points.ConvexHull().ToArray(); svg.Outline(hull, "green"); svg.Outline((IReadOnlyList <Vector2>)oabr.Points(new Vector2[4])); foreach (var vector2 in points) { svg.Circle(vector2, 1, oabr.Contains(vector2) ? "red" : "blue"); } Console.WriteLine(svg.ToString()); //Assert that every point lies within the bounds Assert.IsTrue(points.All(p => oabr.Contains(p))); }
public float AspectRatio() { var oabb = OABR.Fit(Points()); var extents = oabb.Max - oabb.Min; var ratio = Math.Max(extents.X, extents.Y) / Math.Min(extents.X, extents.Y); return(ratio); }
private IEnumerable <Parcel> Split(Parcel parcel, OABR oabb, Vector2 sliceDirection, Func <double> random, INamedDataCollection metadata) { Contract.Requires(parcel != null); Contract.Requires(random != null); Contract.Requires(metadata != null); var extent = (oabb.Max - oabb.Min) / 2; var point = oabb.Middle + Math.Max(extent.X, extent.Y) * sliceDirection.Perpendicular() * _splitPoint.SelectFloatValue(random, metadata); var slices = parcel.Points().SlicePolygon(new Ray2(point, sliceDirection)); return(slices.Select(a => ToParcel(parcel, a))); }
protected BasePolygonRegion(IReadOnlyList <Side> shape, OABR oabr) { Contract.Requires(shape != null); Contract.Requires(shape.Count >= 3); _shape = shape; _bounds = BoundingRectangle.CreateFromPoints(Points); _oabr = oabr; Area = Points.Area(); OabrAreaError = _oabr.Area - Area; }
public void AssertThat_CornerPoints_AreEqualToInputPoints_ForRectangularShape() { var points = new[] { new Vector2(10, 10), new Vector2(10, -10), new Vector2(-10, -10), new Vector2(-10, 10), }; var oabr = OABR.Fit(points); var corners = oabr.Points(); for (var i = 0; i < points.Length; i++) { Assert.AreEqual(points[i], corners[i]); } }
protected BasePolygonRegion(IReadOnlyList <Side> shape) : this(shape, OABR.Fit(shape.Select(a => a.Start))) { Contract.Requires(shape != null); Contract.Requires(shape.Count >= 3); }
protected BasePolygonRegionContracts(IReadOnlyList <Side> shape, OABR oabr) : base(shape, oabr) { }