Пример #1
0
        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());
        }
Пример #2
0
        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));
            }
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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;
                }
            }
        }
Пример #5
0
 /// <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);
 }
Пример #6
0
        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);
        }
Пример #7
0
        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;
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
 private static float DistanceBetweenPoints(PointF a, PointF b)
 {
     return(a.DistanceTo(b).RoundTwoDigits());
 }
Пример #10
0
 private static float AreaForTriangle(PointF a, PointF b, PointF c)
 {
     return(AreaBySemiPerimeter(a.DistanceTo(b), b.DistanceTo(c), c.DistanceTo(a)));
 }
Пример #11
0
 private static float DistanceBetweenPoints(PointF a, PointF b)
 {
     return a.DistanceTo(b).RoundTwoDigits();
 }
Пример #12
0
 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();
 }
Пример #13
0
 private static float AreaForTriangle(PointF a, PointF b, PointF c)
 {
     return AreaBySemiPerimeter(a.DistanceTo(b), b.DistanceTo(c), c.DistanceTo(a));
 }
Пример #14
0
 public static float FBError(PointF p1, PointF p2)
 {
     return(p1.DistanceTo(p2));
 }