//
        public PlacementController(MainFrame motherFrame, ProductAdding pa)
        {
            this.motherFrame = motherFrame;
            productAdding = pa;
            clickLocation = new Point(0, 0);
            productAdding.productPanel.knowYourController(this);

            //Make an event when the selection of the ASSORTMENT or INVENTORY has changed
            productAdding.productList1.SelectionChanged += new ProductSelectionChanged(this.ChangeSelected);


            //Select the first product from the product list, and display it in the default info
            try
            {
                ProductInfo defaultInfo = new ProductInfo(ProductModel.List[0]);
                ChangeSelected(defaultInfo);
            }
            catch { }


            //Make an event that triggers when the list is changed, so that it automatically repaints the screen.
            placedProductList.CollectionChanged += ppList_CollectionChanged;




            //TEMP
            //Fill the staticlyplaced list with walls
            Vector pointTopLeft = new Vector(0, 0);
            Vector pointTopRight = new Vector(productAdding.productPanel.Width - 1, 0);
            Vector pointBottomLeft = new Vector(0, productAdding.productPanel.Height - 1);
            Vector pointBottomRight = new Vector(productAdding.productPanel.Width - 1, productAdding.productPanel.Height - 1);

            staticlyPlacedObjectList = new List<PlacedProduct>();

            int length = (int)(pointBottomRight.Y - pointTopRight.Y);
            int width = (int)(pointTopRight.X - pointTopLeft.X);

            staticlyPlacedObjectList.Add(   //Top
                new PlacedProduct(
                    new ProductModel(0, "", "", width, 1, 1, true),
                    new PointF(width / 2, 0)));

            staticlyPlacedObjectList.Add(   //Right
                new PlacedProduct(
                    new ProductModel(0, "", "", 1, 1, length, true),
                    new PointF(width, length / 2)));

            staticlyPlacedObjectList.Add(   //Bottom
                new PlacedProduct(
                    new ProductModel(0, "", "", width, 1, 1, true),
                    new PointF(width / 2, length)));

            staticlyPlacedObjectList.Add(   //Left
                new PlacedProduct(
                    new ProductModel(0, "", "", 1, 1, length, true),
                    new PointF(0, length / 2)));


        }
예제 #2
0
 public void Offset(float x, float y)
 {
     for (int i = 0; i < points.Count; i++)
     {
         Vector p = points[i];
         points[i] = new Vector(p.X + x, p.Y + y);
     }
 }
예제 #3
0
 public float DistanceTo(Vector vector)
 {
     return (float)Math.Sqrt(Math.Pow(vector.X - this.X, 2) + Math.Pow(vector.Y - this.Y, 2));
 }
예제 #4
0
 public float DotProduct(Vector vector)
 {
     return this.X * vector.X + this.Y * vector.Y;
 }
예제 #5
0
 public bool Equals(Vector v)
 {
     return X == v.X && Y == v.Y;
 }
        public void MoveProduct(PlacedProduct selectedProduct, List<PlacedProduct> placedProducts, Vector deltaVector, int panelWidth, int panelHeight)
        {
            //A variable to keep track of collision
            bool collision = false;
            

            //The new location that the product is going towards
            Point newLocationPoint = new Point(
                (int)(selectedProduct.Location.X + deltaVector.X),
                (int)(selectedProduct.Location.Y + deltaVector.Y)   );

            


            //Checkes the borders
            foreach (Polygon wall in selectedProduct.PolyBorder(panelWidth, panelHeight))
            {
                PolygonCollisionController.PolygonCollisionResult result =
                    PolygonCollisionController.PolygonCollision(selectedProduct.Poly, wall, deltaVector);

                if (result.WillIntersect)
                {
                    collision = true;
                    break;
                }
            }


            //Loops through each item and determines if it collides with any of them
            foreach (PlacedProduct collisionTarget in placedProducts)
            {
                if (collision)
                { break; }
                if (selectedProduct.Product.Collidable == false) //If the selected product is not collidable. For example an 'Energy Socket'. Break out the loop and place it.
                { break; }
                if (collisionTarget.Product.Collidable == false) //If the target is not collidable. For example an 'Energy Socket'. Skip this loop and go to the next target.
                { continue; }

                PolygonCollisionController.PolygonCollisionResult result =
                    PolygonCollisionController.PolygonCollision(selectedProduct.Poly, collisionTarget.Poly, deltaVector);

                if (result.WillIntersect)
                {
                    collision = true;
                    break;
                }
            }

            //Failsafe check at the end
            if (!collision)
            { /*selectedProduct.MoveTo(newLocationPoint); */}
            else
            {
                MessageBox.Show("Fail");
            }
            MessageBox.Show(newLocationPoint.ToString());

        }
        /// <summary>
        /// Moves the product a certain amount to a certain direction
        /// </summary>
        /// <param name="X_Axis">Chooses the axis that the product moves on. True for X-axis. False for Y-axis</param>
        public static void placement_Move(PlacedProduct targetProduct, bool X_Axis)
        {
            int x = 0;
            int y = 0;
            if (X_Axis) { x += targetProduct.GridSpace; }
            else { y += targetProduct.GridSpace; }

            Vector velocity = new Vector(x, y);
            Vector playerTranslation1 = velocity;
            Vector playerTranslation2 = velocity;

            //Resets the speed, after the velocity has been assigned.
            if (targetProduct.GridSpace < 0) { targetProduct.GridSpace *= -1; }


            //Test all product polygons for a collision
            foreach (PlacedProduct placedP in placedProductList)
            {
                //Test if the selected polygon is himself
                if (placedP.Poly == targetProduct.Poly)
                {
                    continue;
                }

                //Test if the polygon collides with others
                PolygonCollisionController.PolygonCollisionResult r = PolygonCollisionController.PolygonCollision(targetProduct.Poly, placedP.Poly, velocity);

                //If it does, alter the speed
                if (r.WillIntersect)
                {
                    //
                    playerTranslation1 = velocity + r.MinimumTranslationVector;

                    if (X_Axis) //Moving the x-axis, so set the y-axis velocity to 0
                    {
                        playerTranslation1.Y = 0;
                    }
                    else //Moving the y-axis, so set the x-axis velocity to 0
                    {
                        playerTranslation1.X = 0;
                    }

                    //If there is any movement along the Y axis while moving along the X axis, then the polygon collision want to move around the other polygon. Can't let that happen. So set all movement to 0.
                    if (X_Axis && r.MinimumTranslationVector.Y != 0)
                    {
                        playerTranslation1.X = 0;
                        playerTranslation1.Y = 0;
                    }
                    if (!X_Axis && r.MinimumTranslationVector.X != 0)
                    {
                        playerTranslation1.X = 0;
                        playerTranslation1.Y = 0;
                    }

                    //Round down to the closest x pixels
                    playerTranslation1.X = ((int)playerTranslation1.X / targetProduct.GridSpace) * targetProduct.GridSpace;
                    playerTranslation1.Y = ((int)playerTranslation1.Y / targetProduct.GridSpace) * targetProduct.GridSpace;
                    //MessageBox.Show("then " + playerTranslation1.X.ToString() + " and " + playerTranslation1.Y.ToString());
                    break;
                }
            }


            //Test all product polygons for a collision
            foreach (PlacedProduct placedO in staticlyPlacedObjectList)
            {
                //Test if the selected polygon is himself
                if (placedO.Poly == targetProduct.Poly)
                {
                    continue;
                }

                //Test if the polygon collides with others
                PolygonCollisionController.PolygonCollisionResult r = PolygonCollisionController.PolygonCollision(targetProduct.Poly, placedO.Poly, velocity);

                //If it does, alter the speed
                if (r.WillIntersect)
                {
                    //
                    playerTranslation2 = velocity + r.MinimumTranslationVector;

                    if (X_Axis) //Moving the x-axis, so set the y-axis velocity to 0
                    {
                        playerTranslation2.Y = 0;
                    }
                    else //Moving the y-axis, so set the x-axis velocity to 0
                    {
                        playerTranslation2.X = 0;
                    }

                    //If there is any movement along the Y axis while moving along the X axis, then the polygon collision want to move around the other polygon. Can't let that happen. So set all movement to 0.
                    if (X_Axis && r.MinimumTranslationVector.Y != 0)
                    {
                        playerTranslation2.X = 0;
                        playerTranslation2.Y = 0;
                    }
                    if (!X_Axis && r.MinimumTranslationVector.X != 0)
                    {
                        playerTranslation2.X = 0;
                        playerTranslation2.Y = 0;
                    }

                    //Round down to the closest x pixels
                    playerTranslation2.X = ((int)playerTranslation2.X / targetProduct.GridSpace) * targetProduct.GridSpace;
                    playerTranslation2.Y = ((int)playerTranslation2.Y / targetProduct.GridSpace) * targetProduct.GridSpace;
                    //MessageBox.Show("then " + playerTranslation2.X.ToString() + " and " + playerTranslation2.Y.ToString());
                    break;
                }
            }

            //Compares the tanslations
            /*
            1. Makes a new vector
            2. compares the two, and chooses the highest for the X and the highest for the Y (it looks for the highest number, even when negative. ie. -10 is higher than 4)
            3. If one of the two is 0, then set that Axis to 0
            */
            //1
            Vector playerTranslation = new Vector();
            //2
            playerTranslation.X = Math.Abs(playerTranslation1.X) > Math.Abs(playerTranslation2.X)
                ? playerTranslation1.X
                : playerTranslation2.X;
            playerTranslation.Y = Math.Abs(playerTranslation1.Y) > Math.Abs(playerTranslation2.Y)
                ? playerTranslation1.Y
                : playerTranslation2.Y;
            //3
            if (playerTranslation1.X == 0 || playerTranslation2.X == 0)
            {
                playerTranslation.X = 0;
            }
            if (playerTranslation1.Y == 0 || playerTranslation2.Y == 0)
            {
                playerTranslation.Y = 0;
            }

            //Set the polygon points
            targetProduct.Poly.Offset(playerTranslation);

            //Update the corner points
            for (int index = 0; index < targetProduct.Poly.Points.Count; index++)
            {
                targetProduct.CornerPoints[index] = new PointF(targetProduct.Poly.Points[index].X, targetProduct.Poly.Points[index].Y);
            }

            //Update the center point
            targetProduct.Location = new PointF(targetProduct.Location.X + playerTranslation.X, targetProduct.Location.Y + playerTranslation.Y);

        }
        /// <summary>
        /// Event that triggers when the dragdrop object is dragged  across the screen.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void event_DragOver(object sender, DragEventArgs e)
        {
            //If not ProductModel or PlacedProduct, then exit out, because you can only get the location from them
            if (!(e.Data.GetDataPresent(typeof(ProductModel)) || e.Data.GetDataPresent((typeof(PlacedProduct)))))
            {
                draggingItem = false;
                return;
            }
            else
            {
                draggingItem = true;
            }

            
            //Gets the location of the mouse inside of the panel
            Point newLocation = new Point(e.X, e.Y);
            newLocation = motherFrame.PointToClient(newLocation);
            newLocation.X -= productAdding.productPanel.Left;
            newLocation.Y -= productAdding.productPanel.Top;
            newLocation.Y -= motherFrame.menuStrip1.Height;

            newLocation.X /= MovementSpeed; newLocation.X *= MovementSpeed; //Round down to the movement speed. (AKA: Fit into the grid)
            newLocation.Y /= MovementSpeed; newLocation.Y *= MovementSpeed; //Round down to the movement speed.
            
            
            Color drawImageColor;

            if (e.Data.GetDataPresent(typeof (ProductModel)))
            {
                //Make a new model, size and color
                ProductModel model = (ProductModel)e.Data.GetData(typeof (ProductModel));
                drawImageColor = GetMainCategoryColorIfNeeded(model.ProductCategory.CatId);

                //Colour in the bitmap and resize it.
                Graphics gfx = Graphics.FromImage(drawImageGhostBitmap);
                SolidBrush brush = new SolidBrush(Color.FromArgb(128, drawImageColor.R, drawImageColor.G, drawImageColor.B));
                gfx.FillRectangle(brush, new Rectangle(new Point(0, 0), new Size(1000,1000)));
                
                //Small dispose
                brush.Dispose();
                gfx.Dispose();
                
                //Set the Bitmap and new location
                drawImageGhostBitmap = new Bitmap(drawImageGhostBitmap, model.Width, model.Length);
                drawImageGhostPoint = new Point(newLocation.X - model.Width/2, newLocation.Y - model.Length/2); //Calculates the top left point for the Ghost.
            }
            else if (e.Data.GetDataPresent(typeof (PlacedProduct)))
            {
                //Get the rotated bitmap
                PlacedProduct placedP = (PlacedProduct)e.Data.GetData(typeof(PlacedProduct));
                drawImageGhostBitmap = placedP.RotatedMap;

                Vector clickOffsetVector = new Vector((clickLocation.X - placedP.Location.X), (clickLocation.Y - placedP.Location.Y)); //Get the click offset if the user clicked the bottom left of the image

                //Set the new location
                drawImageGhostPoint = new Point(
                    newLocation.X - drawImageGhostBitmap.Width/2 - (int) clickOffsetVector.X,
                    newLocation.Y - drawImageGhostBitmap.Height/2 - (int) clickOffsetVector.Y);
                    //Calculates the top left point for the Ghost.
            }

            //And then repaint the panel
            DoRepaintWithGhost();
        }
        // Check if polygon A is going to collide with polygon B for the given velocity
        public static PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB, Vector velocity)
        {
            PolygonCollisionResult result = new PolygonCollisionResult();
            result.Intersect = true;
            result.WillIntersect = true;

            int edgeCountA = polygonA.Edges.Count;
            int edgeCountB = polygonB.Edges.Count;
            float minIntervalDistance = float.PositiveInfinity;
            Vector translationAxis = new Vector();
            Vector edge;

            // Loop through all the edges of both polygons
            for (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++)
            {
                if (edgeIndex < edgeCountA)
                {
                    edge = polygonA.Edges[edgeIndex];
                }
                else
                {
                    edge = polygonB.Edges[edgeIndex - edgeCountA];
                }

                // ===== 1. Find if the polygons are currently intersecting =====

                // Find the axis perpendicular to the current edge
                Vector axis = new Vector(-edge.Y, edge.X);
                axis.Normalize();

                // Find the projection of the polygon on the current axis
                float minA = 0; float minB = 0; float maxA = 0; float maxB = 0;
                ProjectPolygon(axis, polygonA, ref minA, ref maxA);
                ProjectPolygon(axis, polygonB, ref minB, ref maxB);

                // Check if the polygon projections are currentlty intersecting
                if (IntervalDistance(minA, maxA, minB, maxB) > 0) result.Intersect = false;

                // ===== 2. Now find if the polygons *will* intersect =====

                // Project the velocity on the current axis
                float velocityProjection = axis.DotProduct(velocity);

                // Get the projection of polygon A during the movement
                if (velocityProjection < 0)
                {
                    minA += velocityProjection;
                }
                else
                {
                    maxA += velocityProjection;
                }

                // Do the same test as above for the new projection
                float intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.WillIntersect = false;

                // If the polygons are not intersecting and won't intersect, exit the loop
                if (!result.Intersect && !result.WillIntersect) break;

                // Check if the current interval distance is the minimum one. If so store
                // the interval distance and the current distance.
                // This will be used to calculate the minimum translation vector
                intervalDistance = Math.Abs(intervalDistance);
                if (intervalDistance < minIntervalDistance)
                {
                    minIntervalDistance = intervalDistance;
                    translationAxis = axis;

                    Vector d = polygonA.Center - polygonB.Center;
                    if (d.DotProduct(translationAxis) < 0) translationAxis = -translationAxis;
                }
            }

            // The minimum translation vector can be used to push the polygons appart.
            // First moves the polygons by their velocity
            // then move polygonA by MinimumTranslationVector.
            if (result.WillIntersect) result.MinimumTranslationVector = translationAxis * minIntervalDistance;

            return result;
        }
 // Calculate the projection of a polygon on an axis and returns it as a [min, max] interval
 public static void ProjectPolygon(Vector axis, Polygon polygon, ref float min, ref float max)
 {
     // To project a point on an axis use the dot product
     float d = axis.DotProduct(polygon.Points[0]);
     min = d;
     max = d;
     for (int i = 0; i < polygon.Points.Count; i++)
     {
         d = polygon.Points[i].DotProduct(axis);
         if (d < min)
         {
             min = d;
         }
         else
         {
             if (d > max)
             {
                 max = d;
             }
         }
     }
 }
예제 #11
0
 //makes the points move.
 public void Offset(Vector v)
 {
     Offset(v.X, v.Y);
 }
        public List<Polygon> PolyBorder(int width, int height)
        {
            //List to return
            List<Polygon> list = new List<Polygon>();

            //
            //Add the 4 corners
            //
            Polygon pTop = new Polygon();
            Polygon pRight = new Polygon();
            Polygon pBottom = new Polygon();
            Polygon pLeft = new Polygon();

            //Points for corners
            Vector pointTopLeft = new Vector(0, 0);
            Vector pointTopRight = new Vector(width, 0);
            Vector pointBottomLeft = new Vector(0, height);
            Vector pointBottomRight = new Vector(width, height);


            //Add points/vectors
            pTop.Points.Add(pointTopLeft);
            pTop.Points.Add(pointTopRight);
            //
            pRight.Points.Add(pointTopRight);
            pRight.Points.Add(pointBottomRight);
            //
            pBottom.Points.Add(pointBottomRight);
            pBottom.Points.Add(pointBottomLeft);
            //
            pLeft.Points.Add(pointBottomLeft);
            pLeft.Points.Add(pointTopLeft);


            //Build edges
            pTop.BuildEdges();
            pRight.BuildEdges();
            pBottom.BuildEdges();
            pLeft.BuildEdges();


            //Add to the list
            list.Add(pTop);
            list.Add(pRight);
            list.Add(pBottom);
            list.Add(pLeft);


            return list;
        }       
        public Polygon GetVirtualPolygon(Point newLocation)
        {
            Polygon virtualPolygon = new Polygon();
            foreach (Vector v in Poly.Points)
            {
                virtualPolygon.Points.Add(v);
            }

            Vector delta = new Vector(new Vector(newLocation) - new Vector(Location));

            virtualPolygon.Offset(delta);
            virtualPolygon.BuildEdges();

            return virtualPolygon;
        }