Esempio n. 1
0
        public override void OnScannedRobot(ScannedRobotEvent e)
        {
            double absoluteBearing   = HeadingRadians + e.BearingRadians;
            PointF myLocation        = new PointF((float)X, (float)Y);
            PointF predictedLocation = projectMotion(myLocation, absoluteBearing, e.Distance);
            double predictedHeading;
            double enemyTurnRate = -Utils.NormalRelativeAngle(expectedHeading - (predictedHeading = expectedHeading = e.HeadingRadians));
            double bulletPower   = Math.Min(e.Distance < 250 ? 500 / e.Distance : 200 / e.Distance, 3);

            int time = 0;

            while ((time++) * (20 - (3 * bulletPower)) < myLocation.Distance(predictedLocation) - 18)
            {
                predictedHeading += (enemyTurnRate / 3);
                predictedLocation = projectMotion(predictedLocation, predictedHeading, e.Velocity);

                if (!new RectangleF(18, 18, 764, 564).Contains(predictedLocation))
                {
                    break;
                }
            }

            double maxValue = Double.MinValue;
            double angle    = 0;

            do
            {
                double value          = Math.Abs(Math.Cos(Utils.NormalRelativeAngle(absoluteBearing - angle))) * e.Distance / 150;
                PointF testedLocation = projectMotion(myLocation, angle, 8);

                value -= testedLocation.Distance(predictedLocation);
                value -= testedLocation.Distance(new PointF(400, 300)) / 3;

                if (!new RectangleF(30, 30, 740, 540).Contains(testedLocation))
                {
                    value -= 10000;
                }

                if (value > maxValue)
                {
                    maxValue = value;
                    double turnAngle = angle - HeadingRadians;
                    SetAhead(Math.Cos(turnAngle) > 0 ? 100 : -100);
                    SetTurnRightRadians(Math.Tan(turnAngle));
                }
            } while ((angle += 0.01) < Math.PI * 2);

            MaxVelocity = (Math.Abs(TurnRemaining) < 30 ? 8 : 8 - Math.Abs(TurnRemaining / 30));

            double gunTurn = Utils.NormalRelativeAngle(Math.Atan2(predictedLocation.X - myLocation.X, predictedLocation.Y - myLocation.Y) - GunHeadingRadians);

            SetTurnGunRightRadians(gunTurn);

            if ((Math.Abs(gunTurn) < Math.PI / 9) && (GunHeat == 0.0))
            {
                SetFire(bulletPower);
            }

            SetTurnRadarRightRadians(2 * Utils.NormalRelativeAngle(absoluteBearing - RadarHeadingRadians));
        }
Esempio n. 2
0
        private void Flocking(IEnumerable <BoidBehaviour> boids)
        {
            if (boids.Count() == 1)
            {
                Direction.X += 1;
                Direction.Y += 1;
            }

            foreach (BoidBehaviour boid in boids)
            {
                float distance = Position.Distance(boid.Position);
                if (boid != this && !boid.Predator)
                {
                    if (distance < Space)
                    {
                        // Create space.
                        Direction.X += (Position.X - boid.Position.X) * 0.01f;
                        Direction.Y += (Position.Y - boid.Position.Y) * 0.01f;
                    }
                    else if (distance < Sight)
                    {
                        // Flock together.
                        Direction.X += (boid.Position.X - Position.X) * 0.001f;
                        Direction.Y += (boid.Position.Y - Position.Y) * 0.001f;
                    }

                    if (distance < Sight)
                    {
                        // Align movement.
                        Direction.X += boid.Direction.X * 0.001f;
                        Direction.Y += boid.Direction.Y * 0.001f;
                    }
                }

                if (boid.Predator && distance < Sight)
                {
                    // Avoid hunters.
                    Direction.X += Position.X - boid.Position.X * 0.2f;
                    Direction.Y += Position.Y - boid.Position.Y * 0.2f;
                }

                if (this.Avoid.HasValue && this.Position.Distance(this.Avoid.Value) < Sight)
                {
                    // Avoid hunters.
                    Direction.X += Position.X - this.Avoid.Value.X * 1.0f;
                    Direction.Y += Position.Y - this.Avoid.Value.Y * 1.0f;
                }
            }
        }
Esempio n. 3
0
        public static double FindDistanceAlongSpine(PointF[] spine, PointF point)
        {
            if (spine == null || spine.Length <= 1)
            {
                return(-1);
            }

            double minDist   = double.MaxValue;
            PointF bestPoint = PointF.Empty;

            PointF[] closestPoints = new PointF[2];
            double   totalDist     = 0;

            for (int i = 1; i < spine.Length; i++)
            {
                PointF previousPoint = spine[i - 1];
                PointF currentPoint  = spine[i];
                PointF closestPoint;
                double currentMinDist = MathExtension.MinDistanceFromLineToPoint(previousPoint, currentPoint, point, out closestPoint);

                if (currentMinDist < minDist)
                {
                    minDist          = currentMinDist;
                    bestPoint        = closestPoint;
                    closestPoints[0] = previousPoint;
                    closestPoints[1] = currentPoint;
                }
            }

            for (int i = 1; i < spine.Length; i++)
            {
                PointF previousPoint = spine[i - 1];
                PointF currentPoint  = spine[i];

                if (previousPoint == closestPoints[0])
                {
                    //We're on the line
                    totalDist += previousPoint.Distance(bestPoint);
                    break;
                }
                else
                {
                    //Not on this line
                    totalDist += previousPoint.Distance(currentPoint);
                }
            }

            return(totalDist);
        }
Esempio n. 4
0
        public static PointF GetDistancePointFromBase(PointF[] spine, double distance, PointF offset = new PointF())
        {
            if (spine == null || spine.Length <= 1)
            {
                return(PointF.Empty);
            }

            //double targetDistance = 0;

            if (!offset.IsEmpty)
            {
            }

            double distanceCounter = 0;

            for (int i = 1; i < spine.Length; i++)
            {
                PointF previousPoint = spine[i - 1];
                PointF currentPoint  = spine[i];

                distanceCounter += previousPoint.Distance(currentPoint);

                if (distanceCounter > distance)
                {
                    //The point is somewhere along this line
                    Vector dir = new Vector(currentPoint.X - previousPoint.X, currentPoint.Y - previousPoint.Y);
                    dir.Normalize();
                    dir *= distance;
                    return(new PointF((float)(previousPoint.X + dir.X), (float)(previousPoint.Y + dir.Y)));
                }
            }

            return(PointF.Empty);
        }
Esempio n. 5
0
        public static PointF Mid(this PointF p, PointF other)
        {
            var distance  = p.Distance(other);
            var direction = (other.Sub(p)).Normalize();

            return(p.Add(direction.Scale(distance / 2)));
        }
Esempio n. 6
0
        public void DistanceTest()
        {
            var p        = new PointF(1, 1);
            var c        = new PointF(5, 4);
            var distance = p.Distance(c);

            Assert.AreEqual(distance, 5);
        }
Esempio n. 7
0
        public void DistanceTest(double x1, double y1, double x2, double y2)
        {
            Assert.AreEqual(x2.Hypot2(y2), MathTool.Distance(x1, y1, x2, y2), 0.000000001d);

            var p1 = new PointF((float)x1, (float)y1);
            var p2 = new PointF((float)x2, (float)y2);

            Assert.AreEqual(x2.Hypot2(y2), p1.Distance(p2), 0.000000001d);
        }
        public double GetDistance()
        {
            GenericPointViewModel genericPoint1 = CanvasChildren[0];
            GenericPointViewModel genericPoint2 = CanvasChildren[1];

            PointF relativePoint1 = new PointF((float)genericPoint1.XRatio * Image.Width, (float)genericPoint1.YRatio * Image.Height);
            PointF relativePoint2 = new PointF((float)genericPoint2.XRatio * Image.Width, (float)genericPoint2.YRatio * Image.Height);

            double dist = relativePoint1.Distance(relativePoint2);

            return(dist);
        }
Esempio n. 9
0
        public double GetTrackLength(PointF[] track)
        {
            double dist   = 0;
            int    length = track.Length;

            for (int i = 1; i < length; i++)
            {
                PointF p1 = track[i - 1];
                PointF p2 = track[i];
                dist += p1.Distance(p2);
            }

            return(dist);
        }
Esempio n. 10
0
        private float[] GetEuclideanDistance(IRadialGradient gradient, PointF center, RectangleF rect)
        {
            var points = gradient.Stretch.IsCorner() ?
                         GetCornerPoints(rect) :
                         GetSidePoints(center, rect);

            var distances = new float[points.Length];

            for (var i = 0; i < distances.Length; i++)
            {
                distances[i] = center.Distance(points[i]);
            }

            return(distances);
        }
Esempio n. 11
0
        public static PointF NearestPointFFromList(PointF srcPointF, List <PointF> listOfPointFs)
        {
            KeyValuePair <double, int> smallestDistance = new KeyValuePair <double, int>();

            for (int i = 0; i < listOfPointFs.Count; i++)
            {
                double distance = srcPointF.Distance(listOfPointFs[i]);
                if (i == 0)
                {
                    smallestDistance = new KeyValuePair <double, int>(distance, i);
                }
                else
                {
                    if (distance < smallestDistance.Key)
                    {
                        smallestDistance = new KeyValuePair <double, int>(distance, i);
                    }
                }
            }
            return(listOfPointFs[smallestDistance.Value]);
        }
Esempio n. 12
0
        public static bool GetPerpendicularLineDistanceFromBase(PointF[] spine, double distance, out PointF intersection, out Vector direction, PointF offset = new PointF())
        {
            intersection = PointF.Empty;
            direction    = new Vector();

            if (spine == null || spine.Length <= 1)
            {
                return(false);
            }

            double distanceCounter = 0;

            for (int i = 1; i < spine.Length; i++)
            {
                PointF previousPoint = spine[i - 1];
                PointF currentPoint  = spine[i];

                double currentSegmentDistance = previousPoint.Distance(currentPoint);
                distanceCounter += currentSegmentDistance;

                if (distanceCounter > distance)
                {
                    //The point is somewhere along this line
                    distanceCounter -= currentSegmentDistance;

                    double delta = distance - distanceCounter;

                    Vector dir = new Vector(currentPoint.X - previousPoint.X, currentPoint.Y - previousPoint.Y);
                    dir.Normalize();
                    dir         *= delta;
                    intersection = new PointF((float)(previousPoint.X + dir.X), (float)(previousPoint.Y + dir.Y));

                    //Create perpendicular Vector
                    direction = new Vector(dir.Y, -dir.X);
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 13
0
        protected override void OnTouchDown(Touch t)
        {
            if (t == Touch || _another != null)
            {
                return;
            }

            if (!Touch.Down)
            {
                Touch = t;
                OnTouchDown(t);
                return;
            }

            _pinching = true;

            _another   = t;
            _startSpan = PointF.Distance(Touch.Current, _another.Current);
            _startZoom = Camera.Zoom;

            _dragging = false;
        }
Esempio n. 14
0
            protected override void OnDrag(Touch t)
            {
                if (_dragging)
                {
                    var content = _scrollPane.Content();
                    var c       = content.Camera;

                    c.Scroll.Offset(PointF.Diff(_lastPos, t.Current).InvScale(c.Zoom));

                    if (c.Scroll.X + Width > content.Width)
                    {
                        c.Scroll.X = content.Width - Width;
                    }

                    if (c.Scroll.X < 0)
                    {
                        c.Scroll.X = 0;
                    }

                    if (c.Scroll.Y + Height > content.Height)
                    {
                        c.Scroll.Y = content.Height - Height;
                    }

                    if (c.Scroll.Y < 0)
                    {
                        c.Scroll.Y = 0;
                    }

                    _lastPos.Set(t.Current);
                }
                else
                if (PointF.Distance(t.Current, t.Start) > _dragThreshold)
                {
                    _dragging = true;
                    _lastPos.Set(t.Current);
                }
            }
Esempio n. 15
0
        protected override void OnDrag(Touch t)
        {
            Camera.Target = null;

            if (_pinching)
            {
                var curSpan = PointF.Distance(Touch.Current, _another.Current);
                Camera.ZoomTo(GameMath.Gate(PixelScene.minZoom, _startZoom * curSpan / _startSpan, PixelScene.maxZoom));
            }
            else
            {
                if (!_dragging && PointF.Distance(t.Current, t.Start) > _dragThreshold)
                {
                    _dragging = true;
                    _lastPos.Set(t.Current);
                }
                else if (_dragging)
                {
                    Camera.Scroll.Offset(PointF.Diff(_lastPos, t.Current).InvScale(Camera.Zoom));
                    _lastPos.Set(t.Current);
                }
            }
        }
Esempio n. 16
0
        public void Draw(Graphics g)
        {
            var BackgroundBrush = CSMABackgroundBrush;

            switch (Type)
            {
            case DomainType.CSMA:
            {
                BackgroundBrush = CSMABackgroundBrush;
                break;
            }

            case DomainType.IEEE81211:
            {
                BackgroundBrush = IEEE81211BackgroundBrush;
                break;
            }

            case DomainType.LTE:
            {
                BackgroundBrush = LTEBackgroundBrush;
                break;
            }

            case DomainType.Wimax:
            {
                BackgroundBrush = WimaxBackgroundBrush;
                break;
            }
            }

            if (Nodes.Count == 0)
            {
                if (Radius > 0)
                {
                    g.FillEllipse(BackgroundBrush, new Rectangle((int)(X - Radius), (int)(Y - Radius), (int)(Radius * 2), (int)(Radius * 2)));
                }
            }
            else
            {
                if (DisplayProperties.RenderDomain)
                {
                    var nodeRadius = 0.0d;
                    foreach (var node in Nodes)
                    {
                        var dist = Position.Distance(node.Position);
                        if (dist > nodeRadius)
                        {
                            nodeRadius = dist;
                        }
                    }

                    g.FillEllipse(BackgroundBrush, new Rectangle((int)(X - nodeRadius), (int)(Y - nodeRadius), (int)(nodeRadius * 2), (int)(nodeRadius * 2)));
                }
            }

            if (DisplayProperties.RenderDomainText)
            {
                var textWidth  = (int)g.MeasureString(Text, SystemFonts.DefaultFont).Width;
                var textHeight = (int)g.MeasureString(Text, SystemFonts.DefaultFont).Height;
                var diameter   = textWidth > textHeight ? textWidth : textHeight;

                if (diameter < 35)
                {
                    diameter = 35;
                }
                g.FillEllipse(BackgroundBrush, new Rectangle((int)(X - diameter / 2), (int)(Y - diameter / 2), diameter, diameter));
                g.DrawString(Text, SystemFonts.DefaultFont, Brushes.Black, new Point((int)(X - textWidth / 2), (int)(Y - textHeight / 2)));
            }
        }
Esempio n. 17
0
        public LineSet(int id, LineContainer container, IEnumerable <Dot> dots)
        {
            ID        = id;
            this.dots = dots.ToArray();
            //if(dots.Last().NextConnectDot)
            foreach (var item in this.dots)
            {
                item.LineSet       = this;
                item.PointChanged += DotPointChanged;
            }
            List <Dot> pl = new List <Dot>();
            Dot        first, prev;

            prev = first = this.dots.First();
            PointF firstP, prevP = prev.Point;

            firstP = first.Point;
            float minX, maxX, minY, maxY;

            minX = maxX = firstP.X;
            minY = maxY = firstP.Y;
            //PointF first = dots.First().Point;
            //PointF prev = first;
            int counter = 0;
            int length  = this.dots.Length;

            dotDistances  = new float[length];
            dotRectangles = new RectangleF[length];
            lines         = new Line[length];
            Line line;

            foreach (var item in this.dots.Skip(1))
            {
                PointF currentP = item.Point;
                //dotRectangles[counter] = currentP.GetRectangleFromTwoPoint(prevP);
                dotDistances[counter] = (float)currentP.Distance(prevP);
                line                   = new Line(prev, item, this, container);
                lines[counter]         = line;
                dotRectangles[counter] = line.RectangleF;
                prev                   = item;
                prevP                  = prev.Point;
                counter++;

                float x = currentP.X, y = currentP.Y;
                if (x < minX)
                {
                    minX = x;
                }
                else if (x > maxX)
                {
                    maxX = x;
                }

                if (y < minY)
                {
                    minY = y;
                }
                else if (y > maxY)
                {
                    maxY = y;
                }
            }
            dotDistances[counter] = (float)firstP.Distance(prevP);
            line                   = new Line(prev, first, this, container);
            lines[counter]         = line;
            dotRectangles[counter] = line.RectangleF;

            RectangleF = new RectangleF(minX, minY, maxX - minX, maxY - minY);
            Color      = ColorCollections[ID % ColorCollections.Length];
        }
Esempio n. 18
0
            public Bitmap GetImage(int width, int height, Font font, float offsetX, float offsetY, float scale)
            {
                Bitmap   bmp = new Bitmap(width, height);
                Graphics g = Graphics.FromImage(bmp);
                float    minX = float.PositiveInfinity, minY = float.PositiveInfinity, maxX = float.NegativeInfinity, maxY = float.NegativeInfinity;

                foreach (Node n in Nodes)
                {
                    minX = Math.Min(minX, n.Location.X);
                    minY = Math.Min(minY, n.Location.Y);
                    maxX = Math.Max(maxX, n.Location.X);
                    maxY = Math.Max(maxY, n.Location.Y);
                }
                if (!fixCamera)
                {
                    float s = scale;
                    scale    = 1f;
                    origin   = new PointF((minX + maxX) * 30 * scale / 2, (minY + maxY) * 30 * scale / 2);
                    scale    = Math.Min(width / 2 / (maxX * 30 * scale - origin.X), height / 2 / (maxY * 30 * scale - origin.Y)) * 0.9f;
                    scale   *= s;
                    RefScale = scale;
                    origin   = new PointF((minX + maxX) * 30 * scale / 2, (minY + maxY) * 30 * scale / 2);
                }
                else
                {
                    scale = RefScale;
                }
                if (Math.Abs((minX + maxX) * 30 * scale / 2) > 10000f || Math.Abs((minY + maxY) * 30 * scale / 2) > 10000f)
                {
                    Recenter();
                    minX = float.PositiveInfinity;
                    minY = float.PositiveInfinity;
                    maxX = float.NegativeInfinity;
                    maxY = float.NegativeInfinity;
                    foreach (Node n in Nodes)
                    {
                        minX = Math.Min(minX, n.Location.X);
                        minY = Math.Min(minY, n.Location.Y);
                        maxX = Math.Max(maxX, n.Location.X);
                        maxY = Math.Max(maxY, n.Location.Y);
                    }
                    if (!fixCamera)
                    {
                        float s = scale;
                        scale    = 1f;
                        origin   = new PointF((minX + maxX) * 30 * scale / 2, (minY + maxY) * 30 * scale / 2);
                        scale    = Math.Min(width / 2 / (maxX * 30 * scale - origin.X), height / 2 / (maxY * 30 * scale - origin.Y)) * 0.9f;
                        scale   *= s;
                        RefScale = scale;
                        origin   = new PointF((minX + maxX) * 30 * scale / 2, (minY + maxY) * 30 * scale / 2);
                    }
                }
                g.TranslateTransform(width / 2 + offsetX - origin.X, height / 2 + offsetY - origin.Y);
                bool found = false;

                foreach (Node n in Nodes)
                {
                    if (simpleMode && n.Type != Elements.Hydrogen || !simpleMode)
                    {
                        if (found || Selected != null && Selected.Locked)
                        {
                            g.DrawString(n.Type.ToDString(), font, Brushes.Black, n.Location.X * 30 * scale, n.Location.Y * 30 * scale, new StringFormat()
                            {
                                LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center
                            });
                        }
                        else if (Cursor.Distance(n.Location.Scale(30f * scale).Add(new PointF(width / 2 + offsetX, height / 2 + offsetY)).Subtract(origin)) < 10f)
                        {
                            found    = true;
                            Selected = n;
                        }
                    }
                    g.DrawString(n.Type.ToDString(), font, n == Selected ? Brushes.Silver : Brushes.Black, n.Location.X * 30 * scale, n.Location.Y * 30 * scale, new StringFormat()
                    {
                        LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center
                    });
                }
                if ((Selected == null || !Selected.Locked) && !found)
                {
                    Selected = null;
                }
                foreach (Bond b in Bonds)
                {
                    PointF Dir21 = b.Node2.Location.Subtract(b.Node1.Location).Normalize();
                    PointF gap   = Dir21.Scale(10);
                    if (simpleMode && b.Node1.Type != Elements.Hydrogen && b.Node2.Type != Elements.Hydrogen || !simpleMode)
                    {
                        if (b.Type == BondType.Single || b.Type == BondType.Triple)
                        {
                            g.DrawLine(Pens.Black,
                                       gap.X + b.Node1.Location.X * 30 * scale,
                                       gap.Y + b.Node1.Location.Y * 30 * scale,
                                       -gap.X + b.Node2.Location.X * 30 * scale,
                                       -gap.Y + b.Node2.Location.Y * 30 * scale);
                        }
                        if (b.Type == BondType.Triple)
                        {
                            double angle   = Math.Atan2(Dir21.Y, Dir21.X);
                            PointF lateral = new PointF((float)Math.Cos(angle + Math.PI / 2), (float)Math.Sin(angle + Math.PI / 2)).Scale(4);
                            g.DrawLine(Pens.Black,
                                       lateral.X + gap.X + b.Node1.Location.X * 30 * scale,
                                       lateral.Y + gap.Y + b.Node1.Location.Y * 30 * scale,
                                       lateral.X - gap.X + b.Node2.Location.X * 30 * scale,
                                       lateral.Y - gap.Y + b.Node2.Location.Y * 30 * scale);
                            g.DrawLine(Pens.Black,
                                       -lateral.X + gap.X + b.Node1.Location.X * 30 * scale,
                                       -lateral.Y + gap.Y + b.Node1.Location.Y * 30 * scale,
                                       -lateral.X - gap.X + b.Node2.Location.X * 30 * scale,
                                       -lateral.Y - gap.Y + b.Node2.Location.Y * 30 * scale);
                        }
                        if (b.Type == BondType.Double)
                        {
                            double angle   = Math.Atan2(Dir21.Y, Dir21.X);
                            PointF lateral = new PointF((float)Math.Cos(angle + Math.PI / 2), (float)Math.Sin(angle + Math.PI / 2)).Scale(2);
                            g.DrawLine(Pens.Black,
                                       lateral.X + gap.X + b.Node1.Location.X * 30 * scale,
                                       lateral.Y + gap.Y + b.Node1.Location.Y * 30 * scale,
                                       lateral.X - gap.X + b.Node2.Location.X * 30 * scale,
                                       lateral.Y - gap.Y + b.Node2.Location.Y * 30 * scale);
                            g.DrawLine(Pens.Black,
                                       -lateral.X + gap.X + b.Node1.Location.X * 30 * scale,
                                       -lateral.Y + gap.Y + b.Node1.Location.Y * 30 * scale,
                                       -lateral.X - gap.X + b.Node2.Location.X * 30 * scale,
                                       -lateral.Y - gap.Y + b.Node2.Location.Y * 30 * scale);
                        }
                    }
                }
                for (int i = 0; i < 10; i++)
                {
                    Tick();
                }
                return(bmp);
            }
Esempio n. 19
0
        /*
         * This method looks at all the directions we could go, then rates them based on how close they will take us
         * to simulated bullets fired with both linear and head-on targeting generated by the waves we have logged.
         * It is the core of our movement.
         */
        public void chooseDirection(PointF enemyLocation, Operations operations, AdvancedRobot robot)
        {
            MovementWave w;
            //This for loop rates each angle individually
            double bestRating = Double.PositiveInfinity;

            for (double moveAngle = 0; moveAngle < Math.PI * 2; moveAngle += Math.PI / 16D)
            {
                double rating = 0;

                //Movepoint is position we would be at if we were to move one robot-length in the given direction.
                PointF movePoint = project(new PointF((float)robot.X, (float)robot.Y), 36, moveAngle);

                /*
                 * This loop will iterate through each wave and add a risk for the simulated bullets on each one
                 * to the total risk for this angle.
                 */
                for (int i = 0; i < moveWaves.Count; i++)
                {
                    w = moveWaves[i];

                    //This part will remove waves that have passed our robot, so we no longer keep taking into account old ones
                    if (new PointF((float)robot.X, (float)robot.Y).Distance(w.origin) < (robot.Time - w.startTime) * w.speed + w.speed)
                    {
                        moveWaves.Remove(w);
                    }
                    else
                    {
                        /*
                         * This adds two risks for each wave: one based on the distance from where a head-on targeting
                         * bullet would be, and one for where a linear targeting bullet would be.
                         */
                        rating += 1D /
                                  Math.Pow(
                            movePoint.Distance(project(w.origin, movePoint.Distance(w.origin), w.angle)), 2);
                        rating += 1D /
                                  Math.Pow(
                            movePoint.Distance(project(w.origin, movePoint.Distance(w.origin),
                                                       w.angle + w.latVel)), 2);
                    }
                }
                //This adds a risk associated with being to close to the other robot if there are no waves.
                if (moveWaves.Count == 0)
                {
                    rating = 1D / Math.Pow(movePoint.Distance(enemyLocation), 2);
                }
                //This part tells us to go in the direction if it is better than the previous best option and is reachable.
                if (rating < bestRating &&
                    new RectangleF(50, 50, (float)(robot.BattleFieldWidth - 100), (float)(robot.BattleFieldHeight - 100)).Contains(
                        movePoint))
                {
                    bestRating = rating;

                    /*
                     * These next three lines are a very codesize-efficient way to
                     * choose the best direction for moving to a point.
                     */
                    int pointDir;
                    operations.Ahead            = 1000 * (pointDir = (Math.Abs(moveAngle - robot.HeadingRadians) < Math.PI / 2 ? 1 : -1));
                    operations.TurnRightRadians = Utils.NormalRelativeAngle(moveAngle + (pointDir == -1 ? Math.PI : 0) - robot.HeadingRadians);
                }
            }
        }
Esempio n. 20
0
 public static bool Equivalent(this PointF a, PointF b, float epsilon = 0.01f) => a.Distance(b) < epsilon;
Esempio n. 21
0
        public Operations HandleScanedRobot(AdvancedRobot robot, ScannedRobotEvent e, ScannedRobotEvent previousScaned,
                                            Operations operations, BattleEvents battleEvents)
        {
            var newOperations = operations.Clone();

            double absoluteBearing   = robot.HeadingRadians + e.BearingRadians;
            PointF myLocation        = new PointF((float)robot.X, (float)robot.Y);
            PointF predictedLocation = projectMotion(myLocation, absoluteBearing, e.Distance);
            double predictedHeading;
            double enemyTurnRate = -Utils.NormalRelativeAngle(expectedHeading - (predictedHeading = expectedHeading = e.HeadingRadians));
            double bulletPower   = Math.Min(e.Distance < 250 ? 500 / e.Distance : 200 / e.Distance, 3);

            int time = 0;

            while ((time++) * (20 - (3 * bulletPower)) < myLocation.Distance(predictedLocation) - 18)
            {
                predictedHeading += (enemyTurnRate / 3);
                predictedLocation = projectMotion(predictedLocation, predictedHeading, e.Velocity);

                if (!new RectangleF(18, 18, 764, 564).Contains(predictedLocation))
                {
                    break;
                }
            }

            double maxValue = Double.MinValue;
            double angle    = 0;

            do
            {
                double value          = Math.Abs(Math.Cos(Utils.NormalRelativeAngle(absoluteBearing - angle))) * e.Distance / 150;
                PointF testedLocation = projectMotion(myLocation, angle, 8);

                value -= testedLocation.Distance(predictedLocation);
                value -= testedLocation.Distance(new PointF(400, 300)) / 3;

                if (!new RectangleF(30, 30, 740, 540).Contains(testedLocation))
                {
                    value -= 10000;
                }

                if (value > maxValue)
                {
                    maxValue = value;
                    double turnAngle = angle - robot.HeadingRadians;
                    if (headingEnemy)
                    {
                        newOperations.Ahead            = (Math.Cos(turnAngle) > 0 ? 100 : -100);
                        newOperations.TurnRightRadians = (Math.Tan(turnAngle));
                    }
                    else
                    {
                        var    absoluteBearingMedkit = lastMedicalKitEvent.BearingRadians + robot.HeadingRadians;
                        double turn = absoluteBearingMedkit + Math.PI / 2;
                        turn -= Math.Max(0.5, (1 / lastMedicalKitEvent.Distance) * 100) * newOperations.Direction;
                        newOperations.TurnRightRadians = Utils.NormalRelativeAngle(turn - robot.HeadingRadians);
                        newOperations.Ahead            = (Math.Cos(turn) > 0 ? 100 : -100);
                    }
                }
            } while ((angle += 0.01) < Math.PI * 2);

            robot.MaxVelocity = (Math.Abs(robot.TurnRemaining) < 30 ? 8 : 8 - Math.Abs(robot.TurnRemaining / 30));

            double gunTurn = Utils.NormalRelativeAngle(Math.Atan2(predictedLocation.X - myLocation.X, predictedLocation.Y - myLocation.Y) - robot.GunHeadingRadians);

            newOperations.TurnGunRightRadians = (gunTurn);

            if ((Math.Abs(gunTurn) < Math.PI / 9) && (robot.GunHeat == 0.0))
            {
                newOperations.BulletPower = (bulletPower);
            }

            newOperations.TurnRadarRightRadians = (2 * Utils.NormalRelativeAngle(absoluteBearing - robot.RadarHeadingRadians));

            return(newOperations);
        }
Esempio n. 22
0
        public static List <Point> FindBoundingContourPoints(IEnumerable <Point> contours, PointF[] boundingPoints)
        {
            if (boundingPoints.Length != 2)
            {
                return(null);
            }

            List <Point> contourPoints           = contours.ToList();
            List <Point> actualContourPointsList = new List <Point>();

            foreach (Point point in contourPoints)
            {
                if (!actualContourPointsList.Contains(point))
                {
                    actualContourPointsList.Add(point);
                }
                else
                {
                    break;
                }
            }

            PointF firstPoint = boundingPoints[0];
            PointF lastPoint  = boundingPoints[1];

            int    firstIndex = -1;
            int    lastIndex  = -1;
            double p1Dist     = 10000;
            double p2Dist     = 10000;

            //Loop through all the points and find the closest points to the bounds
            for (int i = 0; i < actualContourPointsList.Count; i++)
            {
                double dist1 = firstPoint.Distance(actualContourPointsList[i]);
                double dist2 = lastPoint.Distance(actualContourPointsList[i]);

                if (dist1 < p1Dist)
                {
                    p1Dist = dist1;
                    //closestFirstPoint = contourPoints[i];
                    firstIndex = i;
                }

                if (dist2 < p2Dist)
                {
                    p2Dist = dist2;
                    //closestLastPoint = contourPoints[i];
                    lastIndex = i;
                }
            }

            List <Point> result = new List <Point>();

            //Return all the points that lie between first index and last index
            int start = firstIndex <= lastIndex ? firstIndex : lastIndex;
            int end   = lastIndex >= firstIndex ? lastIndex : firstIndex;

            for (int j = start; j <= end; j++)
            {
                result.Add(actualContourPointsList[j]);
            }

            return(result);
        }
Esempio n. 23
0
        private double GetBestGapDistance(RBSK rbsk, Action <double> progressCallBack = null)
        {
            //Caluclate gap distnace if it hasn't been set
            //Auto Find the gap distance
            //Scan from 20 - 300, the range which gives us consistent results is the right one
            int start    = 20;
            int end      = 300;
            int interval = 1;

            Video.SetFrame(0);
            Image <Gray, Byte>       firstFrame = Video.GetGrayFrameImage();
            Dictionary <int, PointF> nosePoints = new Dictionary <int, PointF>();

            for (int i = start; i <= end; i += interval)
            {
                using (Image <Gray, Byte> filteredImage = firstFrame.SmoothMedian(5))
                    using (Image <Gray, Byte> binaryImage = filteredImage.ThresholdBinary(new Gray(30), new Gray(255)))
                    {
                        rbsk.Settings.GapDistance = i;
                        Point[]  temp        = null;
                        PointF[] mousePoints = RBSKService.RBSKParallel(binaryImage, rbsk, ref temp);

                        if (mousePoints != null)
                        {
                            //We've found a set of points for this gap distance, store it
                            nosePoints.Add(i, mousePoints[2]);
                        }
                    }
                double progressValue = ((i - start) / ((double)end - start)) * 100;
                if (progressCallBack != null)
                {
                    progressCallBack(progressValue);
                }
            }

            const double threshold         = 20;
            PointF?      previousPoint     = null;
            List <int>   currentSelection  = new List <int>();
            int          bestCounter       = 0;
            double       bestDistanceSoFar = -1;

            foreach (KeyValuePair <int, PointF> kvp in nosePoints)
            {
                PointF currentPoint = kvp.Value;

                //Do we have a value?
                if (previousPoint.HasValue)
                {
                    //Is the previous point within the threshold distance of the current point
                    if (currentPoint.Distance(previousPoint.Value) < threshold)
                    {
                        currentSelection.Add(kvp.Key);
                        previousPoint = currentPoint;
                    }
                    else
                    {
                        //We're not within the threshold, compare the current list to see if it's the best
                        if (currentSelection.Count > bestCounter)
                        {
                            bestCounter       = currentSelection.Count;
                            bestDistanceSoFar = currentSelection.Average();
                        }

                        currentSelection.Clear();
                        previousPoint = null;
                    }
                }
                else
                {
                    previousPoint = currentPoint;
                }
            }

            if (currentSelection.Count > bestCounter)
            {
                bestDistanceSoFar = currentSelection.Average();
            }

            if (bestDistanceSoFar == -1)
            {
                bestDistanceSoFar = 100;
            }

            return(bestDistanceSoFar);
        }
Esempio n. 24
0
        private LineSegment2D[] FindSpine(LineSegment2D[] lines, RotatedRect rotatedRectangle, Image <Gray, Byte> img, PointF headPoint, PointF tailPoint)
        {
            //LineSegment2DF[] initialLines = new LineSegment2DF[2];

            //if (!rotatedRectangle.Size.IsEmpty)
            //{
            //    //Use one of the smaller boundries from rotatedRect for initial detection
            //    PointF[] vertices = rotatedRectangle.GetVertices();
            //    PointF p1 = vertices[0];
            //    PointF p2 = vertices[1];
            //    PointF p3 = vertices[2];
            //    PointF p4 = vertices[3];

            //    //PointF p1 = new PointF(rotatedRectangle.Left, rotatedRectangle.Top);
            //    //PointF p2 = new PointF(rotatedRectangle.Left, rotatedRectangle.Bottom);
            //    //PointF p3 = new PointF(rotatedRectangle.Right, rotatedRectangle.Bottom);
            //    //PointF p4 = new PointF(rotatedRectangle.Right, rotatedRectangle.Top);

            //    if (p2.DistanceSquared(p1) < p2.DistanceSquared(p3))
            //    {
            //        //p1 and p2 are paired, p3 and p4 are paired
            //        initialLines[0] = new LineSegment2DF(p1, p2);
            //        initialLines[1] = new LineSegment2DF(p3, p4);
            //    }
            //    else
            //    {
            //        //p2 and p3 are paired, p1 and p4 are paired
            //        initialLines[0] = new LineSegment2DF(p2, p3);
            //        initialLines[1] = new LineSegment2DF(p1, p4);
            //    }
            //}
            //else
            //{
            //    //Use one of the image sides for intial detection
            //    initialLines[1] = new LineSegment2DF(new PointF(0, 0), new PointF(0, img.Height - 1));
            //    initialLines[0] = new LineSegment2DF(new PointF(img.Width - 1, 0), new PointF(img.Width - 1, img.Height - 1));
            //    //initialLines[0] = new LineSegment2DF(new PointF(0, 0), new PointF(img.Width - 1, 0));
            //    //initialLines[1] = new LineSegment2DF(new PointF(0 - 1, img.Height-1), new PointF(img.Width - 1, img.Height - 1));
            //}

            //Find closest line segment to initial line
            double minDistance = double.MaxValue;

            LineSegment2D?targetLine = null;

            foreach (LineSegment2D line in lines)
            {
                //double minDistance1 = MathExtension.MinDistanceFromLineToPoint(initialLines[0].P1, initialLines[0].P2, line.P1);
                //double minDistance2 = MathExtension.MinDistanceFromLineToPoint(initialLines[0].P1, initialLines[0].P2, line.P2);

                double minDistance1 = headPoint.DistanceSquared(line.P1);
                double minDistance2 = headPoint.DistanceSquared(line.P2);

                double currentDist = minDistance1 < minDistance2 ? minDistance1 : minDistance2;

                if (currentDist < minDistance)
                {
                    minDistance = currentDist;
                    targetLine  = line;
                }
            }

            List <LineSegment2D> previousLines = new List <LineSegment2D>();

            //We have our target line, try to traverse to the other side
            LineSegment2D?nextLine = null;

            if (targetLine.HasValue)
            {
                previousLines.Add(targetLine.Value);
            }

            do
            {
                GetValue(lines, tailPoint, previousLines.ToArray(), targetLine, ref nextLine);

                if (nextLine.HasValue)
                {
                    targetLine = nextLine;
                    previousLines.Add(nextLine.Value);
                }
            }while (nextLine.HasValue);

            if (previousLines.Count == 0)
            {
                return(null);
            }

            double minDistanceFromEnd1 = tailPoint.Distance(previousLines.Last().P1); //MathExtension.MinDistanceFromLineToPoint(initialLines[1].P1, initialLines[1].P2, previousLines.Last().P1));
            double minDistanceFromEnd2 = tailPoint.Distance(previousLines.Last().P2); //MathExtension.MinDistanceFromLineToPoint(initialLines[1].P1, initialLines[1].P2, previousLines.Last().P2);

            if (minDistanceFromEnd1 < 30 || minDistanceFromEnd2 < 30)
            {
                //Made it!
                return(previousLines.ToArray());
            }

            minDistance = double.MaxValue;

            targetLine = null;
            foreach (var line in lines)
            {
                double minDistance1 = tailPoint.Distance(line.P1); //MathExtension.MinDistanceFromLineToPoint(initialLines[1].P1, initialLines[1].P2, line.P1));
                double minDistance2 = tailPoint.Distance(line.P2); //MathExtension.MinDistanceFromLineToPoint(initialLines[1].P1, initialLines[1].P2, line.P2));

                double currentDist = minDistance1 < minDistance2 ? minDistance1 : minDistance2;

                if (currentDist < minDistance)
                {
                    minDistance = currentDist;
                    targetLine  = line;
                }
            }


            List <LineSegment2D> previousLines2 = new List <LineSegment2D>();

            //We have our target line, try to traverse to the other side
            nextLine = null;
            if (targetLine.HasValue)
            {
                previousLines2.Add(targetLine.Value);
            }

            do
            {
                GetValue(lines, headPoint, previousLines2.ToArray(), targetLine, ref nextLine);

                if (nextLine.HasValue)
                {
                    targetLine = nextLine;
                    previousLines2.Add(nextLine.Value);
                }
            }while (nextLine.HasValue);

            previousLines2.Reverse();
            previousLines.AddRange(previousLines2);

            return(previousLines.ToArray());
        }
Esempio n. 25
0
        public Meteor(Hex.OffsetCoordinates meteorCoordinates, int health, int damage, HexagonNeighborDirection movementDirection) : base(Player.None, health, ObjectType.Meteor, 1)
        {
            this.MovementDirection = movementDirection;
            this.ObjectCoordinates = meteorCoordinates;
            this.CollisionDamage   = damage;

            int meteorRadius = 15; //TODO: make meteor size dependent on it's damage

            this.ObjectAppearance = new List <DrawableShape>
            {
                new Ellipse(new Point(-meteorRadius, -meteorRadius), Colors.DarkGray, new Size(2 * meteorRadius, 2 * meteorRadius)),
            };

            var    darkSpots     = new List <Ellipse>();
            Random rand          = new Random();
            int    minSpotRadius = meteorRadius / 7;
            int    maxSpotRadius = meteorRadius / 5;

            for (int i = 0; i < 20; i++)
            {
                var spotRadius = rand.Next(minSpotRadius, maxSpotRadius + 1);

                var r   = rand.Next(spotRadius, meteorRadius - spotRadius);
                var phi = 2 * Math.PI * rand.NextDouble();
                int x   = (int)(r * Math.Cos(phi)) - spotRadius;
                int y   = (int)(r * Math.Sin(phi)) - spotRadius;

                var spotCenter = new PointF(x + spotRadius, y + spotRadius);
                if (!darkSpots.Any(existingSpot => spotCenter.Distance(existingSpot.Origin + existingSpot.Size / 2) < spotRadius + existingSpot.Size.Width))
                {
                    darkSpots.Add(new Ellipse(new Point(x, y), Colors.DimGray, new Size(2 * spotRadius, 2 * spotRadius)));
                }
            }
            this.ObjectAppearance.AddRange(darkSpots);


            var flameSweepsOnMeteor = new Dictionary <Color, double> {
                { Colors.Orange, 2 * Math.PI / 3 }, { Colors.Red, Math.PI / 4 }
            };
            var flameSpanAngle = Math.PI / 4;

            foreach (var flameSweep in flameSweepsOnMeteor)
            {
                float flameBaseLengthHalf = meteorRadius * (float)Math.Sin(flameSweep.Value / 2);
                float flameHeight         = flameBaseLengthHalf / (float)Math.Tan(flameSpanAngle / 2);
                float flameTipOffset      = meteorRadius * (float)Math.Cos(flameSweep.Value / 2) + flameHeight;
                // arcSpanAngle = 180 - 2 * (90 - flameSpanAngle/2) = 180 - 180 + 2 * flameSpanAngle/2 = flameSpanAngle
                float arcRadius = flameHeight / (float)Math.Sin(flameSpanAngle);

                var pathComponents = new List <DrawableShape>
                {
                    new Arc(new Point(-meteorRadius, -meteorRadius),
                            new SizeF(2 * meteorRadius, 2 * meteorRadius),
                            180 - (float)(flameSweep.Value.ToDegrees() / 2),
                            (float)flameSweep.Value.ToDegrees()),
                    new Arc(new PointF(-flameTipOffset - arcRadius, -2 * arcRadius),
                            new SizeF(2 * arcRadius, 2 * arcRadius),
                            90 - (float)flameSpanAngle.ToDegrees(),
                            (float)flameSpanAngle.ToDegrees()),
                    new Arc(new PointF(-flameTipOffset - arcRadius, 0),
                            new SizeF(2 * arcRadius, 2 * arcRadius),
                            -90,
                            (float)flameSpanAngle.ToDegrees())
                };
                this.ObjectAppearance.Add(new Path(new Point(0, 0), flameSweep.Key, pathComponents));
            }
        }
Esempio n. 26
0
        public List <List <PointF> > FindKeyPoints(Point[] points, int numberOfSlides, bool removeDuplicates = true)
        {
            //Stopwatch sw = new Stopwatch();
            //sw.Start();
            //Point[] allPoints = points.ToArray();
            List <List <PointF> > result = new List <List <PointF> >();

            if (points.Length <= 1)
            {
                return(result);
            }

            int listCounter = 0;

            for (int i = 0; i <= numberOfSlides; i++)
            {
                result.Add(new List <PointF>());
            }

            List <PointF> visitedPoints = new List <PointF>();
            PointF        currentPoint  = points[0];

            if (removeDuplicates)
            {
                visitedPoints.Add(currentPoint);
            }

            double distanceCounter = 0;
            double offset          = Settings.GapDistance / numberOfSlides;

            result[listCounter].Add(currentPoint);
            listCounter++;

            if (listCounter > numberOfSlides)
            {
                listCounter = 0;
            }

            int pointCounter = 0;
            int targetLimit  = Settings.NumberOfPoints + 1;
            int limitCounter = 0;
            int?targetList   = null;

            while (true)
            {
                Point targetPoint = points[pointCounter];

                double dist = currentPoint.Distance(targetPoint);

                if (distanceCounter + dist >= offset)
                {
                    StraightLine line     = new StraightLine(currentPoint, targetPoint);
                    double       addOn    = offset - distanceCounter;
                    PointF       keyPoint = line.DistanceFromStartFloat(addOn);
                    result[listCounter].Add(keyPoint);

                    if (listCounter == targetList)
                    {
                        limitCounter++;

                        if (limitCounter == targetLimit)
                        {
                            break;
                        }
                    }

                    listCounter++;

                    if (listCounter > numberOfSlides)
                    {
                        listCounter = 0;
                    }

                    currentPoint    = keyPoint;
                    distanceCounter = 0;
                }
                else
                {
                    distanceCounter += dist;
                    currentPoint     = points[pointCounter];
                    pointCounter++;

                    if (pointCounter == points.Length)
                    {
                        targetList    = listCounter;
                        pointCounter -= points.Length;
                    }

                    if (removeDuplicates)
                    {
                        if (visitedPoints.Contains(points[pointCounter]))
                        {
                            break;
                        }
                        else
                        {
                            visitedPoints.Add(points[pointCounter]);
                        }
                    }
                }
            }

            //sw.Stop();
            //Console.WriteLine("FindKeyPoints: " + sw.ElapsedMilliseconds);
            return(result);
        }
Esempio n. 27
0
        private Dictionary <int, ISingleFrameResult> GenerateDictionary()
        {
            //const int SecondBinaryThresold = 10;
            const double movementDelta = 15;

            Services.RBSK.RBSK rbsk = MouseService.GetStandardMouseRules();

            if (GapDistance <= 0)
            {
                GapDistance = GetBestGapDistance(rbsk);
            }

            rbsk.Settings.GapDistance     = GapDistance;
            rbsk.Settings.BinaryThreshold = ThresholdValue;

            Dictionary <int, ISingleFrameResult> results = new Dictionary <int, ISingleFrameResult>();

            Video.Reset();
            int counter = 0;

            int frameCount = Video.FrameCount;

            while (true)
            {
                if (Paused)
                {
                    continue;
                }

                if (Cancelled)
                {
                    break;
                }

                using (Image <Bgr, byte> frame = Video.GetFrameImage())
                {
                    if (frame == null)
                    {
                        break;
                    }

                    if (Roi != Rectangle.Empty)
                    {
                        frame.ROI = Roi;
                    }

                    double waist, waistArea, waistArea2, waistArea3, waistArea4;
                    PointF centroid;

                    //if (counter == 500)
                    //{
                    //    frame.ROI = new Rectangle(0,0,1,1);
                    //}

                    PointF[] headPoints = ProcessFrame(frame, rbsk, out waist, out waistArea, out waistArea2, out waistArea3, out waistArea4, out centroid, true);

                    if (Roi != Rectangle.Empty)
                    {
                        centroid.X += Roi.X;
                        centroid.Y += Roi.Y;

                        if (headPoints != null)
                        {
                            headPoints[0].X += Roi.X;
                            headPoints[0].Y += Roi.Y;
                            headPoints[1].X += Roi.X;
                            headPoints[1].Y += Roi.Y;
                            headPoints[2].X += Roi.X;
                            headPoints[2].Y += Roi.Y;
                            headPoints[3].X += Roi.X;
                            headPoints[3].Y += Roi.Y;
                            headPoints[4].X += Roi.X;
                            headPoints[4].Y += Roi.Y;
                        }
                    }

                    //Console.WriteLine(waist + " " + waistArea);
                    //if (headPoints != null)
                    //{
                    //    foreach (var point in headPoints)
                    //    {
                    //        frame.Draw(new CircleF(point, 2), new Bgr(Color.Yellow), 2);
                    //    }
                    //}

                    //ImageViewer.Show(frame);
                    ISingleFrameResult frameResult = ModelResolver.Resolve <ISingleFrameResult>();
                    frameResult.HeadPoints   = headPoints;
                    frameResult.CentroidSize = waist;
                    frameResult.PelvicArea   = waistArea;
                    frameResult.PelvicArea2  = waistArea2;
                    frameResult.PelvicArea3  = waistArea3;
                    frameResult.PelvicArea4  = waistArea4;
                    frameResult.Centroid     = centroid;
                    results.Add(counter, frameResult);
                    counter++;

                    if (ProgressUpdates != null)
                    {
                        ProgressUpdates(this, new RBSKVideoUpdateEvent((double)counter / frameCount));
                    }
                }
            }

            if (Cancelled)
            {
                return(results);
            }

            //Find the most confident run of head detections
            List <List <HeadPointHolder> > confidentPoints = new List <List <HeadPointHolder> >();
            PointF lastPoint = PointF.Empty;
            List <HeadPointHolder> currentList = new List <HeadPointHolder>();
            double currentTotalMovement        = 0;

            for (int i = 0; i < results.Count; i++)
            {
                PointF[] headPoints = results[i].HeadPoints;

                if (headPoints == null)
                {
                    //No head found, use alternative methods
                    if (currentList.Count > 0)
                    {
                        confidentPoints.Add(currentList);
                    }
                    currentList          = new List <HeadPointHolder>();
                    lastPoint            = PointF.Empty;
                    currentTotalMovement = 0;
                    //Console.WriteLine("Head points are null " + i);
                    continue;
                }

                //Check against expected position
                PointF currentPoint = headPoints[2];

                if (lastPoint.IsEmpty)
                {
                    lastPoint = currentPoint;
                    currentList.Add(new HeadPointHolder(i, currentPoint, currentTotalMovement));
                    continue;
                }

                double distance = lastPoint.Distance(currentPoint);
                if (distance < movementDelta)
                {
                    //Acceptable
                    currentTotalMovement += distance;
                    currentList.Add(new HeadPointHolder(i, currentPoint, currentTotalMovement));
                    lastPoint = currentPoint;
                }
                else
                {
                    if (currentList.Count > 0)
                    {
                        confidentPoints.Add(currentList);
                    }
                    currentList          = new List <HeadPointHolder>();
                    lastPoint            = PointF.Empty;
                    currentTotalMovement = 0;
                    //Console.WriteLine("Outside of range " + i);
                }
            }

            if (currentList.Count > 0)
            {
                confidentPoints.Add(currentList);
            }

            if (confidentPoints.Count == 0)
            {
                return(results);
            }

            //Find longest list with highest total movement
            List <HeadPointHolder> bestList = confidentPoints[0];

            //double currentMaxTraverse = bestList.Last().TotalDelta;
            foreach (List <HeadPointHolder> list in confidentPoints)
            {
                //double currentTotalDelta = list.Last().TotalDelta;
                if (list.Count > bestList.Count)
                {
                    //currentMaxTraverse = currentTotalDelta;
                    bestList = list;
                }
            }

            //We now have a confident set of headpoints
            int minIndex = bestList.Select(x => x.FrameNumber).Min();
            int maxIndex = bestList.Select(x => x.FrameNumber).Max();


            minIndex--;
            while (minIndex >= 0)
            {
                //Traverse backwards
                PointF[] lastPoints = results[minIndex + 1].HeadPoints;
                if (lastPoints != null)
                {
                    lastPoint = lastPoints[2];
                }
                else
                {
                    lastPoint = new PointF(-100, -100);
                }

                PointF[] headPoints = results[minIndex].HeadPoints;

                if (headPoints == null)
                {
                    //No head found, use alternative methods
                    int previousThreshold = rbsk.Settings.BinaryThreshold;
                    rbsk.Settings.BinaryThreshold = ThresholdValue2;
                    Video.SetFrame(minIndex);
                    PointF[] headPoints2 = null;
                    using (Image <Bgr, byte> frame = Video.GetFrameImage())
                    {
                        if (frame == null)
                        {
                            break;
                        }

                        if (Roi != Rectangle.Empty)
                        {
                            frame.ROI = Roi;
                        }

                        headPoints2 = ProcessFrame(frame, rbsk, lastPoint, movementDelta);
                    }

                    rbsk.Settings.BinaryThreshold = previousThreshold;

                    if (headPoints2 != null)
                    {
                        //We've got a good location
                        //double temp = results[minIndex].CentroidSize;
                        results[minIndex].HeadPoints = headPoints2;
                        //results[minIndex].CentroidSize = temp;
                        //results[minIndex] = new Tuple<PointF[], double>(headPoints2, temp);
                    }
                    else
                    {
                        for (int i = 0; i <= minIndex; i++)
                        {
                            if (results.ContainsKey(i))
                            {
                                //double temp = results[i].Item2;
                                //results[i] = new Tuple<PointF[], double>(null, temp);
                                results[i].HeadPoints = null;
                            }
                        }

                        break;
                    }

                    minIndex--;
                    continue;
                }

                //Check against expected position
                PointF currentPoint = headPoints[2];

                if (lastPoint.Distance(currentPoint) < movementDelta)
                {
                    //Good point
                }
                else
                {
                    //Wrong point, search for another rbsk that falls within range
                    //if (minIndex == 17 || minIndex == 16)
                    //{
                    //    Console.WriteLine("");
                    //}

                    Video.SetFrame(minIndex);
                    PointF[] headPoints2 = null;
                    using (Image <Bgr, byte> frame = Video.GetFrameImage())
                    {
                        if (frame == null)
                        {
                            break;
                        }

                        if (Roi != Rectangle.Empty)
                        {
                            frame.ROI = Roi;
                        }

                        headPoints2 = ProcessFrame(frame, rbsk, lastPoint, movementDelta);
                    }

                    if (headPoints2 != null)
                    {
                        //We've got a good location
                        //double temp = results[maxIndex].Item2;
                        //results[minIndex] = new Tuple<PointF[], double>(headPoints2, temp);
                        results[minIndex].HeadPoints = headPoints2;
                    }
                    else
                    {
                        //No other rbsk falls within range, use alternative methods
                        //Console.WriteLine("Need to use alternative methods");
                        for (int i = 0; i <= minIndex; i++)
                        {
                            if (results.ContainsKey(i))
                            {
                                //double temp = results[i].Item2;
                                //results[i] = new Tuple<PointF[], double>(null, temp);
                                results[i].HeadPoints = null;
                            }
                        }

                        break;
                    }
                }

                minIndex--;
            }

            maxIndex++;
            while (maxIndex < results.Count)
            {
                //Traverse backwards
                PointF[] lastPoints = results[maxIndex - 1].HeadPoints;
                if (lastPoints != null)
                {
                    lastPoint = lastPoints[2];
                }
                else
                {
                    lastPoint = new PointF(-100, -100);
                }

                PointF[] headPoints = results[maxIndex].HeadPoints;


                if (headPoints == null)
                {
                    //No head found, use alternative methods
                    int previousThreshold = rbsk.Settings.BinaryThreshold;
                    rbsk.Settings.BinaryThreshold = ThresholdValue2;
                    Video.SetFrame(maxIndex);
                    PointF[] headPoints2 = null;
                    using (Image <Bgr, byte> frame = Video.GetFrameImage())
                    {
                        if (frame == null)
                        {
                            break;
                        }

                        if (Roi != Rectangle.Empty)
                        {
                            frame.ROI = Roi;
                        }

                        headPoints2 = ProcessFrame(frame, rbsk, lastPoint, movementDelta);
                    }

                    rbsk.Settings.BinaryThreshold = previousThreshold;

                    if (headPoints2 != null)
                    {
                        //We've got a good location
                        //double temp = results[maxIndex].Item2;
                        //results[maxIndex] = new Tuple<PointF[], double>(headPoints2, temp);
                        results[maxIndex].HeadPoints = headPoints2;
                    }
                    else
                    {
                        int max = results.Keys.Max();
                        for (int i = maxIndex; i <= max; i++)
                        {
                            if (results.ContainsKey(i))
                            {
                                //double temp = results[i].Item2;
                                //results[i] = new Tuple<PointF[], double>(null, temp);
                                results[i].HeadPoints = null;
                            }
                        }

                        break;
                    }

                    maxIndex++;
                    continue;
                }

                //Check against expected position
                PointF currentPoint = headPoints[2];

                if (lastPoint.Distance(currentPoint) < movementDelta)
                {
                    //Good point
                }
                else
                {
                    //Wrong point, search for another rbsk that falls within range
                    Video.SetFrame(maxIndex);
                    PointF[] headPoints2 = null;
                    using (Image <Bgr, byte> frame = Video.GetFrameImage())
                    {
                        if (frame == null)
                        {
                            break;
                        }

                        if (Roi != Rectangle.Empty)
                        {
                            frame.ROI = Roi;
                        }

                        headPoints2 = ProcessFrame(frame, rbsk, lastPoint, movementDelta);
                    }

                    if (headPoints2 != null)
                    {
                        //We've got a good location
                        //double temp = results[maxIndex].Item2;
                        //results[maxIndex] = new Tuple<PointF[], double>(headPoints2, temp);
                        results[maxIndex].HeadPoints = headPoints2;
                    }
                    else
                    {
                        //No other rbsk falls within range, use alternative methods
                        //Console.WriteLine("Need to use alternative methods");
                        int max = results.Keys.Max();
                        for (int i = maxIndex; i <= max; i++)
                        {
                            if (results.ContainsKey(i))
                            {
                                //double temp = results[i].Item2;
                                //results[i] = new Tuple<PointF[], double>(null, temp);
                                results[i].HeadPoints = null;
                            }
                        }

                        break;
                    }
                }

                maxIndex++;
            }

            return(results);
        }
Esempio n. 28
0
        private void EditorWindow_MouseMove(object sender, MouseEventArgs e)
        {
            StatusBar.Message($"X: {e.X} , Y: {e.Y}");
            if (ActiveCommand != DrawCommands.Noun && clickCount >= 1)
            {
                //delta_Y = p2.Sub(e.Location);

                var offsetPoint = new PointF(offsetX, offsetY).Scale(Zoom);
                p2 = (new PointF(e.X, e.Y).Sub(offsetPoint)).Scale(1 / Zoom);


                switch (ActiveCommand)
                {
                case DrawCommands.Line:
                    #region Line
                    tempShape = new GLine(p1, p2);
                    #endregion

                    break;

                case DrawCommands.Circle:
                    #region Circle
                    tempShape = new GCircle(p1, p1.Distance(p2));
                    Debug.WriteLine($"x:{p1.X},Y:{p1.Y},R:{p1.Distance(p2)}");
                    Debug.WriteLine($"offsetX:{offsetX},OffsetY:{ offsetY}");
                    #endregion
                    break;

                case DrawCommands.Rectangle:
                    #region Rectangle
                    tempShape = new GRectangle(p1, p2);
                    #endregion
                    break;

                case DrawCommands.PolyLine:
                    #region PolyLine
                    tempShape = tempPolyLine;
                    if (clickCount == 1)
                    {
                        if (tempPolyLine == null)
                        {
                            tempPolyLine = new GPolyLine();
                            tempPolyLine.Lines.Add(new GLine(p1, p2));
                        }
                        else
                        {
                            tempPolyLine.Lines.LastOrDefault().EndPoint = p2;
                        }
                    }
                    else if (clickCount == 2)
                    {
                        //check end line position to exit or continue drawing.

                        var prevLine = tempPolyLine.Lines.LastOrDefault();
                        tempPolyLine.Lines.Add(new GLine(prevLine.EndPoint, p2));

                        if (p2.Distance(tempPolyLine.Lines.FirstOrDefault().StartPoint) < Setup.Snap)
                        {
                            GeometryEngine.AddShape(tempShape);
                            clickCount   = 0;
                            tempShape    = null;
                            tempPolyLine = null;
                            // ActiveCommand = DrawCommands.Noun;
                        }
                        else
                        {
                            clickCount--;
                        }
                    }
                    #endregion
                    break;

                case DrawCommands.Curve:

                    #region Curve

                    if (clickCount == 1)
                    {
                        tempShape = new GLine(p1, p2);
                    }

                    else if (clickCount == 2)
                    {
                        if (tempShape is GCurve)
                        {
                            ((GCurve)tempShape).Center = p2;
                        }
                        else
                        {
                            var l = (GLine)tempShape;

                            tempShape = new GCurve(l.StartPoint, p2, l.EndPoint);
                        }
                    }
                    else if (clickCount == 3)
                    {
                        ((GCurve)tempShape).Center = p2;
                        GeometryEngine.AddShape(tempShape);
                        clickCount = 0;
                    }

                    #endregion
                    break;

                case DrawCommands.Parabola:
                    #region Parabola
                    if (clickCount == 1)
                    {
                        tempShape = new GLine(p1, p2);
                    }

                    else if (clickCount == 2)
                    {
                        if (tempShape is GParabola)
                        {
                            ((GParabola)tempShape).Points[2] = p2;
                        }
                        else
                        {
                            var l = (GLine)tempShape;

                            tempShape = new GParabola(l.StartPoint, l.EndPoint, p2);
                        }
                    }
                    else if (clickCount == 3)
                    {
                        ((GParabola)tempShape).Points[2] = p2;
                        GeometryEngine.AddShape(tempShape);
                        clickCount = 0;
                    }
                    #endregion
                    break;

                case DrawCommands.Clear:
                    break;

                case DrawCommands.Noun:
                    break;

                default:
                    break;
                }
                EditorWindow.Invalidate();
            }
            else if (clickCount == 0)
            {
                MouseEventArgs mouse = e as MouseEventArgs;

                if (mouse.Button == MouseButtons.Left)
                {
                    Point mousePosNow = mouse.Location;

                    int deltaX = mousePosNow.X - mouseDown.X; // the distance the mouse has been moved since mouse was pressed
                    int deltaY = mousePosNow.Y - mouseDown.Y;

                    offsetX = (int)(startx + (deltaX / Zoom));  // calculate new offset of image based on the current zoom factor
                    offsetY = (int)(starty + (deltaY / Zoom));

                    EditorWindow.Invalidate();
                }
            }
        }
Esempio n. 29
0
        public List <PointF> FindKeyPoints(Point[] points, float offset = 0, bool removeDuplicates = true)
        {
            //Stopwatch sw = new Stopwatch();
            //sw.Start();
            //Point[] allPoints = points.ToArray();
            List <PointF> result        = new List <PointF>();
            List <PointF> visitedPoints = new List <PointF>();
            PointF        currentPoint  = points[0];

            if (removeDuplicates)
            {
                visitedPoints.Add(currentPoint);
            }

            double distanceCounter = 0;

            if (offset == 0)
            {
                result.Add(currentPoint);
            }
            else
            {
                distanceCounter += offset;
            }

            int pointCounter = 1;

            while (true)
            {
                Point targetPoint = points[pointCounter];

                double dist = currentPoint.Distance(targetPoint);

                if (distanceCounter + dist >= Settings.GapDistance)
                {
                    StraightLine line     = new StraightLine(currentPoint, targetPoint);
                    double       addOn    = Settings.GapDistance - distanceCounter;
                    PointF       keyPoint = line.DistanceFromStart(addOn);
                    result.Add(keyPoint);
                    currentPoint    = keyPoint;
                    distanceCounter = 0;
                }
                else
                {
                    distanceCounter += dist;
                    currentPoint     = points[pointCounter];
                    pointCounter++;

                    if (pointCounter == points.Length)
                    {
                        break;
                    }

                    if (removeDuplicates)
                    {
                        if (visitedPoints.Contains(points[pointCounter]))
                        {
                            break;
                        }
                        else
                        {
                            visitedPoints.Add(points[pointCounter]);
                        }
                    }
                }
            }

            //sw.Stop();
            //Console.WriteLine("FindKeyPoints: " + sw.ElapsedMilliseconds);
            return(result);
        }
Esempio n. 30
0
        public void FindTail(Point[] mouseContour, PointF[] spine, Image <Bgr, Byte> drawImage, double width, PointF centroid, out List <Point> bodyPoints, out double waistLength, out double pelvicArea, out double pelvicArea2)
        {
            //Generate graph for both sides of spine
            List <Tuple <PointF, double> > r1Distances = new List <Tuple <PointF, double> >();
            List <Tuple <PointF, double> > r2Distances = new List <Tuple <PointF, double> >();

            double halfWidth    = width / 2;
            double quarterWidth = halfWidth / 2;
            //Console.WriteLine("Quarter Width: " + quarterWidth);
            //bool bodyStarted1 = false, bodyStarted2 = false;
            //bool bodyEnded1 = false, bodyEnded2 = false;
            PointF r1BodyStart = PointF.Empty, r1BodyEnd = PointF.Empty, r2BodyStart = PointF.Empty, r2BodyEnd = PointF.Empty;

            for (int i = 1; i < spine.Length; i++)
            {
                LineSegment2DF line = new LineSegment2DF(spine[i - 1], spine[i]);

                //Create direction vector
                Vector lineDirection = new Vector(line.P2.X - line.P1.X, line.P2.Y - line.P1.Y);
                lineDirection.Normalize();

                //Create vector perpendicular to spine
                Vector r1 = new Vector(lineDirection.Y, -lineDirection.X);
                Vector r2 = new Vector(-lineDirection.Y, lineDirection.X);

                //Get starting point
                Vector startingPoint = new Vector(line.P1.X, line.P1.Y);

                //We have our vectors for this part of the spine, iterate over spine length by 1
                double length = line.Length;

                for (int spinePos = 0; spinePos < length; spinePos++)
                {
                    Vector p = startingPoint + (spinePos * lineDirection);

                    Vector test  = p + (r1 * 300);
                    Vector test2 = p + (r2 * 300);

                    PointF start = new PointF((float)p.X, (float)p.Y);
                    PointF p1    = new PointF((float)test.X, (float)test.Y);
                    PointF p2    = new PointF((float)test2.X, (float)test2.Y);

                    PointF intersect1 = MathExtension.PolygonLineIntersectionPoint(start, p1, mouseContour);
                    PointF intersect2 = MathExtension.PolygonLineIntersectionPoint(start, p2, mouseContour);

                    if (!intersect1.IsEmpty)
                    {
                        double distance = intersect1.Distance(start);
                        r1Distances.Add(new Tuple <PointF, double>(intersect1, distance));
                    }

                    if (!intersect2.IsEmpty)
                    {
                        double distance = intersect2.Distance(start);
                        r2Distances.Add(new Tuple <PointF, double>(intersect2, distance));
                    }
                }
            }

            //Iterate forwards to find body start, backwards to find body end
            int r1Count = r1Distances.Count;

            for (int i = 0; i < r1Count; i++)
            {
                Tuple <PointF, double> currentItem = r1Distances.ElementAt(i);
                if (currentItem.Item2 > quarterWidth)
                {
                    r1BodyStart = currentItem.Item1;
                    break;
                }
            }

            for (int i = r1Count - 1; i >= 0; i--)
            {
                Tuple <PointF, double> currentItem = r1Distances.ElementAt(i);
                if (currentItem.Item2 > quarterWidth)
                {
                    r1BodyEnd = currentItem.Item1;
                    break;
                }
            }

            int r2Count = r2Distances.Count;

            for (int i = 0; i < r2Count; i++)
            {
                Tuple <PointF, double> currentItem = r2Distances.ElementAt(i);
                if (currentItem.Item2 > quarterWidth)
                {
                    r2BodyStart = currentItem.Item1;
                    break;
                }
            }

            for (int i = r2Count - 1; i >= 0; i--)
            {
                Tuple <PointF, double> currentItem = r2Distances.ElementAt(i);
                if (currentItem.Item2 > quarterWidth)
                {
                    r2BodyEnd = currentItem.Item1;
                    break;
                }
            }

            if (r1BodyStart.IsEmpty || r1BodyEnd.IsEmpty || r2BodyStart.IsEmpty || r2BodyEnd.IsEmpty)
            {
                bodyPoints  = null;
                waistLength = -1;
                pelvicArea  = -1;
                pelvicArea2 = -1;
                return;
            }

            Point[] alternateSegment1 = MathExtension.GetSegmentOfPolygon(mouseContour, r1BodyStart, r2BodyStart);
            Point[] alternateSegment2 = MathExtension.GetSegmentOfPolygon(mouseContour, r1BodyEnd, r2BodyEnd);

            if (alternateSegment1 == null || alternateSegment1.Length == 0 || alternateSegment2 == null || alternateSegment2.Length == 0)
            {
                bodyPoints  = null;
                waistLength = -1;
                pelvicArea  = -1;
                pelvicArea2 = -1;
                return;
            }

            for (int i = 1; i < alternateSegment1.Length; i++)
            {
                LineSegment2D line = new LineSegment2D(alternateSegment1[i - 1], alternateSegment1[i]);
                drawImage.Draw(line, new Bgr(Color.Green), 2);
            }

            for (int i = 1; i < alternateSegment2.Length; i++)
            {
                LineSegment2D line = new LineSegment2D(alternateSegment2[i - 1], alternateSegment2[i]);
                drawImage.Draw(line, new Bgr(Color.Red), 2);
            }

            Point[] bodySegment1 = MathExtension.GetSegmentOfPolygon(mouseContour, r1BodyStart, r1BodyEnd);
            Point[] bodySegment2 = MathExtension.GetSegmentOfPolygon(mouseContour, r2BodyStart, r2BodyEnd);

            if (bodySegment1 == null || bodySegment2 == null || bodySegment1.Length == 0 || bodySegment2.Length == 0)
            {
                bodyPoints  = null;
                waistLength = -1;
                pelvicArea  = -1;
                pelvicArea2 = -1;
                return;
            }

            double d1 = alternateSegment2[0].DistanceSquared(bodySegment2[0]);
            double d2 = alternateSegment2[0].DistanceSquared(bodySegment2.Last());
            double d3 = alternateSegment2[0].DistanceSquared(bodySegment1[0]);
            double d4 = alternateSegment2[0].DistanceSquared(bodySegment1.Last());

            Point[] noTailPoints = null;
            if (d1 < d2 && d1 < d3 && d1 < d4)
            {
                Point[] p1 = bodySegment2.Reverse().ToArray();
                Point[] p2 = alternateSegment2;
                Point[] p3 = null;
                double  f1 = alternateSegment2.Last().DistanceSquared(bodySegment1[0]);
                double  f2 = alternateSegment2.Last().DistanceSquared(bodySegment1.Last());

                if (f1 < f2)
                {
                    p3 = bodySegment1;
                }
                else
                {
                    p3 = bodySegment1.Reverse().ToArray();
                }

                noTailPoints = p1.Concat(p2).Concat(p3).ToArray();
            }
            else if (d2 < d3 && d2 < d4)
            {
                Point[] p1 = bodySegment2;
                Point[] p2 = alternateSegment2;
                Point[] p3 = null;
                double  f1 = alternateSegment2.Last().DistanceSquared(bodySegment1[0]);
                double  f2 = alternateSegment2.Last().DistanceSquared(bodySegment1.Last());

                if (f1 < f2)
                {
                    p3 = bodySegment1;
                }
                else
                {
                    p3 = bodySegment1.Reverse().ToArray();
                }

                noTailPoints = p1.Concat(p2).Concat(p3).ToArray();
            }
            else if (d3 < d4)
            {
                Point[] p1 = bodySegment1;
                Point[] p2 = alternateSegment2;
                Point[] p3 = null;
                double  f1 = alternateSegment2.Last().DistanceSquared(bodySegment2[0]);
                double  f2 = alternateSegment2.Last().DistanceSquared(bodySegment2.Last());

                if (f1 < f2)
                {
                    p3 = bodySegment2;
                }
                else
                {
                    p3 = bodySegment2.Reverse().ToArray();
                }

                noTailPoints = p1.Concat(p2).Concat(p3).ToArray();
            }
            else
            {
                Point[] p1 = bodySegment1;
                Point[] p2 = alternateSegment2;
                Point[] p3 = null;
                double  f1 = alternateSegment2.Last().DistanceSquared(bodySegment2[0]);
                double  f2 = alternateSegment2.Last().DistanceSquared(bodySegment2.Last());

                if (f1 < f2)
                {
                    p3 = bodySegment2;
                }
                else
                {
                    p3 = bodySegment2.Reverse().ToArray();
                }

                noTailPoints = p1.Concat(p2).Concat(p3).ToArray();
            }


            RotatedRect rotatedRect = CvInvoke.MinAreaRect(noTailPoints.Select(x => new PointF(x.X, x.Y)).ToArray());


            //bodyPoints = new List<Point>(noTailPoints);

            //PointF lastTail = alternateSegment1[0];
            //PointF[] allBody = bodySegment1.Concat(bodySegment2.Reverse()).Select(x => new PointF(x.X, x.Y)).ToArray();
            //Point[] allBody = mouseContour;
            double spineDistance1  = SpineExtension.FindDistanceAlongSpine(spine, centroid);
            double spineDistance2  = SpineExtension.FindDistanceAlongSpine(spine, alternateSegment1[0]);
            double halfWayDistance = (spineDistance1 + spineDistance2) / 2d;
            //Console.WriteLine("Spine Distance from point: " + spineDistance1);
            //spineDistance1 += 50;

            PointF intersection;
            Vector targetDirection2;

            PointF intersection2;
            Vector targetDirection3;

            PointF intersection3;
            Vector targetDirection4;

            bool result  = SpineExtension.GetPerpendicularLineDistanceFromBase(spine, spineDistance1, out intersection, out targetDirection2);
            bool result2 = SpineExtension.GetPerpendicularLineDistanceFromBase(spine, halfWayDistance, out intersection2, out targetDirection3);
            bool result3 = SpineExtension.GetPerpendicularLineDistanceFromBase(spine, spineDistance2, out intersection3, out targetDirection4);


            PointF[] temp = rotatedRect.GetVertices();

            bool   widthShorter = temp[1].DistanceSquared(temp[0]) < temp[1].DistanceSquared(temp[2]);
            Vector targetDirection;

            if (widthShorter)
            {
                targetDirection = new Vector(temp[1].X - temp[0].X, temp[1].Y - temp[0].Y);
            }
            else
            {
                targetDirection = new Vector(temp[1].X - temp[2].X, temp[1].Y - temp[2].Y);
            }


            if (!result)
            {
                //Console.WriteLine("Unable to get perpendiular length");
                bodyPoints  = null;
                waistLength = -1;
                pelvicArea  = -1;
                pelvicArea2 = -1;
                return;
            }

            PointF i1 = new PointF(intersection.X + (float)(targetDirection.X * 100), intersection.Y + (float)(targetDirection.Y * 100));
            PointF i2 = new PointF(intersection.X + (float)(targetDirection.X * -100), intersection.Y + (float)(targetDirection.Y * -100));

            PointF i3 = new PointF(intersection2.X + (float)(targetDirection.X * 100), intersection2.Y + (float)(targetDirection.Y * 100));
            PointF i4 = new PointF(intersection2.X + (float)(targetDirection.X * -100), intersection2.Y + (float)(targetDirection.Y * -100));

            PointF i5 = new PointF(intersection3.X + (float)(targetDirection.X * 100), intersection3.Y + (float)(targetDirection.Y * 100));
            PointF i6 = new PointF(intersection3.X + (float)(targetDirection.X * -100), intersection3.Y + (float)(targetDirection.Y * -100));


            PointF bodyI1 = MathExtension.PolygonLineIntersectionPoint(intersection, i1, mouseContour);
            PointF bodyI2 = MathExtension.PolygonLineIntersectionPoint(intersection, i2, mouseContour);

            PointF bodyI3 = MathExtension.PolygonLineIntersectionPoint(intersection2, i3, mouseContour);
            PointF bodyI4 = MathExtension.PolygonLineIntersectionPoint(intersection2, i4, mouseContour);

            PointF bodyI5 = MathExtension.PolygonLineIntersectionPoint(intersection3, i5, mouseContour);
            PointF bodyI6 = MathExtension.PolygonLineIntersectionPoint(intersection3, i6, mouseContour);

            //drawImage.Draw(new CircleF(bodyI1, 4), new Bgr(Color.Red), 3);
            //drawImage.Draw(new CircleF(bodyI2, 4), new Bgr(Color.Red), 3);
            //drawImage.Draw(new CircleF(bodyI3, 4), new Bgr(Color.Red), 3);
            //drawImage.Draw(new CircleF(bodyI4, 4), new Bgr(Color.Red), 3);
            //drawImage.Draw(new CircleF(bodyI5, 4), new Bgr(Color.Red), 3);
            //drawImage.Draw(new CircleF(bodyI6, 4), new Bgr(Color.Red), 3);

            //drawImage.Draw(new LineSegment2DF(bodyI3, bodyI4), new Bgr(Color.Yellow), 3);
            //drawImage.Draw(new LineSegment2DF(bodyI5, bodyI6), new Bgr(Color.Red), 3);

            drawImage.Draw(new LineSegment2DF(bodyI1, bodyI2), new Bgr(Color.MediumPurple), 3);
            //drawImage.Draw(new LineSegment2DF(bodyI3, bodyI4), new Bgr(Color.MediumPurple), 3);
            waistLength = bodyI1.Distance(bodyI2);
            //Console.WriteLine("Waist Length = " + waistLength);
            //List<Point> tempBodyPoints = new List<Point>();

            //double r1BodyStartToTail = r1BodyStart.DistanceSquared(alternateSegment1[0]);
            //double r1BodyEndToTail = r1BodyEnd.DistanceSquared(alternateSegment1[0]);

            //bool startCloser = r1BodyStartToTail < r1BodyEndToTail;

            //if (!r1BodyStart.IsEmpty && !r1BodyEnd.IsEmpty)
            //{
            //    //Find segment from mouse contour
            //    Point[] bodySegment = MathExtension.GetSegmentOfPolygon(mouseContour, r1BodyStart, r1BodyEnd);
            //    //tempBodyPoints.AddRange(bodySegment);

            //    ////PointF midPoint = r1BodyStart.MidPoint(r1BodyEnd);
            //    //Point[] newBodySegment;
            //    //if (startCloser)
            //    //{
            //    //    newBodySegment = MathExtension.GetSegmentOfPolygon(mouseContour, bodyI3, bodyI5);
            //    //}
            //    //else
            //    //{
            //    //    newBodySegment = MathExtension.GetSegmentOfPolygon(mouseContour, bodyI5, bodyI3);
            //    //}

            //    //tempBodyPoints.AddRange(newBodySegment);

            //    //for (int i = 1; i < bodySegment.Length; i++)
            //    //{
            //    //    LineSegment2D line = new LineSegment2D(bodySegment[i - 1], bodySegment[i]);
            //    //    drawImage.Draw(line, new Bgr(Color.Cyan), 2);
            //    //}
            //}

            //if (!r2BodyStart.IsEmpty && !r2BodyEnd.IsEmpty)
            //{
            //    //Find segment from mouse contour
            //    Point[] bodySegment = MathExtension.GetSegmentOfPolygon(mouseContour, r2BodyStart, r2BodyEnd);
            //    //tempBodyPoints.AddRange(bodySegment.Reverse());

            //    ////PointF midPoint = r2BodyStart.MidPoint(r2BodyEnd);
            //    //Point[] newBodySegment;
            //    //if (startCloser)
            //    //{
            //    //    newBodySegment = MathExtension.GetSegmentOfPolygon(mouseContour, bodyI4, bodyI6);
            //    //}
            //    //else
            //    //{
            //    //    newBodySegment = MathExtension.GetSegmentOfPolygon(mouseContour, bodyI6, bodyI4);
            //    //}

            //    //tempBodyPoints.AddRange(newBodySegment.Reverse());

            //    //for (int i = 1; i < bodySegment.Length; i++)
            //    //{
            //    //    LineSegment2D line = new LineSegment2D(bodySegment[i - 1], bodySegment[i]);
            //    //    drawImage.Draw(line, new Bgr(Color.Cyan), 2);
            //    //}
            //}

            Point[] bodySegment3 = MathExtension.GetSegmentOfPolygon(mouseContour, r1BodyStart, r1BodyEnd);
            Point[] bodySegment4 = MathExtension.GetSegmentOfPolygon(mouseContour, r2BodyStart, r2BodyEnd);
            var     bodyPoints2  = new List <Point>(bodySegment3.Concat(bodySegment4.Reverse()));

            PointF[] bodyPoints2F     = bodyPoints2.Select(x => x.ToPointF()).ToArray();
            Point[]  squareBodyPoints = new Point[] { bodyI3.ToPoint(), bodyI4.ToPoint(), bodyI6.ToPoint(), bodyI5.ToPoint() };
            //PointF[] tempBodyPointsF = tempBodyPoints.Select(x => x.ToPointF()).ToArray();

            if (bodyPoints2F != null && bodyPoints2F.Length > 0)
            {
                var rect1 = CvInvoke.MinAreaRect(bodyPoints2F);
                rect1.Angle += 90;
                //CvInvoke.Ellipse(drawImage, rect1, new MCvScalar(0, 0, 255), 3);
            }

            pelvicArea  = -1;
            pelvicArea2 = -1;
            if (squareBodyPoints != null && squareBodyPoints.Length > 0)
            {
                var rect2 = CvInvoke.MinAreaRect(squareBodyPoints.Select(x => x.ToPointF()).ToArray());
                rect2.Angle += 90;
                //CvInvoke.Ellipse(drawImage, rect2, new MCvScalar(0, 255, 255), 3);
                pelvicArea = MathExtension.PolygonArea(squareBodyPoints);
                //Console.WriteLine("Pelvic Area tail: " + pelvicArea + " - " + (rect2.Size.Height * rect2.Size.Width));
                pelvicArea2 = rect2.Size.Height * rect2.Size.Width;
            }

            //Ellipse fittedEllipse = PointCollection.EllipseLeastSquareFitting(bodyPoints2F);
            //CvInvoke.Ellipse(drawImage, fittedEllipse.RotatedRect, new MCvScalar(0, 0, 255), 3);
            //fittedEllipse = PointCollection.EllipseLeastSquareFitting(tempBodyPointsF);
            //CvInvoke.Ellipse(drawImage, fittedEllipse.RotatedRect, new MCvScalar(0, 0, 255), 3);



            //drawImage.DrawPolyline(rect1.GetVertices().Select(x => x.ToPoint()).ToArray(), true, new Bgr(Color.Orange), 4);
            //drawImage.DrawPolyline(rect2.GetVertices().Select(x => x.ToPoint()).ToArray(), true, new Bgr(Color.Orange), 4);
            //drawImage.DrawPolyline(fittedEllipse.RotatedRect.GetVertices().Select(x => x.ToPoint()).ToArray(), true, new Bgr(Color.Cyan), 4);
            bodyPoints = bodyPoints2;
            //pelvicArea = MathExtension.PolygonArea(squareBodyPoints);

            //bodyPoints = new List<Point>(new Point[] { bodyI3.ToPoint(), bodyI4.ToPoint(), bodyI6.ToPoint(), bodyI5.ToPoint() });
            //bodyPoints = tempBodyPoints;
            //StringBuilder s1 = new StringBuilder();
            //StringBuilder s2 = new StringBuilder();

            //foreach (double dist in r1Distances)
            //{
            //    s1.Append(dist + ",");
            //}

            //foreach (double dist in r2Distances)
            //{
            //    s2.Append(dist + ",");
            //}

            //System.IO.File.WriteAllText(@"D:\PhD\r1test.txt", s1.ToString());
            //System.IO.File.WriteAllText(@"D:\PhD\r2test.txt", s2.ToString());
        }