Beispiel #1
0
 /// <summary>
 /// Copies edge object to another edge object
 /// </summary>
 /// <param name="p_edgeoriginal">Original edge</param>
 /// <param name="p_edgecopy">Copy edge</param>
 private void copyedge(edge p_edgeoriginal, edge p_edgecopy)
 {
     p_edgecopy.getStart().setX(p_edgeoriginal.getStart().getX());
     p_edgecopy.getStart().setY(p_edgeoriginal.getStart().getY());
     p_edgecopy.getEnd().setX(p_edgeoriginal.getEnd().getX());
     p_edgecopy.getEnd().setY(p_edgeoriginal.getEnd().getY());
 }
Beispiel #2
0
        /// <summary>
        /// Used for picking aisle intersection points calculation
        /// </summary>
        /// <param name="p_edge">Intersecting edge</param>
        /// <returns>Returns -1000000 if there is no intersection between the line segments, returns the intersection point if there is intersection</returns>
        public node calculateIntersect(edge p_edge)
        {
            double nointersection = -1000000;//A magic coordinate number used for no intersection
            node   tempcoordinate = new node(options.tempnode);
            double ua, ub;

            double x1 = this.getStart().getX();
            double x2 = this.getEnd().getX();
            double x3 = p_edge.getStart().getX();
            double x4 = p_edge.getEnd().getX();

            double y1 = this.getStart().getY();
            double y2 = this.getEnd().getY();
            double y3 = p_edge.getStart().getY();
            double y4 = p_edge.getEnd().getY();

            //Fixing the rounding error problem when picking aisles are 90 degrees to cross aisles (or regionedges) using epsilon
            x3 = x3 + (options.getEpsilon()) * (x3 - x4);
            x4 = x4 - (options.getEpsilon()) * (x3 - x4);
            y3 = y3 + (options.getEpsilon()) * (y3 - y4);
            y4 = y4 - (options.getEpsilon()) * (y3 - y4);

            double denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));

            if (denom == 0)//Lines are parallel
            {
                tempcoordinate.setX(nointersection);
                tempcoordinate.setY(nointersection);
                return(tempcoordinate);
            }

            double noma = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));

            double nomb = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));

            ua = noma / denom;
            ub = nomb / denom;
            if ((ua <= 1) && (ua >= 0) && (ub <= 1) && (ub >= 0))//Lines intersect within their line segments
            {
                tempcoordinate.setX(x1 + ua * (x2 - x1));
                tempcoordinate.setY(y1 + ua * (y2 - y1));
                return(tempcoordinate);
            }
            else//Lines intersect but beyond their line segments
            {
                tempcoordinate.setX(nointersection);
                tempcoordinate.setY(nointersection);
                return(tempcoordinate);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Used for interior cross aisle intersection point calculation
        /// This is little different than the previous one, we assume the lines are infinitely long lines
        /// We get rid of the ua <= 1 type of checks
        /// </summary>
        /// <param name="p_edge">Intersecting edge</param>
        /// <returns>Returns -1000000 if lines are parallel otherwise returns the intersection point</returns>
        public node calculateIntersectInfinite(edge p_edge)
        {
            int    precision = 10;            //Used for rounding error problem when intersection of 90 degree pick aisles
            double nointersection = -1000000; //A magic coordinate number used for no intersection
            node   tempcoordinate = new node(options.tempnode);
            double ua, ub;

            double x1 = this.getStart().getX();
            double x2 = this.getEnd().getX();
            double x3 = p_edge.getStart().getX();
            double x4 = p_edge.getEnd().getX();

            double y1 = this.getStart().getY();
            double y2 = this.getEnd().getY();
            double y3 = p_edge.getStart().getY();
            double y4 = p_edge.getEnd().getY();

            //Fixing the rounding error problem when picking aisles are 90 degrees
            x1 = Math.Round(x1, precision);
            x2 = Math.Round(x2, precision);
            x3 = Math.Round(x3, precision);
            x4 = Math.Round(x4, precision);
            y1 = Math.Round(y1, precision);
            y2 = Math.Round(y2, precision);
            y3 = Math.Round(y3, precision);
            y4 = Math.Round(y4, precision);

            double denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));

            if (denom == 0)
            {
                tempcoordinate.setX(nointersection);
                tempcoordinate.setY(nointersection);
                return(tempcoordinate);
            }

            double noma = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));

            double nomb = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));

            ua = noma / denom;
            ub = nomb / denom;
            tempcoordinate.setX(x1 + ua * (x2 - x1));
            tempcoordinate.setY(y1 + ua * (y2 - y1));
            return(tempcoordinate);
        }
Beispiel #4
0
        /// <summary>
        /// Fulfills pick aisles with pick locations and storage locations, returns false if no storage location can be created (because aisle is too small)
        /// </summary>
        /// <param name="p_edge">Picking aisle</param>
        /// <param name="p_referencenode">Reference node 1 is used for aligning storage locations correctly between picking aisles</param>
        /// <param name="p_referencenode2">Reference node 2 is used for aligning storage locations correctly between picking aisles</param>
        /// <returns>Returns false if no storage locations are created in a pick aisle, otherwise returns true</returns>
        public bool fulfillLocations(edge p_edge, node p_referencenode1, node p_referencenode2)
        {
            double X;
            double Y;
            double Xl1, Xr1;
            double Xl2, Xr2;
            double Xl3, Xr3;
            double Xl4, Xr4;
            double Yl1, Yr1;
            double Yl2, Yr2;
            double Yl3, Yr3;
            double Yl4, Yr4;

            double Xs, Xe, Xr, Ys, Ye, Yr;

            if (p_edge.getStart().getY() > p_edge.getEnd().getY())
            {
                Xs = p_edge.getEnd().getX();
                Xe = p_edge.getStart().getX();
                Ys = p_edge.getEnd().getY();
                Ye = p_edge.getStart().getY();
            }
            else
            {
                Xs = p_edge.getStart().getX();
                Xe = p_edge.getEnd().getX();
                Ys = p_edge.getStart().getY();
                Ye = p_edge.getEnd().getY();
            }

            //Check which reference point is close to starting coordinate (Xs, Ys)
            if (p_referencenode1.getY() < p_referencenode2.getY())
            {
                Xr = p_referencenode1.getX();
                Yr = p_referencenode1.getY();
            }
            else
            {
                Xr = p_referencenode2.getX();
                Yr = p_referencenode2.getY();
            }

            double angle  = p_edge.calculateAngle();
            double angle1 = (visualmath.radianToDegree(angle) - 90);

            angle = visualmath.degreeToRadian(angle1);
            double halfpickingaislewidth = pickingaislewidth / 2;

            double lengthofaisle = Math.Sqrt(Math.Pow(Xs - Xe, 2) + Math.Pow(Ys - Ye, 2));

            int    numberoflocations = Convert.ToInt32(Math.Ceiling(lengthofaisle / locationwidth));
            double incx = (Xe - Xs) / (lengthofaisle / locationwidth);
            double incy = (Ye - Ys) / (lengthofaisle / locationwidth);

            //Find the starting point that is inside the picking aisle
            X = Xr;
            Y = Yr;
            if (Math.Abs(incy) > options.getEpsilon())//if the lines are not parallel then use this one
            {
                if (Yr < Ys)
                {
                    if (incy > 0)
                    {
                        while (Y < Ys)
                        {
                            X = X + incx;
                            Y = Y + incy;
                        }
                    }
                    else
                    {
                        while (Y < Ys)
                        {
                            X = X - incx;
                            Y = Y - incy;
                        }
                    }
                }
                else
                {
                    if (incy > 0)
                    {
                        while (Y > Ys)
                        {
                            X = X - incx;
                            Y = Y - incy;
                        }
                    }
                    else
                    {
                        while (Y > Ys)
                        {
                            X = X + incx;
                            Y = Y + incy;
                        }
                    }
                }
            }
            else//angle is zero so no y increment
            {
                if (Xr < Xs)
                {
                    if (incx > 0)
                    {
                        while (X < Xs)
                        {
                            X = X + incx;
                            Y = Y + incy;
                        }
                    }
                    else
                    {
                        while (X < Xs)
                        {
                            X = X - incx;
                            Y = Y - incy;
                        }
                    }
                }
                else
                {
                    if (incx > 0)
                    {
                        while (X > Xs)
                        {
                            X = X - incx;
                            Y = Y - incy;
                        }
                    }
                    else
                    {
                        while (X > Xs)
                        {
                            X = X + incx;
                            Y = Y + incy;
                        }
                    }
                }
            }

            X = X + incx * verticaladjuster;
            Y = Y + incy * verticaladjuster;

            for (int i = 0; i < numberoflocations; i++)
            {
                storagelocation s1 = null;
                storagelocation s2 = null;
                node            c  = new node(X, Y, options.locationnode);
                //Check each corner of the storage location is inside the region in a smart way
                //If all the corners are inside then create a storage location for left face
                Xl1 = X - incx / 2 - (halfpickingaislewidth + locationdepth) * Math.Cos(angle);
                Yl1 = Y - incy / 2 - (halfpickingaislewidth + locationdepth) * Math.Sin(angle);

                if (!isOnCrossAisle(Xl1, Yl1) && isInsideRegion(Xl1, Yl1))
                {
                    Xl3 = X + incx / 2 - (halfpickingaislewidth + locationdepth) * Math.Cos(angle);
                    Yl3 = Y + incy / 2 - (halfpickingaislewidth + locationdepth) * Math.Sin(angle);
                    if (!isOnCrossAisle(Xl3, Yl3) && isInsideRegion(Xl3, Yl3))
                    {
                        Xl2 = X - incx / 2 - (halfpickingaislewidth) * Math.Cos(angle);
                        Yl2 = Y - incy / 2 - (halfpickingaislewidth) * Math.Sin(angle);
                        if (!isOnCrossAisle(Xl2, Yl2) && isInsideRegion(Xl2, Yl2))
                        {
                            Xl4 = X + incx / 2 - (halfpickingaislewidth) * Math.Cos(angle);
                            Yl4 = Y + incy / 2 - (halfpickingaislewidth) * Math.Sin(angle);
                            if (!isOnCrossAisle(Xl4, Yl4) && isInsideRegion(Xl4, Yl4))
                            {
                                s1 = new storagelocation(c, Xl1, Yl1, Xl2, Yl2, Xl3, Yl3, Xl4, Yl4, 1);
                            }
                        }
                    }
                }

                Xr2 = X - incx / 2 + (halfpickingaislewidth + locationdepth) * Math.Cos(angle);
                Yr2 = Y - incy / 2 + (halfpickingaislewidth + locationdepth) * Math.Sin(angle);

                if (!isOnCrossAisle(Xr2, Yr2) && isInsideRegion(Xr2, Yr2))
                {
                    Xr4 = X + incx / 2 + (halfpickingaislewidth + locationdepth) * Math.Cos(angle);
                    Yr4 = Y + incy / 2 + (halfpickingaislewidth + locationdepth) * Math.Sin(angle);
                    if (!isOnCrossAisle(Xr4, Yr4) && isInsideRegion(Xr4, Yr4))
                    {
                        Xr1 = X - incx / 2 + (halfpickingaislewidth) * Math.Cos(angle);
                        Yr1 = Y - incy / 2 + (halfpickingaislewidth) * Math.Sin(angle);
                        if (!isOnCrossAisle(Xr1, Yr1) && isInsideRegion(Xr1, Yr1))
                        {
                            Xr3 = X + incx / 2 + (halfpickingaislewidth) * Math.Cos(angle);
                            Yr3 = Y + incy / 2 + (halfpickingaislewidth) * Math.Sin(angle);
                            if (!isOnCrossAisle(Xr3, Yr3) && isInsideRegion(Xr3, Yr3))
                            {
                                s2 = new storagelocation(c, Xr1, Yr1, Xr2, Yr2, Xr3, Yr3, Xr4, Yr4, 1);
                            }
                        }
                    }
                }

                if (s1 != null)
                {
                    c.s1 = s1;
                }
                if (s2 != null)
                {
                    c.s2 = s2;
                }
                //Do not create a pick location if there is no storage location
                if (s1 != null || s2 != null)
                {
                    c.setPickingAisleEdge(p_edge);
                    p_edge.addOnEdgeNode(c);
                }
                X = X + incx;
                Y = Y + incy;
            }
            //Return false if there are no pick locations created (because aisle is too short), else return true
            if (p_edge.getOnEdgeNodes().Count == 0)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }