private static float AngleMadeByPoints(PointF a, PointF b) { double hypotenuse = a.DistanceTo(b); double cathetus = Math.Abs(a.Y - b.Y); return(Math.Asin(cathetus / hypotenuse).RoundTwoDigits()); }
private float GetHandWidthBetween(PointF p1, PointF p2) { float slope = Math.Abs(p2.X - p1.X) / p2.DistanceTo(p1); PointF p3 = new PointF(); PointF p4 = new PointF(); if (slope < 0.707)//vert { for (int Y = 0; Y < Math.Abs(p2.Y - p1.Y); Y++) { p3 = InterPolateP(p1, p2, Y / (p2.Y - p1.Y)); if (IsHand(p3)) { break; } } for (int Y = 0; Y < Math.Abs(p2.Y - p1.Y); Y++) { p4 = InterPolateP(p2, p1, Y / (p2.Y - p1.Y)); if (IsHand(p4)) { break; } } return(p3.DistanceTo(p4)); } else//hori { for (int x = 0; x < Math.Abs(p2.X - p1.X); x++) { p3 = InterPolateP(p1, p2, x / (p2.X - p1.X)); if (IsHand(p3)) { break; } } for (int x = 0; x < Math.Abs(p2.X - p1.X); x++) { p4 = InterPolateP(p2, p1, x / (p2.X - p1.X)); if (IsHand(p4)) { break; } } return(p3.DistanceTo(p4)); } }
/// <inheritdoc/> public override bool Contains(PointF point) { var distanceFromStart = Position.DistanceTo(point); var distanceToEnd = point.DistanceTo(LineEnd); var totalDistance = Position.DistanceTo(LineEnd); return(distanceFromStart + distanceToEnd - totalDistance < 0.01); }
public void FillArray(float[,] ary, Rectangle outer, Rectangle inner, List <StabilityChunk> chunks) { //Console.WriteLine(inner.ToString()); if (inner.Height > 64) { // i1, i3 // i2, i4 var x2 = (inner.Left + inner.Right) / 2; var y2 = (inner.Top + inner.Bottom) / 2; var i1 = new Rectangle(inner.X, inner.Y, x2 - inner.X, y2 - inner.Y); var i2 = new Rectangle(inner.X, y2, x2 - inner.X, inner.Bottom - y2); var i3 = new Rectangle(x2, inner.Y, inner.Right - x2, y2 - inner.Y); var i4 = new Rectangle(x2, y2, inner.Right - x2, inner.Bottom - y2); FillArray(ary, outer, i1, chunks.Where(c => i1.IntersectsWith(c.BoundingBox)).ToList()); FillArray(ary, outer, i2, chunks.Where(c => i2.IntersectsWith(c.BoundingBox)).ToList()); FillArray(ary, outer, i3, chunks.Where(c => i3.IntersectsWith(c.BoundingBox)).ToList()); FillArray(ary, outer, i4, chunks.Where(c => i4.IntersectsWith(c.BoundingBox)).ToList()); return; } // Calculate the triangle centers for this set var centers = new List <(PointF, float)>(); for (var i = 0; i < chunks.Count; i++) { var tris = chunks[i].Triangles; for (var j = 0; j < tris.Count; j++) { var tri = tris[j]; centers.Add((tri.AveragePoint(), tri.Depth)); } } for (var row = inner.Y; row < inner.Bottom; row++) { for (var col = inner.X; col < inner.Right; col++) { var best_distance = float.MaxValue; var best_depth = 1.5f; var pt = new PointF(col, row); for (var i = 0; i < centers.Count; i++) { var center = centers[i]; var d = pt.DistanceTo(center.Item1); if (d < best_distance) { best_distance = d; best_depth = center.Item2; } } ary[row - outer.Y, col - outer.X] = best_depth; } } }
/// <summary> /// Determines whether two points are within 'epsilon' of each other /// </summary> public static bool WithinEpsilonOf(this PointF This, PointF other, float epsilon) { return(This.DistanceTo(other) < epsilon); }
private unsafe void ProcessImage(ref Image <Bgr, byte> img) { Image <Gray, byte> gray_image = img.Convert <Gray, byte>(); grayImg = gray_image; binaryImg = gray_image.ThresholdBinaryInv(new Gray(200), new Gray(255)); //Find contours with no holes try CV_RETR_EXTERNAL to find holes IntPtr Dyncontour = new IntPtr();//存放检测到的图像块的首地址 IntPtr Dynstorage = CvInvoke.cvCreateMemStorage(0); int n = CvInvoke.cvFindContours(binaryImg.Ptr, Dynstorage, ref Dyncontour, sizeof(MCvContour), Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, new Point(0, 0)); Seq <Point> DyncontourTemp1 = new Seq <Point>(Dyncontour, null);//方便对IntPtr类型进行操作 Seq <Point> DyncontourTemp = DyncontourTemp1; List <MCvBox2D> rectList = new List <MCvBox2D>(); for (; DyncontourTemp != null && DyncontourTemp.Ptr.ToInt32() != 0; DyncontourTemp = DyncontourTemp.HNext) { CvInvoke.cvDrawContours(image, DyncontourTemp, new MCvScalar(255, 0, 0), new MCvScalar(0, 255, 0), 10, 1, Emgu.CV.CvEnum.LINE_TYPE.FOUR_CONNECTED, new Point(0, 0)); PointF[] rect1 = DyncontourTemp.GetMinAreaRect().GetVertices(); rectList.Add(DyncontourTemp.GetMinAreaRect()); var pointfSeq = from p in rect1 select new Point((int)p.X, (int)p.Y); Point[] points = pointfSeq.ToArray(); for (int j = 0; j < 4; j++) { CvInvoke.cvLine(image, points[j], points[(j + 1) % 4], new MCvScalar(0, 0, 255), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); } //CvInvoke.cvNamedWindow("main"); } for (int i = 0; i < rectList.Count(); i++) { MCvBox2D rect = rectList[i]; PointF[] pl = rect.GetVertices(); var points = from p in pl orderby p.Y ascending select p; pl = points.ToArray(); PointF startP = pl[0]; PointF shortP = pl[1]; PointF longP = pl[2]; if (pl[1].DistanceTo(startP) > pl[2].DistanceTo(startP)) { shortP = pl[2]; longP = pl[1]; } float longDis = longP.DistanceTo(startP); if (longDis < minLength) { continue; } float shortDis = shortP.DistanceTo(startP); float longslope = Math.Abs(longP.X - startP.X) / longDis; float min = 9999; PointF ap1 = new PointF(); PointF ap2 = new PointF(); if (longslope < 0.707)//vert { for (int y = begin; y < Convert.ToInt32(Math.Abs(longP.Y - startP.Y)) && Math.Abs(y) < width; y++) { PointF p1 = InterPolateP(startP, longP, y / Math.Abs(longP.Y - startP.Y)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } else { for (int X = begin; X < Convert.ToInt32(Math.Abs(longP.X - startP.X)) && Math.Abs(X) < width; X++) { PointF p1 = InterPolateP(startP, longP, X / Math.Abs(longP.X - startP.X)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } CvInvoke.cvLine(image, ap1.ToPoint(), ap2.ToPoint(), new MCvScalar(0, 0, 255), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); } //CvInvoke.cvShowImage("main", tempImage); //image = binaryImg.Convert<Bgr, Byte>(); //Bitmap bmp = image.ToBitmap(); //using (Graphics g = Graphics.FromImage(bmp)) //{ // List<Rectangle> recList = new List<Rectangle>(); // double max_area = 0; // for (int i = 0; contours != null; contours = contours.HNext) // { // if ((contours.Area > Math.Pow(25, 2)) && (contours.Area < Math.Pow(300, 2))) // { // // Console.WriteLine(contours.Area); // Seq<Point> seq = contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); // var pointfSeq = // from p in seq // select new PointF(p.X, p.Y); // //max_area = contours.Area; // // MCvBox2D ellp = CvInvoke.cvFitEllipse2(seq.Ptr); // MCvBox2D ellp = contours.GetMinAreaRect(); // //g.DrawPolygon(new Pen(Brushes.Red, 2), contours.ToArray()); // //Ellipse elps = PointCollection.EllipseLeastSquareFitting(pointfSeq.ToArray()); // g.TranslateTransform(ellp.center.X, ellp.center.Y); // g.RotateTransform(ellp.angle); // g.DrawRectangle(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2, // -ellp.MinAreaRect().Height / 2, // ellp.MinAreaRect().Width, // ellp.MinAreaRect().Height); // g.RotateTransform(-ellp.angle); // g.DrawRectangle(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2, // -ellp.MinAreaRect().Height / 2, // ellp.MinAreaRect().Width, // ellp.MinAreaRect().Height); // // g.DrawRectangle(new Pen(Brushes.Red, 2), -elps.MCvBox2D.MinAreaRect().Width / 2, -elps.MCvBox2D.MinAreaRect().Height / 2, elps.MCvBox2D.MinAreaRect().Width, elps.MCvBox2D.MinAreaRect().Height); // //g.DrawEllipse(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2, // // -ellp.MinAreaRect().Height / 2, // // ellp.MinAreaRect().Width, // // ellp.MinAreaRect().Height); // g.ResetTransform(); // // break; // } // } //} //imageBox1.Image = new Image<Bgr, byte>(bmp); }
private MCvBox2D SplitHand(MCvBox2D rect, HandEnum handEnum, PointF Elbow2HandVector) { if (handEnum == HandEnum.Both || handEnum == HandEnum.Intersect) { return new MCvBox2D(rect.center, rect.MinAreaRect().Size, 0); } PointF[] pl = rect.GetVertices(); Point[] splittedHands = new Point[4]; //find angle of long edge PointF startP = pl[1]; PointF shortP = pl[0]; PointF longP = pl[2]; PointF ap1 = new PointF(); PointF ap2 = new PointF(); if (pl[0].DistanceTo(startP) > pl[2].DistanceTo(startP)) { shortP = pl[2]; longP = pl[0]; } SizeF size = new SizeF(); size.Width = shortP.DistanceTo(startP); size.Height = longP.DistanceTo(startP); PointF shortEdge = new PointF(shortP.X - startP.X, shortP.Y - startP.Y); float t_angle = (float)(Math.Atan(shortEdge.Tan())*180/Math.PI); MCvBox2D box = new MCvBox2D(); box.size = size; box.center = pl.GetCenter(); float longDis = longP.DistanceTo(startP); float shortDis = shortP.DistanceTo(startP); // x and long edge slope float longslope = Math.Abs(longP.X - startP.X) / longDis; float min = float.MaxValue; float factor = Math.Max(Math.Abs(longP.Y - startP.Y) / longDis, Math.Abs(longP.X - startP.X) / longDis); int TransformEnd = Convert.ToInt32(factor * end); int TransformBegin = Convert.ToInt32(factor * begin); //Console.WriteLine(TransformBegin); //Console.WriteLine(TransformEnd); // > 45 if (longslope < 0.707)//vert { // point up if (Elbow2HandVector.Y <= 0) { box.angle = t_angle; startP = pl.OrderBy((x => x.Y)).First(); } else { box.angle = t_angle + 180; startP = pl.OrderByDescending((x => x.Y)).First(); } if (longDis < minLength) { return box; } pl = pl.OrderBy(x => x.DistanceTo(startP)).ToArray(); shortP = pl[1]; longP = pl[2]; for (int y = TransformBegin; y < Convert.ToInt32(Math.Abs(longP.Y - startP.Y)) && Math.Abs(y) < TransformEnd; y++) { PointF p1 = InterPolateP(startP, longP, y / Math.Abs(longP.Y - startP.Y)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } else // horizontal { // point top for right hand if (t_angle <0) { if (handEnum == HandEnum.Right) { box.angle = t_angle; } else { box.angle = t_angle + 180; } } // point bottom for right hand else { if (handEnum == HandEnum.Right) { box.angle = t_angle - 180; } else { box.angle = t_angle; } } if (handEnum == HandEnum.Right) { startP = pl.OrderBy((x => x.X)).ToArray()[0]; } else if (handEnum == HandEnum.Left) { startP = pl.OrderByDescending((x => x.X)).ToArray()[0]; } if (longDis < minLength) { return box; } pl = pl.OrderBy(x => x.DistanceTo(startP)).ToArray(); shortP = pl[1]; longP = pl[2]; for (int X = TransformBegin; X < Convert.ToInt32(Math.Abs(longP.X - startP.X)) && Math.Abs(X) < TransformEnd; X++) { PointF p1 = InterPolateP(startP, longP, X / Math.Abs(longP.X - startP.X)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } if (ap1 == null || ap1 == PointF.Empty) { return box; } splittedHands[0] = startP.ToPoint(); splittedHands[1] = ap1.ToPoint(); splittedHands[2] = ap2.ToPoint(); splittedHands[3] = shortP.ToPoint(); //Point lowP = p.OrderByDescending(x => x.Y).First(); //Point highP = p.OrderByDescending(x => x.DistanceTo(lowP)).First(); //Point widthP = p.OrderBy(x => x.TanWith(lowP)).First(); box.center = splittedHands.GetCenter(); box.size.Height = startP.DistanceTo(ap1); return box; }
public void ActionCE(ControlElement ce, PointF from, PointF to) { var rect = GetRect(); switch (ce) { case ControlElement.Inside: Translate = Translate.Move(to.Shift(from)); break; case ControlElement.Outside: var c = PosCE(ControlElement.Center); var a = from.Shift(c); var b = to.Shift(c); var nA = a.Norm(); var nB = b.Norm(); var d = from.DistanceTo(to); var cos = (nA * nA + nB * nB - d * d) / (2 * nA * nB); // law of cosines var ang = Math.Acos(cos) * Math.Sign(a.Cross(b)); Rotate += ang.ToDegrees(); Rotate %= 360; break; case ControlElement.Center: RotateCenter = RotateCenter.Move(to.Shift(from).Relative(img.Size)); break; case ControlElement.SizeTopLeft: Scale = Scale.Move(to.Shift(from).Factors(-1, -1).Relative(img.Size)); Translate = Translate.Move(to.Shift(from).Factors(1, 1)); break; case ControlElement.SizeTopRight: Scale = Scale.Move(to.Shift(from).Factors(1, -1).Relative(img.Size)); Translate = Translate.Move(to.Shift(from).Factors(0, 1)); break; case ControlElement.SizeBottomRight: Scale = Scale.Move(to.Shift(from).Relative(img.Size)); break; case ControlElement.SizeBottomLeft: Scale = Scale.Move(to.Shift(from).Factors(-1, 1).Relative(img.Size)); Translate = Translate.Move(to.Shift(from).Factors(1, 0)); break; case ControlElement.SizeTop: Scale = Scale.Move(to.Shift(from).Factors(0, -1).Relative(img.Size)); Translate = Translate.Move(to.Shift(from).Factors(0, 1)); break; case ControlElement.SizeRight: Scale = Scale.Move(to.Shift(from).Factors(1, 0).Relative(img.Size)); break; case ControlElement.SizeBottom: Scale = Scale.Move(to.Shift(from).Factors(0, 1).Relative(img.Size)); break; case ControlElement.SizeLeft: Scale = Scale.Move(to.Shift(from).Factors(-1, 0).Relative(img.Size)); Translate = Translate.Move(to.Shift(from).Factors(1, 0)); break; default: break; } if (Math.Abs(Scale.X) < 0.0001) { Scale = new PointF(0.0001f, Scale.Y); } if (Math.Abs(Scale.Y) < 0.0001) { Scale = new PointF(Scale.X, 0.0001f); } }
private static float DistanceBetweenPoints(PointF a, PointF b) { return(a.DistanceTo(b).RoundTwoDigits()); }
private static float AreaForTriangle(PointF a, PointF b, PointF c) { return(AreaBySemiPerimeter(a.DistanceTo(b), b.DistanceTo(c), c.DistanceTo(a))); }
private static float DistanceBetweenPoints(PointF a, PointF b) { return a.DistanceTo(b).RoundTwoDigits(); }
private static float AngleMadeByPoints(PointF a, PointF b) { double hypotenuse = a.DistanceTo(b); double cathetus = Math.Abs(a.Y - b.Y); return Math.Asin(cathetus / hypotenuse).RoundTwoDigits(); }
private static float AreaForTriangle(PointF a, PointF b, PointF c) { return AreaBySemiPerimeter(a.DistanceTo(b), b.DistanceTo(c), c.DistanceTo(a)); }
public static float FBError(PointF p1, PointF p2) { return(p1.DistanceTo(p2)); }