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 | 468 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 364 insertions(+), 104 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..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,13 +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> /// 瀹瑰櫒灏哄 @@ -25,8 +61,8 @@ 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) { @@ -53,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> @@ -136,17 +208,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)) @@ -154,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; + } + } } } @@ -173,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) @@ -182,38 +331,6 @@ } 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> @@ -237,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 => @@ -253,74 +375,212 @@ return xOverlap && yOverlap && zOverlap; }); } - } - /// <summary> - /// 涓夌淮鍧愭爣缁撴瀯浣� - /// 琛ㄧず璐х墿鏀剧疆浣嶇疆鐨勫乏涓嬪墠瑙掑潗鏍囷紙X,Y,Z锛� - /// 鍧愭爣绯昏鏄庯細 - /// - X杞达細娌垮鍣ㄩ暱搴︽柟鍚� - /// - Y杞达細娌垮鍣ㄥ搴︽柟鍚� - /// - Z杞达細鍨傜洿鏂瑰悜锛堥珮搴︼級 - /// </summary> - public struct Point3D - { - /// <summary>X杞村潗鏍囷紙姣背锛�</summary> - public int X { get; } - - /// <summary>Y杞村潗鏍囷紙姣背锛�</summary> - public int Y { get; } - - /// <summary>Z杞村潗鏍囷紙姣背锛�</summary> - public int Z { get; } - - public Point3D(int x, int y, int z) + private bool IsPositionValid(TaskPosition pos) { - X = x; - Y = y; - Z = z; + // 杈圭晫妫�鏌ワ紙鍚鍣ㄨ竟缂橀棿闅旓級 + //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; } - } - /// <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) + 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; // 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