From b6837f097e9cdb2645368aed4ddb03f580c331e4 Mon Sep 17 00:00:00 2001
From: z8018 <1282578289@qq.com>
Date: 星期一, 05 五月 2025 17:29:07 +0800
Subject: [PATCH] 1

---
 项目代码/WCS/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/PlaceBlockService.cs |  375 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 370 insertions(+), 5 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WCS/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/PlaceBlockService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WCS/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/PlaceBlockService.cs"
index 082fc1d..a1ae45c 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WCS/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/PlaceBlockService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WCS/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/PlaceBlockService.cs"
@@ -3,14 +3,49 @@
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
+using WIDESEAWCS_Core.Helper;
 using WIDESEAWCS_DTO.PlacedBlockDTO;
+using WIDESEAWCS_DTO.TaskInfo;
 using WIDESEAWCS_IBasicInfoService;
 
 namespace WIDESEAWCS_BasicInfoService
 {
     public class PlaceBlockService
     {
-        public const int SPACING = 5;
+        public static int SPACING = AppSettings.GetValue("Spacing").ObjToInt();
+
+        public static int MaxRotateLength = AppSettings.GetValue("MaxRotateLength").ObjToInt();
+
+        /// <summary>
+        /// 鏈�澶鍧愭爣闄愬埗锛堟绫筹級
+        /// </summary>
+        public const int MaxY = 600;
+
+        /// <summary>
+        /// 鏈�灏忔í鍚慪鍧愭爣闄愬埗锛堟绫筹級
+        /// </summary>
+        public static int MinY = AppSettings.GetValue("MinY").ObjToInt();
+
+        /// <summary>
+        /// 鍚哥洏妯悜闀垮害
+        /// </summary>
+        public const int SuctionLengthH = 920;
+
+        /// <summary>
+        /// 鍚哥洏妯悜瀹藉害
+        /// </summary>
+        public const int SuctionWidthH = 530;
+
+        /// <summary>
+        /// 鍚哥洏绾靛悜闀垮害
+        /// </summary>
+        public const int SuctionLengthZ = 530;
+
+        /// <summary>
+        /// 鍚哥洏绾靛悜瀹藉害
+        /// </summary>
+        public const int SuctionWidthZ = 130;
 
         /// <summary>
         /// 瀹瑰櫒灏哄
@@ -39,7 +74,7 @@
             }
 
 
-            containerFloor = new PlacedBlock(new Point3D(0, 0, 0), ContainerSize.Length, ContainerSize.Width, 0);
+            containerFloor = new PlacedBlock(new Point3D(SPACING, SPACING, 0), ContainerSize.Length - 2 * SPACING, ContainerSize.Width - 2 * SPACING, 0);
         }
 
         /// <summary>
@@ -54,10 +89,46 @@
         /// </returns>
         public Point3D? PlaceBlock(int length, int width, int height)
         {
+            int tempLength = length;
+            int tempWidth = width;
+
+            if (length < width)
+            {
+                length = tempWidth;
+                width = tempLength;
+            }
+
             if (!IsValidBlock(length, width, height))
                 return null;
 
             return FindStackablePosition(length, width, height);
+        }
+
+        /// <summary>
+        /// 涓绘斁缃柟娉曪細灏濊瘯鏀剧疆鎸囧畾灏哄鐨勮揣鐗�
+        /// </summary>
+        /// <param name="length">璐х墿闀垮害锛圶杞存柟鍚戯級</param>
+        /// <param name="width">璐х墿瀹藉害锛圷杞存柟鍚戯級</param>
+        /// <param name="height">璐х墿楂樺害锛圸杞存柟鍚戯級</param>
+        /// <returns>
+        /// 鎴愬姛锛氳繑鍥炲彲鏀剧疆浣嶇疆鐨勫乏涓嬪墠瑙扨oint3D鍧愭爣
+        /// 澶辫触锛氳繑鍥瀗ull锛堝昂瀵告棤鏁堟垨绌洪棿涓嶈冻锛�
+        /// </returns>
+        public TaskPosition? PlaceBlock(int length, int width, int height, int edge)
+        {
+            int tempLength = length;
+            int tempWidth = width;
+
+            if (length < width)
+            {
+                length = tempWidth;
+                width = tempLength;
+            }
+
+            if (!IsValidBlock(length, width, height))
+                return null;
+
+            return FindStackablePosition(length, width, height, edge);
         }
 
         /// <summary>
@@ -140,9 +211,9 @@
                     if (xStart > xEnd || yStart > yEnd) continue;
 
                     // 浼樺寲鎼滅储锛氫紭鍏堣钀戒綅缃�
-                    for (int y = yStart; y <= yEnd; y += 10)
+                    for (int x = xStart; x <= xEnd; x += 10)
                     {
-                        for (int x = xStart; x <= xEnd; x += 10)
+                        for (int y = yStart; y <= yEnd; y += 10)
                         {
                             var candidate = new Point3D(x, y, baseZ);
                             if (IsPositionValid(candidate, l, w, h))
@@ -150,6 +221,88 @@
                                 var placed = new PlacedBlock(candidate, l, w, h);
                                 //PlacedBlocks.Add(placed);
                                 return candidate;
+                            }
+                        }
+                    }
+                }
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// 鍦ㄧ幇鏈夎揣鐗╅《閮ㄥ鎵惧彔鏀句綅缃紙鍫嗗彔妯″紡锛�
+        /// 鍙犳斁鏉′欢锛�
+        /// - 鏀拺闈㈢Н >= 琚敮鎾戦潰闈㈢Н鐨�70%
+        /// - 鏂拌揣鐗╁畬鍏ㄤ綅浜庢敮鎾戣揣鐗╀笂鏂�
+        /// - 婊¤冻闂撮殧瑕佹眰
+        /// </summary>
+        /// <param name="l">闀垮害</param>
+        /// <param name="w">瀹藉害</param>
+        /// <param name="h">楂樺害</param>
+        /// <returns></returns>
+        private TaskPosition? FindStackablePosition(int l, int w, int h, int edge)
+        {
+            // 鐢熸垚鍊欓�夋敮鎾戝眰锛堝寘鍚鍣ㄥ簳閮級
+            var candidateLayers = PlacedBlocks
+                .Select(b => b.Position.Z + b.Height)
+                .Append(0)
+                .Distinct()
+                .OrderBy(z => z)
+                .ToList();
+
+            foreach (var baseZ in candidateLayers)
+            {
+                if (baseZ + h > ContainerSize.Height) continue;
+
+                // 鑾峰彇褰撳墠灞傜殑鏀拺鍧楋紙鍖呭惈铏氭嫙瀹瑰櫒搴曢儴锛�
+                var supports = GetSupportBlocks(baseZ);
+
+                foreach (var support in supports)
+                {
+                    // 璁$畻鏈夋晥鍙犳斁鍖哄煙锛堜慨姝i棿闅旈�昏緫锛�
+                    int xStart = support.Position.X;
+                    int yStart = support.Position.Y;
+
+                    // 瀹瑰櫒搴曢儴鏀拺蹇呴』鍐呯缉闂撮殧锛堝嵆浣垮昂瀵哥浉鍚岋級
+                    if (support == containerFloor)
+                    {
+                        xStart = support.Position.X;
+                        yStart = support.Position.Y;
+                    }
+
+                    int xEnd = support.Position.X + support.Length - l;
+                    int yEnd = support.Position.Y + support.Width - w;
+
+                    // 鏅�氭敮鎾戝潡浠呭湪灏哄涓嶅悓鏃跺姞闂撮殧
+                    if (support != containerFloor &&
+                       (l != support.Length && w != support.Width))
+                    {
+                        xStart += SPACING;
+                        yStart += SPACING;
+                        xEnd -= SPACING;
+                        yEnd -= SPACING;
+                    }
+
+                    // 鏈�缁堝鍣ㄨ竟鐣岀害鏉�
+                    xEnd = Math.Min(xEnd, ContainerSize.Length - l);
+                    yEnd = Math.Min(yEnd, ContainerSize.Width - w);
+
+                    if (xStart > xEnd || yStart > yEnd) continue;
+
+                    // 浼樺寲鎼滅储锛氫紭鍏堣钀戒綅缃�
+                    for (int x = xStart; x <= xEnd; x += 10)
+                    {
+                        for (int y = yStart; y <= yEnd; y += 10)
+                        {
+                            var candidate = new Point3D(x, y, baseZ);
+                            if (IsPositionValid(candidate, l, w, h))
+                            {
+                                TaskPosition taskPosition = GetTaskPosition(candidate, l, w, h, edge);
+                                if (IsPositionValid(taskPosition))
+                                {
+                                    return taskPosition;
+                                }
+
                             }
                         }
                     }
@@ -169,7 +322,7 @@
         {
             var blocks = PlacedBlocks
                 .Where(b => b.Position.Z + b.Height == baseZ)
-                .OrderByDescending(b => b.Length * b.Width).ToList();
+                /*.OrderByDescending(b => b.Length * b.Width)*/.ToList();
 
             // 褰揵aseZ=0鏃舵坊鍔犲鍣ㄥ簳閮ㄦ敮鎾�
             if (baseZ == 0 && blocks.Count == 0)
@@ -201,6 +354,11 @@
                 pos.Y + w > ContainerSize.Width - SPACING)
                 return false;
 
+            if (pos.X > 1600)
+                return false;
+
+            if (pos.X > MaxY && l > MaxRotateLength) return false;
+
             // 涓夌淮纰版挒妫�娴�
             var newBlock = new PlacedBlock(pos, l, w, h);
             return !PlacedBlocks.Any(existing =>
@@ -217,5 +375,212 @@
                 return xOverlap && yOverlap && zOverlap;
             });
         }
+
+        private bool IsPositionValid(TaskPosition pos)
+        {
+            // 杈圭晫妫�鏌ワ紙鍚鍣ㄨ竟缂橀棿闅旓級
+            //if (pos.X < SPACING ||
+            //    pos.Y < SPACING ||
+            //    pos.X + l > ContainerSize.Length - SPACING ||
+            //    pos.Y + w > ContainerSize.Width - SPACING)
+            //    return false;
+
+            return pos.PutPositionY <= MaxY && pos.PutPositionY >= 0 && pos.TakePositionY >= 0;
+        }
+
+        public TaskPosition GetTaskPosition(Point3D point3D, int length, int width, int height, int edge)
+        {
+            //鏀捐揣浣嶇疆鏉挎潗涓績鐐�
+            Point3D putCenter = new Point3D(point3D.X + length / 2, point3D.Y + width / 2, point3D.Z + height / 2);
+
+            //鍙栬揣浣嶇疆鏉挎潗涓績鐐�
+            Point3D takeCenter = new Point3D(length / 2, width / 2, height / 2);
+
+            //鍚哥洏闀�530 闂撮殧660  鏈�澶�920 鍚哥洏瀹�130
+
+            int positionR = 1;
+
+            int takePositionX = 0;
+            int takePositionY = 0;
+            int takePositionZ = 0;
+            int putPositionX = 0;
+            int putPositionY = 0;
+            int putPositionZ = 0;
+
+            //1.濡傛灉闀垮害澶т簬920锛屽搴﹀ぇ浜庣瓑浜�300锛屽垯鍙互浣跨敤鍙屽惛鐩樻í鍚戝惛鍙�
+            if (length > 920) //妯悜鍙屽惛
+            {
+                //鍚哥洏灏哄
+                Point3D deviceCenter = new Point3D(530 / 2, 920 / 2, 0);
+
+                positionR = 1;
+                takePositionX = (takeCenter.Y - deviceCenter.X);
+                takePositionY = (takeCenter.X - deviceCenter.Y);
+                takePositionZ = 10;
+
+                putPositionX = (putCenter.Y - deviceCenter.X);
+                putPositionY = (putCenter.X - deviceCenter.Y);
+                putPositionZ = point3D.Z; // putCenter.Z /*+ 10*/;
+            }
+            else//妯悜鍗曞惛
+            {
+                //鍚哥洏灏哄
+                Point3D deviceCenter = new Point3D(530 / 2, 130 / 2, 0);
+
+                positionR = 1;
+                takePositionX = (takeCenter.Y - deviceCenter.X);
+                takePositionY = (takeCenter.X - deviceCenter.Y);
+                takePositionZ = 10;
+
+                putPositionX = (putCenter.Y - deviceCenter.X);
+                putPositionY = (putCenter.X - deviceCenter.Y);
+                putPositionZ = point3D.Z; // putCenter.Z /*+ 10*/;
+            }
+
+            //1.濡傛灉鍙栬揣浣嶆渶灏廦鍧愭爣灏忎簬155
+            if (takePositionY <= MinY)
+            {
+                takePositionY = 0;
+                putPositionY = point3D.X + MinY;
+            }
+            else
+            {
+                takePositionY -= MinY;
+            }
+
+            if (putPositionY > MaxY)
+            {
+                int moreY = putPositionY - MaxY;
+                if (takePositionY - moreY > 0)
+                {
+                    takePositionY -= moreY;
+                    putPositionY = MaxY;
+                }
+                else if (Math.Abs(takePositionY - moreY) < SPACING)
+                {
+                    takePositionY = 0;
+                    putPositionY = Math.Abs(takePositionY - moreY);
+                }
+                else
+                {
+                    int count = PlacedBlocks.Where(x => x.Position.Y == 10).Count();
+                    //putPositionY -= (920 - 130 + takePositionY - (count + 1) * SPACING * 2);
+                    putPositionY = point3D.X - 920 + 130;
+                    takePositionY = length - MinY - 130;
+                    if (putPositionY < 0 && takePositionY + putPositionY >= 0)
+                    {
+                        takePositionY += putPositionY;
+                        putPositionY = 0;
+                    }
+                    positionR = 2;
+                }
+            }
+
+
+
+            //妯悜鏃讹紝鏈�灏廦鍧愭爣涓�155锛岀旱鍚戞椂锛屾渶灏廦鍧愭爣涓�350銆傛渶澶鍧愭爣涓�700
+            //if (positionR == 1 && putPositionY < MinY)
+            //{
+            //    takePositionY = 0;
+
+            //    putPositionY = point3D.X + MinY;
+            //}
+            //else if (positionR == 1 && putPositionY >= MinY && putPositionY <= MaxY)
+            //{
+            //    if (takePositionY >= MinY)
+            //        takePositionY -= MinY;
+            //    else
+            //    {
+            //        putPositionY += MinY - takePositionY;
+            //        takePositionY = 0;
+            //    }
+            //}
+            //else if (positionR == 1 && putPositionY > MaxY && putPositionY < 1700)
+            //{
+            //    int moreY = putPositionY - MaxY;
+            //    if (takePositionY - moreY - MinY > 0)
+            //    {
+            //        takePositionY -= moreY + MinY;
+            //        putPositionY = MaxY;
+            //    }
+            //    else if (Math.Abs(takePositionY - moreY - MinY) < SPACING)
+            //    {
+            //        if (takePositionY - moreY - MinY > 0)
+            //        {
+            //            takePositionY -= moreY + MinY;
+            //        }
+            //        else
+            //        {
+            //            takePositionY = 0;
+            //        }
+            //        putPositionY = MaxY;
+            //    }
+            //    else
+            //    {
+            //        int count = PlacedBlocks.Where(x => x.Position.Y == 10).Count();
+            //        //putPositionY -= (920 - 130 + takePositionY - (count + 1) * SPACING * 2);
+            //        putPositionY = point3D.X - 920 + 130;
+            //        takePositionY = length - MinY - 130;
+
+            //        if (putPositionY < 0 && takePositionY + putPositionY >= 0)
+            //        {
+            //            takePositionY += putPositionY;
+            //            putPositionY = 0;
+            //        }
+            //        positionR = 2;
+            //    }
+            //}
+
+            if (positionR == 2 && edge == 0)
+            {
+                takePositionX = width - 530;
+                putPositionX = point3D.Y;
+            }
+            else if (positionR == 2 && edge == 1)
+            {
+                takePositionX = 0;
+                putPositionX = point3D.Y + width - 530;
+            }
+            else if (positionR == 1 && edge == 1)
+            {
+                takePositionX = width - 530;
+                putPositionX = point3D.Y + (width - 530);
+            }
+            else if (positionR == 1 && edge == 0)
+            {
+                if (putPositionX < 0)
+                {
+                    takePositionX = 0;
+                    putPositionX = point3D.Y;
+                }
+            }
+
+            if (takePositionY < 0 && Math.Abs(takePositionY) < SPACING)
+            {
+                takePositionY = 0;
+            }
+
+            TaskPosition taskPosition = new TaskPosition()
+            {
+                PositionR = positionR,
+                TakePositionX = takePositionX,
+                TakePositionY = takePositionY,
+                TakePositionZ = takePositionZ,
+                PutPositionX = putPositionX,
+                PutPositionY = putPositionY,
+                PutPositionZ = putPositionZ,
+                TakeCenterPositionX = takeCenter.X,
+                TakeCenterPositionY = takeCenter.Y,
+                TakeCenterPositionZ = takeCenter.Z,
+                PutCenterPositionX = putCenter.X,
+                PutCenterPositionY = putCenter.Y,
+                PutCenterPositionZ = putCenter.Z,
+                PositionX = point3D.X,
+                PositionY = point3D.Y,
+                PositionZ = point3D.Z
+            };
+
+            return taskPosition;
+        }
     }
 }
\ No newline at end of file

--
Gitblit v1.9.3