From e46aa927d231af83724683c7286d9db503e24cf7 Mon Sep 17 00:00:00 2001
From: z8018 <1282578289@qq.com>
Date: 星期二, 10 六月 2025 11:46:20 +0800
Subject: [PATCH] 1

---
 项目代码/WCS/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/PlaceBlockService.cs |  590 +++++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 438 insertions(+), 152 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 4248711..d214f45 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,13 +3,76 @@
 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
 {
+    /// <summary>
+    /// 璐х墿鏀剧疆鏈嶅姟锛屾彁渚涢泦瑁呯鍐呰揣鐗╂憜鏀句綅缃绠楀姛鑳�
+    /// </summary>
+    /// <remarks>
+    /// 涓昏鍔熻兘鍖呮嫭锛� <br/>
+    /// 1. 鏍规嵁璐х墿灏哄鑷姩璁$畻鏈�浼樻憜鏀句綅缃� <br/>
+    /// 2. 鏀寔妯悜/绾靛悜涓ょ鎽嗘斁鏂瑰紡 <br/>
+    /// 3. 鑰冭檻鍚哥洏灏哄銆佸鍣ㄨ竟鐣岀瓑鐗╃悊闄愬埗 <br/>
+    /// 4. 鎻愪緵浠诲姟浣嶇疆鍧愭爣杞崲鍔熻兘 <br/>
+    ///  <br/>
+    /// 鏍稿績鍙傛暟锛� <br/>
+    /// - SPACING: 璐х墿闂存渶灏忛棿璺� <br/>
+    /// - MaxRotateLength: 鏈�澶ф棆杞暱搴﹂檺鍒� <br/>
+    /// - MaxY/MinY: Y杞村潗鏍囬檺鍒� <br/>
+    /// - SuctionLength/Width: 鍚哥洏灏哄鍙傛暟
+    /// </remarks>
     public class PlaceBlockService
     {
-        public const int SPACING = 5;
+        /// <summary>
+        /// 鑾峰彇閰嶇疆鏂囦欢涓�"Spacing"閿搴旂殑鏁存暟鍊硷紝琛ㄧず闂磋窛鍊�
+        /// </summary>
+        public static int SPACING = AppSettings.GetValue("Spacing").ObjToInt();
+
+        /// <summary>
+        /// 鑾峰彇鎴栬缃渶澶ф棆杞暱搴﹂厤缃��
+        /// </summary>
+        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>
+        /// 鏃嬭浆鎶撳彇Y杞村亸绉婚噺锛堟绫筹級
+        /// </summary>
+        public static int RotateYOffset = AppSettings.GetValue("RotateYOffset").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>
         /// 瀹瑰櫒灏哄
@@ -21,12 +84,25 @@
         /// </summary>
         public List<PlacedBlock> PlacedBlocks { get; private set; }
 
+        /// <summary>
+        /// 瀹瑰櫒鍦版澘鐨勬斁缃潡瀹炰緥
+        /// </summary>
         private readonly PlacedBlock containerFloor;
 
+        /// <summary>
+        /// 鍒濆鍖栨斁缃尯鍧楁湇鍔�
+        /// </summary>
+        /// <param name="containerSize">瀹瑰櫒灏哄</param>
+        /// <param name="placedBlocks">宸叉斁缃尯鍧楀垪琛紝鍙�夊弬鏁�</param>
+        /// <remarks>
+        /// 鏋勯�犲嚱鏁颁細鍒濆鍖栧鍣ㄥ昂瀵稿拰宸叉斁缃尯鍧楀垪琛ㄣ��
+        /// 濡傛灉鏈彁渚沺lacedBlocks鎴栧垪琛ㄤ负绌猴紝灏嗗垱寤烘柊鐨勭┖鍒楄〃銆�
+        /// 鍚屾椂浼氬垱寤鸿〃绀哄鍣ㄥ簳閮ㄧ殑PlacedBlock瀵硅薄銆�
+        /// </remarks>
         public PlaceBlockService(ContainerSize containerSize, List<PlacedBlock>? placedBlocks = null)
         {
-            containerSize.Length = containerSize.Length + 2 * SPACING;
-            containerSize.Width = containerSize.Width + 2 * SPACING;
+            containerSize.Length = containerSize.Length;
+            containerSize.Width = containerSize.Width;
             ContainerSize = containerSize;
             if (placedBlocks == null || placedBlocks.Count == 0)
             {
@@ -36,23 +112,33 @@
             {
                 PlacedBlocks = placedBlocks;
             }
+            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);
+            //containerFloor = new PlacedBlock(new Point3D(SPACING, SPACING, 0), ContainerSize.Length - 2 * SPACING, ContainerSize.Width - 2 * SPACING, 0);
         }
 
         /// <summary>
-        /// 涓绘斁缃柟娉曪細灏濊瘯鏀剧疆鎸囧畾灏哄鐨勮揣鐗�
+        /// 鏍规嵁缁欏畾鐨勯暱瀹介珮瀵绘壘鍚堥�傜殑鏀剧疆浣嶇疆
         /// </summary>
-        /// <param name="length">璐х墿闀垮害锛圶杞存柟鍚戯級</param>
-        /// <param name="width">璐х墿瀹藉害锛圷杞存柟鍚戯級</param>
-        /// <param name="height">璐х墿楂樺害锛圸杞存柟鍚戯級</param>
-        /// <returns>
-        /// 鎴愬姛锛氳繑鍥炲彲鏀剧疆浣嶇疆鐨勫乏涓嬪墠瑙扨oint3D鍧愭爣
-        /// 澶辫触锛氳繑鍥瀗ull锛堝昂瀵告棤鏁堟垨绌洪棿涓嶈冻锛�
-        /// </returns>
+        /// <param name="length">鍧楃殑闀垮害</param>
+        /// <param name="width">鍧楃殑瀹藉害</param>
+        /// <param name="height">鍧楃殑楂樺害</param>
+        /// <returns>鍙斁缃殑3D鍧愭爣鐐癸紝鑻ユ棤娉曟斁缃垯杩斿洖null</returns>
+        /// <remarks>
+        /// 鏂规硶浼氳嚜鍔ㄥ鐞嗛暱瀹藉弬鏁帮紝纭繚length >= width
+        /// 鍦ㄦ斁缃墠浼氬厛妫�鏌ュ潡鐨勬湁鏁堟��
+        /// </remarks>
         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;
 
@@ -60,35 +146,68 @@
         }
 
         /// <summary>
-        /// 楠岃瘉璐х墿灏哄鏈夋晥鎬�
-        /// 鏍¢獙瑙勫垯锛�
-        /// 1. 鍚勭淮搴﹀昂瀵稿繀椤诲ぇ浜庣瓑浜�50mm
-        /// 2. 鍚勭淮搴﹀昂瀵镐笉寰楄秴杩囧鍣ㄥ搴旂淮搴︼紙鎵i櫎闂撮殧鍚庯級
-        /// 3. 楂樺害蹇呴』 <= 瀹瑰櫒鍓╀綑楂樺害
+        /// 鏍规嵁缁欏畾鐨勯暱銆佸銆侀珮鍜岃竟缂樺�兼斁缃竴涓潡锛屽苟杩斿洖鍙斁缃殑浣嶇疆
         /// </summary>
-        /// <param name="l"></param>
-        /// <param name="w"></param>
-        /// <param name="h"></param>
-        /// <returns></returns>
-        private bool IsValidBlock(int l, int w, int h)
+        /// <param name="length">鍧楃殑闀垮害</param>
+        /// <param name="width">鍧楃殑瀹藉害</param>
+        /// <param name="height">鍧楃殑楂樺害</param>
+        /// <param name="edge">杈圭紭鍊�</param>
+        /// <returns>鍙斁缃殑浣嶇疆淇℃伅锛岃嫢鍧楁棤鏁堝垯杩斿洖null</returns>
+        public TaskPosition? PlaceBlock(int length, int width, int height, int edge)
         {
-            return l > 0 && w > 0 && h > 0 &&
-                   l <= ContainerSize.Length - 2 * SPACING &&
-                   w <= ContainerSize.Width - 2 * SPACING &&
-                   h < ContainerSize.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, edge);
         }
 
         /// <summary>
-        /// 鍦ㄧ幇鏈夎揣鐗╅《閮ㄥ鎵惧彔鏀句綅缃紙鍫嗗彔妯″紡锛�
-        /// 鍙犳斁鏉′欢锛�
-        /// - 鏀拺闈㈢Н >= 琚敮鎾戦潰闈㈢Н鐨�70%
-        /// - 鏂拌揣鐗╁畬鍏ㄤ綅浜庢敮鎾戣揣鐗╀笂鏂�
-        /// - 婊¤冻闂撮殧瑕佹眰
+        /// 妫�鏌ョ粰瀹氱殑闀垮楂樻槸鍚︽瀯鎴愭湁鏁堢殑鍧椾綋灏哄
         /// </summary>
         /// <param name="l">闀垮害</param>
         /// <param name="w">瀹藉害</param>
         /// <param name="h">楂樺害</param>
-        /// <returns></returns>
+        /// <returns>濡傛灉灏哄鏈夋晥杩斿洖true锛屽惁鍒欒繑鍥瀎alse</returns>
+        /// <remarks>
+        /// 鏈夋晥鍧椾綋闇�婊¤冻锛氶暱瀹介珮閮藉ぇ浜�0锛屼笖闀垮涓嶈秴杩囧鍣ㄥ昂瀵稿噺鍘讳袱鍊嶉棿璺濓紝楂樺害涓嶈秴杩囧鍣ㄩ珮搴�
+        /// </remarks>
+        private bool IsValidBlock(int l, int w, int h)
+        {
+            return l > 0 && w > 0 && h > 0 &&
+                   l <= ContainerSize.Length &&
+                   w <= ContainerSize.Width &&
+                   h < ContainerSize.Height;
+        }
+
+        //private bool IsValidBlock(int l, int w, int h)
+        //{
+        //    return l > 0 && w > 0 && h > 0 &&
+        //           l <= ContainerSize.Length - 2 * SPACING &&
+        //           w <= ContainerSize.Width - 2 * SPACING &&
+        //           h < ContainerSize.Height;
+        //}
+
+        /// <summary>
+        /// 鍦ㄥ鍣ㄤ腑鏌ユ壘鍙斁缃寚瀹氬昂瀵稿潡浣撶殑鏈夋晥浣嶇疆
+        /// </summary>
+        /// <param name="l">鍧椾綋闀垮害</param>
+        /// <param name="w">鍧椾綋瀹藉害</param>
+        /// <param name="h">鍧椾綋楂樺害</param>
+        /// <returns>鍙斁缃綅缃殑3D鍧愭爣鐐癸紝鑻ユ棤鍚堥�備綅缃垯杩斿洖null</returns>
+        /// <remarks>
+        /// 1. 閫氳繃鍒嗘瀽宸叉斁缃潡浣撶敓鎴愬�欓�夋敮鎾戝眰
+        /// 2. 鑰冭檻瀹瑰櫒搴曢儴鍜屾敮鎾戝潡鐨勪笉鍚岄棿闅旇鍒�
+        /// 3. 浼樺厛妫�鏌ヨ钀戒綅缃互鎻愰珮鎼滅储鏁堢巼
+        /// </remarks>
         private Point3D? FindStackablePosition(int l, int w, int h)
         {
             // 鐢熸垚鍊欓�夋敮鎾戝眰锛堝寘鍚鍣ㄥ簳閮級
@@ -136,17 +255,12 @@
                     xEnd = Math.Min(xEnd, ContainerSize.Length - l - SPACING);
                     yEnd = Math.Min(yEnd, ContainerSize.Width - w - SPACING);
 
-                    // 楠岃瘉鏀拺闈㈢Н
-                    //int supportArea = support.Length * support.Width;
-                    //int requiredSupportArea = (int)(l * w * 0.7); // 鏀拺闈㈢Н >= 琚敮鎾戦潰闈㈢Н鐨�70%
-                    //if (supportArea < requiredSupportArea) continue;
-
                     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))
@@ -163,17 +277,86 @@
         }
 
         /// <summary>
-        /// 鑾峰彇鏀拺褰撳墠璐х墿鐨勫簳灞傝揣鐗╁垪琛�
-        /// 鐗规畩澶勭悊锛氬綋baseZ=0鏃惰繑鍥炶櫄鎷熷鍣ㄥ簳閮ㄤ綔涓烘敮鎾�
-        /// 鏀拺鏉′欢锛氳揣鐗╁簳闈笌鏀拺璐х墿椤堕潰鎺ヨЕ涓擹鍧愭爣鍖归厤
+        /// 鍦ㄥ鍣ㄤ腑鏌ユ壘鍙爢鍙犱綅缃�
         /// </summary>
-        /// <param name="baseZ">鏀拺鍧楅珮搴�</param>
-        /// <returns></returns>
+        /// <param name="l">鐗╁搧闀垮害</param>
+        /// <param name="w">鐗╁搧瀹藉害</param>
+        /// <param name="h">鐗╁搧楂樺害</param>
+        /// <param name="edge">杈圭紭绫诲瀷</param>
+        /// <returns>杩斿洖鎵惧埌鐨勬湁鏁堜换鍔′綅缃紝鑻ユ壘涓嶅埌鍒欒繑鍥瀗ull</returns>
+        /// <remarks>
+        /// 1. 鐢熸垚鍊欓�夋敮鎾戝眰锛堝寘鍚鍣ㄥ簳閮級
+        /// 2. 閬嶅巻姣忓眰鏀拺鍧楄绠楁湁鏁堝彔鏀惧尯鍩�
+        /// 3. 鑰冭檻瀹瑰櫒杈圭晫绾︽潫鍜岄棿闅旇鍒�
+        /// 4. 浼樺厛妫�鏌ヨ钀戒綅缃互鎻愰珮鎼滅储鏁堢巼
+        /// </remarks>
+        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;
+
+                    int xEnd = support.Position.X + support.Length - l;
+                    int yEnd = support.Position.Y + support.Width - w;
+
+                    // 鏈�缁堝鍣ㄨ竟鐣岀害鏉�
+                    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;
+                                }
+
+                            }
+                        }
+                    }
+                }
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// 鑾峰彇鎸囧畾楂樺害灞傜殑鏀拺鍧�
+        /// </summary>
+        /// <param name="baseZ">闇�瑕佹敮鎾戠殑楂樺害灞�</param>
+        /// <returns>鎸夐潰绉粠澶у埌灏忔帓搴忕殑鏀拺鍧楅泦鍚堬紝褰揵aseZ=0涓旀棤鏀拺鍧楁椂杩斿洖瀹瑰櫒搴曢儴</returns>
         private IEnumerable<PlacedBlock> GetSupportBlocks(int baseZ)
         {
             var blocks = PlacedBlocks
                 .Where(b => b.Position.Z + b.Height == baseZ)
-                .OrderByDescending(b => b.Length * b.Width).ToList();
+                .OrderBy(b => b.Position.X)
+                .ThenBy(b => b.Position.Y)
+                /*.OrderByDescending(b => b.Length * b.Width)*/
+                .ToList();
 
             // 褰揵aseZ=0鏃舵坊鍔犲鍣ㄥ簳閮ㄦ敮鎾�
             if (baseZ == 0 && blocks.Count == 0)
@@ -182,62 +365,34 @@
             }
 
             return blocks;
-
-
-            //// 鑾峰彇鎵�鏈夊湪 baseZ 楂樺害鐨勬敮鎾戝潡
-            //var blocks = PlacedBlocks
-            //    .Where(b => b.Position.Z + b.Height == baseZ)
-            //    .ToList();
-
-            //// 褰� baseZ=0 鏃舵坊鍔犲鍣ㄥ簳閮ㄦ敮鎾�
-            //if (baseZ == 0 && !blocks.Any())
-            //{
-            //    return new List<PlacedBlock> { containerFloor };
-            //}
-
-            //// 璁$畻鏁翠綋骞抽潰
-            //if (blocks.Any())
-            //{
-            //    int minX = blocks.Min(b => b.Position.X);
-            //    int minY = blocks.Min(b => b.Position.Y);
-            //    int maxX = blocks.Max(b => b.Position.X + b.Length);
-            //    int maxY = blocks.Max(b => b.Position.Y + b.Width);
-
-            //    var overallSupport = new PlacedBlock(
-            //        new Point3D(minX, minY, baseZ),
-            //        maxX - minX,
-            //        maxY - minY,
-            //        0
-            //    );
-
-            //    return new List<PlacedBlock> { overallSupport };
-            //}
-
-            //return blocks;
         }
 
         /// <summary>
-        /// 楠岃瘉鎸囧畾浣嶇疆鏄惁鍚堟硶
-        /// 鏍¢獙鍐呭锛�
-        /// 1. 杈圭晫鏉′欢锛氳揣鐗╀笉寰楄秴鍑哄鍣ㄦ湁鏁堢┖闂�
-        /// 2. 纰版挒妫�娴嬶細涓庡凡鏀剧疆璐х墿鏃犵┖闂撮噸鍙�
-        /// 3. 闂撮殧瑕佹眰锛氫繚鎸佹渶灏忛棿闅旓紙SPACING甯搁噺锛�
+        /// 妫�鏌ユ寚瀹氫綅缃槸鍚︽湁鏁堬紝鍗宠浣嶇疆鏄惁鍙互鏀剧疆鎸囧畾灏哄鐨勫潡浣�
         /// </summary>
-        /// <param name="pos">鍧愭爣</param>
-        /// <param name="l">闀垮害</param>
-        /// <param name="w">瀹藉害</param>
-        /// <param name="h">楂樺害</param>
-        /// <returns></returns>
+        /// <param name="pos">瑕佹鏌ョ殑浣嶇疆鍧愭爣</param>
+        /// <param name="l">鍧椾綋闀垮害</param>
+        /// <param name="w">鍧椾綋瀹藉害</param>
+        /// <param name="h">鍧椾綋楂樺害</param>
+        /// <returns>濡傛灉浣嶇疆鏈夋晥涓斾笉涓庡叾浠栧凡鏀剧疆鍧椾綋閲嶅彔鍒欒繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse</returns>
+        /// <remarks>
+        /// 妫�鏌ユ潯浠跺寘鎷細
+        /// 1. 鏄惁瓒呭嚭瀹瑰櫒灏哄闄愬埗
+        /// 2. X鍧愭爣鏄惁瓒呰繃1600闄愬埗
+        /// 3. 褰揦鍧愭爣瓒呰繃MaxY涓旈暱搴﹁秴杩嘙axRotateLength鏃剁殑闄愬埗
+        /// 4. 鏄惁涓庡凡鏀剧疆鐨勫潡浣撳彂鐢熼噸鍙狅紙鑰冭檻SPACING闂磋窛锛�
+        /// </remarks>
         private bool IsPositionValid(Point3D pos, int l, int w, int h)
         {
-            // 杈圭晫妫�鏌ワ紙鍚鍣ㄨ竟缂橀棿闅旓級
-            if (pos.X < SPACING ||
-                pos.Y < SPACING ||
-                pos.X + l > ContainerSize.Length - SPACING ||
-                pos.Y + w > ContainerSize.Width - SPACING)
+            if (pos.X + l > ContainerSize.Length ||
+                pos.Y + w > ContainerSize.Width)
                 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 =>
             {
@@ -253,74 +408,205 @@
                 return xOverlap && yOverlap && zOverlap;
             });
         }
-    }
 
-    /// <summary>
-    /// 涓夌淮鍧愭爣缁撴瀯浣�
-    /// 琛ㄧず璐х墿鏀剧疆浣嶇疆鐨勫乏涓嬪墠瑙掑潗鏍囷紙X,Y,Z锛�
-    /// 鍧愭爣绯昏鏄庯細
-    /// - X杞达細娌垮鍣ㄩ暱搴︽柟鍚�
-    /// - Y杞达細娌垮鍣ㄥ搴︽柟鍚�
-    /// - Z杞达細鍨傜洿鏂瑰悜锛堥珮搴︼級
-    /// </summary>
-    public struct Point3D
-    {
-        /// <summary>X杞村潗鏍囷紙姣背锛�</summary>
-        public int X { get; }
+        //private bool IsPositionValid(Point3D pos, int l, int w, int h)
+        //{
+        //    // 杈圭晫妫�鏌ワ紙鍚鍣ㄨ竟缂橀棿闅旓級
+        //    if (pos.X < SPACING ||
+        //        pos.Y < SPACING ||
+        //        pos.X + l > ContainerSize.Length - SPACING ||
+        //        pos.Y + w > ContainerSize.Width - SPACING)
+        //        return false;
 
-        /// <summary>Y杞村潗鏍囷紙姣背锛�</summary>
-        public int Y { get; }
+        //    if (pos.X > 1600)
+        //        return false;
 
-        /// <summary>Z杞村潗鏍囷紙姣背锛�</summary>
-        public int Z { get; }
+        //    if (pos.X > MaxY && l > MaxRotateLength) return false;
 
-        public Point3D(int x, int y, int z)
+        //    // 涓夌淮纰版挒妫�娴�
+        //    var newBlock = new PlacedBlock(pos, l, w, h);
+        //    return !PlacedBlocks.Any(existing =>
+        //    {
+        //        bool xOverlap = newBlock.Position.X < existing.Position.X + existing.Length + SPACING &&
+        //                      newBlock.Position.X + newBlock.Length + SPACING > existing.Position.X;
+
+        //        bool yOverlap = newBlock.Position.Y < existing.Position.Y + existing.Width + SPACING &&
+        //                      newBlock.Position.Y + newBlock.Width + SPACING > existing.Position.Y;
+
+        //        bool zOverlap = newBlock.Position.Z < existing.Position.Z + existing.Height &&
+        //                      newBlock.Position.Z + h > existing.Position.Z;
+
+        //        return xOverlap && yOverlap && zOverlap;
+        //    });
+        //}
+
+        /// <summary>
+        /// 妫�鏌ヤ换鍔′綅缃槸鍚︽湁鏁�
+        /// </summary>
+        /// <param name="pos">瑕佹鏌ョ殑浠诲姟浣嶇疆</param>
+        /// <returns>濡傛灉Y杞村潗鏍囧湪鏈夋晥鑼冨洿鍐呰繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse</returns>
+        private bool IsPositionValid(TaskPosition pos)
         {
-            X = x;
-            Y = y;
-            Z = z;
+            return pos.PutPositionY <= MaxY && pos.PutPositionY >= 0 && pos.TakePositionY >= 0;
         }
-    }
 
-    /// <summary>
-    /// 宸叉斁缃揣鐗╀俊鎭被
-    /// 璁板綍姣忎釜璐х墿鐨勪綅缃拰灏哄淇℃伅
-    /// 鍧愭爣绯昏鏄庯細浣嶇疆鐐逛负璐х墿鐨勫乏涓嬪墠瑙掑潗鏍�
-    /// </summary>
-    public class PlacedBlock
-    {
-        /// <summary>璐х墿宸︿笅鍓嶈鍧愭爣</summary>
-        public Point3D Position { get; }
-
-        /// <summary>娌縓杞存柟鍚戦暱搴︼紙姣背锛�</summary>
-        public int Length { get; }
-
-        /// <summary>娌縔杞存柟鍚戝搴︼紙姣背锛�</summary>
-        public int Width { get; }
-
-        /// <summary>娌縕杞存柟鍚戦珮搴︼紙姣背锛�</summary>
-        public int Height { get; }
-
-        public PlacedBlock(Point3D position, int length, int width, int height)
+        /// <summary>
+        /// 鏍规嵁缁欏畾鐨勪笁缁村潗鏍囧拰灏哄鍙傛暟璁$畻浠诲姟浣嶇疆淇℃伅
+        /// </summary>
+        /// <param name="point3D">璧峰涓夌淮鍧愭爣鐐�</param>
+        /// <param name="length">鐗╀綋闀垮害</param>
+        /// <param name="width">鐗╀綋瀹藉害</param>
+        /// <param name="height">鐗╀綋楂樺害</param>
+        /// <param name="edge">杈圭紭鏍囪瘑(0/1)</param>
+        /// <returns>鍖呭惈鍙栨斁璐т綅缃俊鎭殑TaskPosition瀵硅薄</returns>
+        /// <remarks>
+        /// 璇ユ柟娉曟牴鎹墿浣撳昂瀵歌嚜鍔ㄩ�夋嫨鍗曞惛鐩樻垨鍙屽惛鐩樻ā寮忥紝
+        /// 骞惰绠楀惛鐩樹腑蹇冪偣浣嶇疆锛屽悓鏃跺鐞嗚竟鐣屾潯浠堕檺鍒躲��
+        /// 妯悜鏀剧疆鏃舵渶灏廦鍧愭爣涓�155锛岀旱鍚戞椂涓�350锛屾渶澶鍧愭爣涓�700銆�
+        /// </remarks>
+        public TaskPosition GetTaskPosition(Point3D point3D, int length, int width, int height, int edge)
         {
-            Position = position;
-            Length = length;
-            Width = width;
-            Height = height;
-        }
-    }
+            //鏀捐揣浣嶇疆鏉挎潗涓績鐐�
+            Point3D putCenter = new Point3D(point3D.X + length / 2, point3D.Y + width / 2, point3D.Z + height / 2);
 
-    public struct ContainerSize
-    {
-        public int Length { get; set; }
-        public int Width { get; set; }
-        public int Height { get; set; }
+            //鍙栬揣浣嶇疆鏉挎潗涓績鐐�
+            Point3D takeCenter = new Point3D(length / 2, width / 2, height / 2);
 
-        public ContainerSize(int length, int width, int height)
-        {
-            Length = length;
-            Width = width;
-            Height = height;
+            //鍚哥洏闀�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;
+            }
+            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;
+            }
+
+            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) + MinY;
+                }
+                else
+                {
+                    int count = PlacedBlocks.Where(x => x.Position.Y == 10).Count();
+                    putPositionY = point3D.X - 920 + 130 + RotateYOffset;
+                    takePositionY = length - MinY - 130 - RotateYOffset;
+                    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)
+            {
+                if(width > ContainerSize.Width)
+                {
+                    takePositionX = 0;
+                    putPositionX = point3D.Y;
+                }
+                else
+                {
+                    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