public Circle(Vector center, double radius) : this() { Debug.Assert(radius >= 0); this.Center = center; this.Radius = radius; }
public static Tuple<double, double> LineIntersection(Vector point1, Vector dir1, Vector point2, Vector dir2) { double denominator = Vector.CrossProduct(dir1, dir2); if (Math.Abs(denominator) < 1e-6) return null; double t1 = Vector.CrossProduct(dir2, point1 - point2) / denominator; double t2 = Vector.CrossProduct(dir1, point1 - point2) / denominator; return new Tuple<double, double>(t1, t2); }
public LengthAngleSpaceSeparator( Vector segmentStart, Vector segmentEnd, Vector point, double allowedLength, double allowedAngle, bool swapDirection) { if (allowedAngle < -Math.PI || allowedAngle > Math.PI) throw new ArgumentOutOfRangeException("allowedAngle", "Allowed angle should be in [-pi, pi] range."); if (allowedLength < 0) throw new ArgumentOutOfRangeException("allowedLength", "Allowed length should be positive."); if ((segmentStart - segmentEnd).LengthSquared < 1e-6) throw new ArgumentException("Given segment must have non-zero length!"); double distanceToSegmentSqr, alpha; point.DistanceToSegmentSquared(segmentStart, segmentEnd, out distanceToSegmentSqr, out alpha); Vector zeroAngleVec = segmentStart + (segmentEnd - segmentStart) * alpha - point; this.distanceSqr = zeroAngleVec.LengthSquared; if (this.distanceSqr < 1e-6) { this.singularMode = true; double angle = Vector.AngleBetween(Vector.UnitX, segmentEnd - segmentStart); double minAngle, maxAngle; if (angle < 0) { minAngle = angle; maxAngle = angle + Math.PI; } else { maxAngle = angle; minAngle = angle - Math.PI; } singularModeAngleRange = new Range(minAngle, maxAngle); if (!singularModeAngleRange.Contains(allowedAngle)) singularModeAngleRange = singularModeAngleRange.Invert(); } else { this.singularMode = false; this.angleOffset = -Vector.AngleBetween(Vector.UnitX, zeroAngleVec); double offsetedAllowedAngle = this.OffsetAngle(allowedAngle); if (offsetedAllowedAngle < -Math.PI * 0.5 || offsetedAllowedAngle > Math.PI * 0.5) throw new ArgumentOutOfRangeException("allowedAngle", "After translation to the coordinate system of the given segment, allowed angle must be in [-pi/2, pi/2] range."); this.sign = Math.Sign(this.SeparationValue(allowedLength, offsetedAllowedAngle)); } this.swapDirection = swapDirection; }
public VertexConstraints(Vector minCoord, Vector maxCoord) { Debug.Assert(minCoord.X <= maxCoord.X && minCoord.Y <= maxCoord.Y); this.MinCoord = minCoord; this.MaxCoord = maxCoord; this.corners[0] = new Vector(this.MinCoord.X, this.MinCoord.Y); this.corners[1] = new Vector(this.MinCoord.X, this.MaxCoord.Y); this.corners[2] = new Vector(this.MaxCoord.X, this.MaxCoord.Y); this.corners[3] = new Vector(this.MaxCoord.X, this.MinCoord.Y); this.cornersReadOnly = new ReadOnlyCollection<Vector>(corners); }
public Shape FitToSize(double width, double height) { Vector min = new Vector(Double.PositiveInfinity, Double.PositiveInfinity); Vector max = new Vector(Double.NegativeInfinity, Double.NegativeInfinity); foreach (Vector vertexPosition in vertexPositions) { min.X = Math.Min(min.X, vertexPosition.X); min.Y = Math.Min(min.Y, vertexPosition.Y); max.X = Math.Max(max.X, vertexPosition.X); max.Y = Math.Max(max.Y, vertexPosition.Y); } double widthRatio = width / (max.X - min.X); double heightRatio = height / (max.Y - min.Y); double scale = Math.Min(widthRatio, heightRatio); return this.Scale(scale, min); }
private void SetupAnnealingSegmentationAlgorithm(AnnealingSegmentationAlgorithm algorithm) { algorithm.SolutionFitter.AnnealingProgress += OnAnnealingBasedSegmentatorProgress; if (!String.IsNullOrEmpty(this.segmentationProperties.InitialShape)) { algorithm.StartShape = Shape.LoadFromFile(this.segmentationProperties.InitialShape); } else { double angle = this.segmentationProperties.RootEdgeAngle; Vector rootEdgeDirection = new Vector(Math.Cos(angle), -Math.Sin(angle)); algorithm.StartShape = algorithm.ShapeModel.FitMeanShape( this.segmentedImage.Width, this.segmentedImage.Height, rootEdgeDirection); } this.SetupShapeMutator(algorithm.ShapeMutator); this.SetupAnnealing(algorithm.SolutionFitter); }
public List<VertexConstraints> Split() { // We'll use it to split into non-intersecting sets const double eps = 1e-4; Vector middle = this.MiddleCoord; List<VertexConstraints> result = new List<VertexConstraints>(); if (middle.X != MinCoord.X && middle.Y != MinCoord.Y) result.Add(new VertexConstraints(MinCoord, new Vector(middle.X - eps, middle.Y - eps))); if (middle.Y != MinCoord.Y) result.Add(new VertexConstraints(new Vector(middle.X + eps, MinCoord.Y), new Vector(MaxCoord.X, middle.Y - eps))); if (middle.X != MinCoord.X) result.Add(new VertexConstraints(new Vector(MinCoord.X, middle.Y + eps), new Vector(middle.X - eps, MaxCoord.Y))); result.Add(new VertexConstraints(new Vector(middle.X + eps, middle.Y + eps), MaxCoord)); // We should split at least something Debug.Assert(result.Count >= 2); return result; }
public static ShapeConstraints CreateFromBounds( ShapeStructure structure, Vector coordMin, Vector coordMax, double minEdgeWidth, double maxEdgeWidth) { ShapeConstraints result = new ShapeConstraints(); result.ShapeStructure = structure; result.vertexConstraints = new List<VertexConstraints>(); result.edgeConstraints = new List<EdgeConstraints>(); for (int i = 0; i < structure.VertexCount; ++i) result.vertexConstraints.Add(new VertexConstraints(coordMin, coordMax)); for (int i = 0; i < structure.Edges.Count; ++i) result.edgeConstraints.Add(new EdgeConstraints(minEdgeWidth, maxEdgeWidth)); return result; }
private void AddSeparatorsForPoint(Vector point, VertexConstraints constraint2, bool swapDirection) { this.separatorLists.Add(new List<LengthAngleSpaceSeparator>()); Vector middlePoint = 0.5 * (constraint2.Corners[0] + constraint2.Corners[2]); for (int j = 0; j < 4; ++j) { Vector segmentStart = constraint2.Corners[j]; Vector segmentEnd = constraint2.Corners[(j + 1) % 4]; Vector segmentMiddle = 0.5 * (segmentStart + segmentEnd); Vector allowedPoint = segmentMiddle + (middlePoint - segmentMiddle) * 0.01; Vector allowedVec = allowedPoint - point; double allowedLength = allowedVec.Length; double allowedAngle = Vector.AngleBetween(Vector.UnitX, allowedVec); this.separatorLists[this.separatorLists.Count - 1].Add( new LengthAngleSpaceSeparator(segmentStart, segmentEnd, point, allowedLength, allowedAngle, swapDirection)); } }
private void OnShapeCanvasMouseMove(object sender, MouseEventArgs e) { Point mousePos = e.GetPosition(this.shapeCanvas); if (this.controlledVertexIndex.HasValue) { this.shape.VertexPositions[this.controlledVertexIndex.Value] = new Vector(mousePos.X, mousePos.Y) - this.mouseOffset; } else if (this.controlledEdgeIndex.HasValue) { ShapeEdge edge = this.shape.Structure.Edges[this.controlledEdgeIndex.Value]; double distanceFromEdgeLine = new Vector(mousePos.X, mousePos.Y).DistanceToLine( this.shape.VertexPositions[edge.Index1], this.shape.VertexPositions[edge.Index2]); this.shape.EdgeWidths[this.controlledEdgeIndex.Value] = Math.Max(this.initialEdgeWidth + 2 * (distanceFromEdgeLine - this.initialDistanceFromEdgeLine), 5); } if (this.controlledVertexIndex.HasValue || this.controlledEdgeIndex.HasValue) { this.UpdateShapeControls(); } }
public int WindingNumber(Vector point) { int winding = 0; Vector prev = this.vertices[this.vertices.Count - 1]; for (int i = 0; i < this.vertices.Count; ++i) { Vector cur = this.vertices[i]; if (prev.Y <= point.Y) { if (cur.Y > point.Y && Vector.CrossProduct(prev - point, cur - point) > 0) ++winding; } else { if (cur.Y <= point.Y && Vector.CrossProduct(prev - point, cur - point) < 0) --winding; } prev = cur; } return winding; }
public ShapeLengthAngleRepresentation(ShapeStructure structure, Vector origin, IEnumerable<double> edgeLengths, IEnumerable<double> edgeAngles, IEnumerable<double> edgeWidths) { if (edgeLengths == null) throw new ArgumentNullException("edgeLengths"); if (edgeAngles == null) throw new ArgumentNullException("edgeAngles"); if (edgeWidths == null) throw new ArgumentNullException("edgeWidths"); if (structure == null) throw new ArgumentNullException("structure"); this.edgeLengths = new ExposableCollection<double>(edgeLengths.ToList()); this.edgeAngles = new ExposableCollection<double>(edgeAngles.ToList()); this.edgeWidths = new ExposableCollection<double>(edgeWidths.ToList()); this.Structure = structure; this.Origin = origin; if (this.edgeLengths.Count != this.Structure.Edges.Count) throw new ArgumentException("Edge lengths count should be equal to edge count.", "edgeLengths"); if (this.edgeAngles.Count != this.Structure.Edges.Count) throw new ArgumentException("Edge angles count should be equal to edge count.", "edgeAngles"); if (this.edgeWidths.Count != this.Structure.Edges.Count) throw new ArgumentException("Edge widths count should be equal to edge count.", "edgeWidths"); }
public static double DotProduct(Vector vector1, Vector vector2) { return vector1.X * vector2.X + vector1.Y * vector2.Y; }
public void DistanceToLineSquared(Vector point1, Vector point2, out double distanceSqr, out double alpha) { Vector v = point2 - point1; Vector p = this - point1; alpha = DotProduct(v, p) / v.LengthSquared; distanceSqr = ((point1 + alpha * v) - this).LengthSquared; }
public static double AngleBetween(Vector vector1, Vector vector2) { if (vector1 == vector2) return 0; vector1 = vector1.GetNormalized(); vector2 = vector2.GetNormalized(); double cos = DotProduct(vector1, vector2); double sin = CrossProduct(vector1, vector2); double angle = Math.Atan2(sin, cos); return angle; }
public double DistanceToLine(Vector point1, Vector point2) { return Math.Sqrt(this.DistanceToLineSquared(point1, point2)); }
public double DistanceToLineSquared(Vector point1, Vector point2) { double distanceSqr, alpha; this.DistanceToLineSquared(point1, point2, out distanceSqr, out alpha); return distanceSqr; }
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); } }
public void DistanceToSegmentSquared(Vector segmentStart, Vector segmentEnd, out double distanceSqr, out double alpha) { Vector v = segmentEnd - segmentStart; Vector p = this - segmentStart; alpha = DotProduct(v, p) / v.LengthSquared; if (alpha >= 0 && alpha <= 1) distanceSqr = ((segmentStart + alpha * v) - this).LengthSquared; else if (alpha < 0) distanceSqr = p.LengthSquared; else distanceSqr = (this - segmentEnd).LengthSquared; }
public bool Contains(Vector vector) { return vector.X >= this.MinCoord.X && vector.Y >= this.MinCoord.Y && vector.X <= this.MaxCoord.X && vector.Y <= this.MaxCoord.Y; }
static void PointIsClosestExperiment( Vector point, VertexConstraints point1Constraints, VertexConstraints point2Constraints, string fileName) { Console.WriteLine(string.Format("Doing experiment for {0}", fileName)); Bitmap image = new Bitmap(320, 240); const int iterations = 200000; using (Graphics graphics = Graphics.FromImage(image)) { for (int i = 0; i < iterations; ++i) { Vector point1 = new Vector( point1Constraints.MinCoord.X + (point1Constraints.MaxCoord.X - point1Constraints.MinCoord.X) * Random.Double(), point1Constraints.MinCoord.Y + (point1Constraints.MaxCoord.Y - point1Constraints.MinCoord.Y) * Random.Double()); Vector point2 = new Vector( point2Constraints.MinCoord.X + (point2Constraints.MaxCoord.X - point2Constraints.MinCoord.X) * Random.Double(), point2Constraints.MinCoord.Y + (point2Constraints.MaxCoord.Y - point2Constraints.MinCoord.Y) * Random.Double()); double distanceSqr, alpha; point.DistanceToSegmentSquared(point1, point2, out distanceSqr, out alpha); alpha = MathHelper.Trunc(alpha, 0, 1); Vector closestPoint = point1 + (point2 - point1) * alpha; const float radius = 2; graphics.FillEllipse( Brushes.Green, (float)closestPoint.X - radius, (float)closestPoint.Y - radius, radius * 2, radius * 2); } graphics.DrawRectangle( Pens.Blue, point1Constraints.CoordRectangle.Left, point1Constraints.CoordRectangle.Top, point1Constraints.CoordRectangle.Width, point1Constraints.CoordRectangle.Height); graphics.DrawRectangle( Pens.Blue, point2Constraints.CoordRectangle.Left, point2Constraints.CoordRectangle.Top, point2Constraints.CoordRectangle.Width, point2Constraints.CoordRectangle.Height); graphics.FillEllipse(Brushes.Red, (float)point.X - 2, (float)point.Y - 2, 4, 4); } image.Save(fileName); }
private Image DrawConstraintsOnTopOfImage( Image backgroundImage, float drawSizeRatio, ShapeConstraints shapeConstraints, bool drawVertexConstraints, bool drawMinEdgeWidth, bool drawMaxEdgeWidth, bool drawAverageEdgeWidth) { const float pointRadius = 4; const float lineWidth = 2; Bitmap statusImage = new Bitmap((int)(backgroundImage.Width * drawSizeRatio), (int)(backgroundImage.Height * drawSizeRatio)); using (Graphics graphics = Graphics.FromImage(statusImage)) { graphics.DrawImage(backgroundImage, 0, 0, statusImage.Width, statusImage.Height); if (drawVertexConstraints) { foreach (VertexConstraints vertexConstraint in shapeConstraints.VertexConstraints) { graphics.DrawRectangle( new Pen(Color.Orange, lineWidth), (float)vertexConstraint.MinCoord.X * drawSizeRatio, (float)vertexConstraint.MinCoord.Y * drawSizeRatio, (float)(vertexConstraint.MaxCoord.X - vertexConstraint.MinCoord.X) * drawSizeRatio, (float)(vertexConstraint.MaxCoord.Y - vertexConstraint.MinCoord.Y) * drawSizeRatio); } } foreach (VertexConstraints vertexConstraint in shapeConstraints.VertexConstraints) { graphics.FillEllipse( Brushes.Black, (float)vertexConstraint.MiddleCoord.X * drawSizeRatio - pointRadius, (float)vertexConstraint.MiddleCoord.Y * drawSizeRatio - pointRadius, 2 * pointRadius, 2 * pointRadius); } for (int i = 0; i < shapeConstraints.ShapeStructure.Edges.Count; ++i) { ShapeEdge edge = shapeConstraints.ShapeStructure.Edges[i]; Vector point1 = shapeConstraints.VertexConstraints[edge.Index1].MiddleCoord * drawSizeRatio; Vector point2 = shapeConstraints.VertexConstraints[edge.Index2].MiddleCoord * drawSizeRatio; graphics.DrawLine(new Pen(Color.Black, lineWidth), MathHelper.VecToPointF(point1), MathHelper.VecToPointF(point2)); if (drawMinEdgeWidth || drawMaxEdgeWidth || drawAverageEdgeWidth) { EdgeConstraints edgeConstraint = shapeConstraints.EdgeConstraints[i]; Vector diff = point2 - point1; Vector edgeNormal = (new Vector(diff.Y, -diff.X)).GetNormalized(); if (drawMaxEdgeWidth) { DrawOrientedRectange(graphics, point1, point2, edgeNormal, (float)edgeConstraint.MaxWidth * drawSizeRatio, new Pen(Color.Cyan, lineWidth)); } if (drawMinEdgeWidth) { DrawOrientedRectange(graphics, point1, point2, edgeNormal, (float)edgeConstraint.MinWidth * drawSizeRatio, new Pen(Color.Red, lineWidth)); } if (drawAverageEdgeWidth) { DrawOrientedRectange(graphics, point1, point2, edgeNormal, (float)(edgeConstraint.MinWidth + edgeConstraint.MaxWidth) * drawSizeRatio * 0.5f, new Pen(Color.Blue, lineWidth)); } } } } return(statusImage); }
public double DistanceToPoint(Vector vector) { return Math.Sqrt(this.DistanceToPointSquared(vector)); }
public static PointF VecToPointF(Vector vec) { return new PointF((float)vec.X, (float)vec.Y); }
public static Vector Trunc(Vector value, Vector min, Vector max) { return new Vector( Trunc(value.X, min.X, max.X), Trunc(value.Y, min.Y, max.Y)); }
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); } }
public static double CrossProduct(Vector vector1, Vector vector2) { return vector1.X * vector2.Y - vector1.Y * vector2.X; }
private void OnShapeCanvasMouseMove(object sender, MouseEventArgs e) { Point mousePos = e.GetPosition(this.shapeCanvas); if (this.controlledVertexIndex.HasValue) { this.shape.VertexPositions[this.controlledVertexIndex.Value] = new Vector(mousePos.X, mousePos.Y) - this.mouseOffset; } else if (this.controlledEdgeIndex.HasValue) { ShapeEdge edge = this.shape.Structure.Edges[this.controlledEdgeIndex.Value]; double distanceFromEdgeLine = new Vector(mousePos.X, mousePos.Y).DistanceToLine( this.shape.VertexPositions[edge.Index1], this.shape.VertexPositions[edge.Index2]); this.shape.EdgeWidths[this.controlledEdgeIndex.Value] = Math.Max(this.initialEdgeWidth + 2 * (distanceFromEdgeLine - this.initialDistanceFromEdgeLine), 5); } if (this.controlledVertexIndex.HasValue || this.controlledEdgeIndex.HasValue) this.UpdateShapeControls(); }
public double DistanceToPointSquared(Vector vector) { return (vector - this).LengthSquared; }
/// <summary> /// Checks if point is inside the polygon. Polygon is assumed to be "simple". /// </summary> /// <param name="point">Point to check.</param> /// <returns>True if point is inside, false otherwise.</returns> public bool IsPointInside(Vector point) { int windingNumber = this.WindingNumber(point); return windingNumber == 1 || windingNumber == -1; }
public double DistanceToSegment(Vector segmentStart, Vector segmentEnd) { return Math.Sqrt(this.DistanceToSegmentSquared(segmentStart, segmentEnd)); }
public void DistanceToSegment(Vector segmentStart, Vector segmentEnd, out double distance, out double alpha) { double distanceSqr; this.DistanceToSegmentSquared(segmentStart, segmentEnd, out distanceSqr, out alpha); distance = Math.Sqrt(distanceSqr); }
public VertexConstraints(Vector coord) : this(coord, coord) { }
public double DistanceToSegmentSquared(Vector segmentStart, Vector segmentEnd) { double distanceSqr, alpha; this.DistanceToSegmentSquared(segmentStart, segmentEnd, out distanceSqr, out alpha); return distanceSqr; }
public static Polygon SolvePulleyProblem(Circle circle1, Circle circle2) { if (circle1.Radius < circle2.Radius) Helper.Swap(ref circle1, ref circle2); Debug.Assert(!circle1.Contains(circle2)); double edgeLength = (circle1.Center - circle2.Center).Length; double cosAngle = (circle1.Radius - circle2.Radius) / edgeLength; double angle = Math.Acos(cosAngle); Debug.Assert(angle >= 0 && angle <= Math.PI / 2); double lineAngle = Math.Atan2(circle2.Center.Y - circle1.Center.Y, circle2.Center.X - circle1.Center.X); double cosPlusPlus = Math.Cos(lineAngle + angle); double sinPlusPlus = Math.Sin(lineAngle + angle); double cosPlusMinus = Math.Cos(lineAngle - angle); double sinPlusMinus = Math.Sin(lineAngle - angle); Vector line1Point1 = new Vector( circle1.Center.X + circle1.Radius * cosPlusPlus, circle1.Center.Y + circle1.Radius * sinPlusPlus); Vector line2Point1 = new Vector( circle1.Center.X + circle1.Radius * cosPlusMinus, circle1.Center.Y + circle1.Radius * sinPlusMinus); Vector line1Point2 = new Vector( circle2.Center.X + circle2.Radius * cosPlusPlus, circle2.Center.Y + circle2.Radius * sinPlusPlus); Vector line2Point2 = new Vector( circle2.Center.X + circle2.Radius * cosPlusMinus, circle2.Center.Y + circle2.Radius * sinPlusMinus); return Polygon.FromPoints(line1Point1, line1Point2, line2Point2, line2Point1); }
private void DrawOrientedRectange(Graphics graphics, Vector point1, Vector point2, Vector sideDirection, float sideWidth, Pen pen) { graphics.DrawPolygon( pen, new[] { MathHelper.VecToPointF(point1 - sideDirection * sideWidth * 0.5), MathHelper.VecToPointF(point1 + sideDirection * sideWidth * 0.5), MathHelper.VecToPointF(point2 + sideDirection * sideWidth * 0.5), MathHelper.VecToPointF(point2 - sideDirection * sideWidth * 0.5) }); }