static void LengthAngleDependenceExperiment( VertexConstraints constraint1, VertexConstraints constraint2, string fileName) { const int GeneratedPointCount = 100000; List <Vector> lengthAnglePoints = new List <Vector>(); double maxLength = 0; for (int i = 0; i < GeneratedPointCount; ++i) { double randomX1 = constraint1.MinCoord.X + Random.Double() * (constraint1.MaxCoord.X - constraint1.MinCoord.X); double randomY1 = constraint1.MinCoord.Y + Random.Double() * (constraint1.MaxCoord.Y - constraint1.MinCoord.Y); double randomX2 = constraint2.MinCoord.X + Random.Double() * (constraint2.MaxCoord.X - constraint2.MinCoord.X); double randomY2 = constraint2.MinCoord.Y + Random.Double() * (constraint2.MaxCoord.Y - constraint2.MinCoord.Y); Vector vector1 = new Vector(randomX1, randomY1); Vector vector2 = new Vector(randomX2, randomY2); if (vector1 == vector2) { continue; } Vector diff = vector2 - vector1; double length = diff.Length; double angle = Vector.AngleBetween(Vector.UnitX, diff); lengthAnglePoints.Add(new Vector(length, angle)); maxLength = Math.Max(maxLength, length); } //ShapeConstraints constraintSet = ShapeConstraints.CreateFromConstraints( // CreateSimpleShapeModel1(), // new[] { constraint1, constraint2 }, // new[] { new EdgeConstraints(1) }, // 1, // 1); BoxSetLengthAngleConstraints lengthAngleConstraints = BoxSetLengthAngleConstraints.FromVertexConstraints(constraint1, constraint2, 2, 0); const int lengthImageSize = 360; const int angleImageSize = 360; double lengthScale = (lengthImageSize - 20) / maxLength; //Image2D<bool> myAwesomeMask = new Image2D<bool>(lengthImageSize, angleImageSize); //LengthAngleSpaceSeparatorSet myAwesomeSeparator = new LengthAngleSpaceSeparatorSet(constraint1, constraint2); //for (int i = 0; i < lengthImageSize; ++i) // for (int j = 0; j < angleImageSize; ++j) // { // double length = i / lengthScale; // double angle = MathHelper.ToRadians(j - 180.0); // if (myAwesomeSeparator.IsInside(length, angle)) // myAwesomeMask[i, j] = true; // } using (Bitmap image = new Bitmap(lengthImageSize, angleImageSize)) using (Graphics graphics = Graphics.FromImage(image)) { graphics.Clear(Color.White); // Draw generated points for (int i = 0; i < lengthAnglePoints.Count; ++i) { DrawLengthAngle(graphics, Pens.Black, lengthAnglePoints[i].X, lengthAnglePoints[i].Y, lengthScale, 1); } // Draw estimated ranges foreach (BoxLengthAngleConstraints child in lengthAngleConstraints.ChildConstraints) { DrawLengthAngleConstraintBox(graphics, Pens.Green, child, lengthScale); } DrawLengthAngleConstraintBox(graphics, new Pen(Color.Red, 2), lengthAngleConstraints.OverallRange, lengthScale); // Draw constraint corners //for (int i = 0; i < 4; ++i) //{ // for (int j = 0; j < 4; ++j) // { // Vector diff = constraint2.Corners[j] - constraint1.Corners[i]; // DrawLengthAngle(diff.Length, Vector.AngleBetween(Vector.UnitX, diff), lengthScale, 5, graphics, Pens.Blue); // } //} // Draw my awesome separation lines //for (int i = 0; i < lengthImageSize - 1; ++i) // for (int j = 0; j < lengthImageSize - 1; ++j) // { // bool border = false; // border |= myAwesomeMask[i, j] != myAwesomeMask[i + 1, j]; // border |= myAwesomeMask[i, j] != myAwesomeMask[i, j + 1]; // border |= myAwesomeMask[i, j] != myAwesomeMask[i + 1, j + 1]; // if (border) // image.SetPixel(i, j, Color.Orange); // } //graphics.DrawString( // String.Format("Max length is {0:0.0}", maxLength), SystemFonts.DefaultFont, Brushes.Green, 5, 5); image.Save(fileName); } }
private static void TestEdgeLimitsCommonImpl( VertexConstraints constraint1, VertexConstraints constraint2, out Range lengthRange, out Range angleRange) { BoxSetLengthAngleConstraints lengthAngleConstraints = BoxSetLengthAngleConstraints.FromVertexConstraints(constraint1, constraint2, 3, 0); GeneralizedDistanceTransform2D transform = new GeneralizedDistanceTransform2D( new Range(0, 35), new Range(-Math.PI * 2, Math.PI * 2), new Size(2000, 2000)); AllowedLengthAngleChecker allowedLengthAngleChecker = new AllowedLengthAngleChecker(constraint1, constraint2, transform, 1, 0); lengthRange = lengthAngleConstraints.LengthBoundary; angleRange = lengthAngleConstraints.AngleBoundary; const int insideCheckCount = 1000; for (int i = 0; i < insideCheckCount; ++i) { Vector edgePoint1 = constraint1.MinCoord + new Vector( Random.Double() * (constraint1.MaxCoord.X - constraint1.MinCoord.X), Random.Double() * (constraint1.MaxCoord.Y - constraint1.MinCoord.Y)); Vector edgePoint2 = constraint2.MinCoord + new Vector( Random.Double() * (constraint2.MaxCoord.X - constraint2.MinCoord.X), Random.Double() * (constraint2.MaxCoord.Y - constraint2.MinCoord.Y)); Vector vec = edgePoint2 - edgePoint1; double length = vec.Length; double angle = Vector.AngleBetween(Vector.UnitX, vec); const double tolerance = 1e-10; Assert.IsTrue(lengthAngleConstraints.InRange(length, tolerance, angle, tolerance)); Assert.IsTrue(lengthAngleConstraints.OverallRange.InRange(length, tolerance, angle, tolerance)); Assert.IsTrue(allowedLengthAngleChecker.IsAllowed(length, angle)); } const int outsideCheckCount = 1000; for (int i = 0; i < outsideCheckCount; ++i) { Vector edgePoint1 = constraint1.MinCoord + new Vector( (Random.Double() * 2 - 0.5) * (constraint1.MaxCoord.X - constraint1.MinCoord.X), (Random.Double() * 2 - 0.5) * (constraint1.MaxCoord.Y - constraint1.MinCoord.Y)); Vector edgePoint2 = constraint2.MinCoord + new Vector( (Random.Double() * 2 - 0.5) * (constraint2.MaxCoord.X - constraint2.MinCoord.X), (Random.Double() * 2 - 0.5) * (constraint2.MaxCoord.Y - constraint2.MinCoord.Y)); Vector vec = edgePoint2 - edgePoint1; double length = vec.Length; double angle = Vector.AngleBetween(Vector.UnitX, vec); // We've generated too long edge if (length > transform.RangeX.Right) { continue; } bool definitelyOutside = !lengthAngleConstraints.OverallRange.InRange(length, 1e-6, angle, 1e-6); Assert.IsTrue(!definitelyOutside || !allowedLengthAngleChecker.IsAllowed(length, angle)); Assert.IsTrue(!definitelyOutside || !lengthAngleConstraints.InRange(length, 1e-6, angle, 1e-6)); } }