| | |
| | | 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> |
| | | /// æå¤§Yåæ éå¶ï¼æ¯«ç±³ï¼ |
| | | /// </summary> |
| | | public const int MaxY = 600; |
| | | |
| | | /// <summary> |
| | | /// æå°æ¨ªåYåæ éå¶ï¼æ¯«ç±³ï¼ |
| | | /// </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> |
| | | /// 容å¨å°ºå¯¸ |
| | |
| | | /// </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> |
| | | /// æé 彿°ä¼åå§å容å¨å°ºå¯¸åå·²æ¾ç½®åºåå表ã |
| | | /// å¦ææªæä¾placedBlocksæå表为空ï¼å°å建æ°ç空å表ã |
| | | /// åæ¶ä¼å建表示容å¨åºé¨ç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) |
| | | { |
| | |
| | | { |
| | | 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">è´§ç©é¿åº¦ï¼Xè½´æ¹åï¼</param> |
| | | /// <param name="width">è´§ç©å®½åº¦ï¼Yè½´æ¹åï¼</param> |
| | | /// <param name="height">è´§ç©é«åº¦ï¼Zè½´æ¹åï¼</param> |
| | | /// <returns> |
| | | /// æåï¼è¿å坿¾ç½®ä½ç½®çå·¦ä¸åè§Point3Dåæ |
| | | /// 失败ï¼è¿ånullï¼å°ºå¯¸æ ææç©ºé´ä¸è¶³ï¼ |
| | | /// </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; |
| | | |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// éªè¯è´§ç©å°ºå¯¸æææ§ |
| | | /// æ ¡éªè§åï¼ |
| | | /// 1. å维度尺寸å¿
须大äºçäº50mm |
| | | /// 2. å维度尺寸ä¸å¾è¶
è¿å®¹å¨å¯¹åºç»´åº¦ï¼æ£é¤é´éåï¼ |
| | | /// 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ï¼å¦åè¿åfalse</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) |
| | | { |
| | | // çæå鿝æå±ï¼å
å«å®¹å¨åºé¨ï¼ |
| | |
| | | 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)) |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæ¯æå½åè´§ç©çåºå±è´§ç©å表 |
| | | /// ç¹æ®å¤çï¼å½baseZ=0æ¶è¿åèæå®¹å¨åºé¨ä½ä¸ºæ¯æ |
| | | /// æ¯ææ¡ä»¶ï¼è´§ç©åºé¢ä¸æ¯æè´§ç©é¡¶é¢æ¥è§¦ä¸Zåæ å¹é
|
| | | /// å¨å®¹å¨ä¸æ¥æ¾å¯å å ä½ç½® |
| | | /// </summary> |
| | | /// <param name="baseZ">æ¯æåé«åº¦</param> |
| | | /// <returns></returns> |
| | | /// <param name="l">ç©åé¿åº¦</param> |
| | | /// <param name="w">ç©å宽度</param> |
| | | /// <param name="h">ç©åé«åº¦</param> |
| | | /// <param name="edge">è¾¹ç¼ç±»å</param> |
| | | /// <returns>è¿åæ¾å°çææä»»å¡ä½ç½®ï¼è¥æ¾ä¸å°åè¿ånull</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) |
| | | { |
| | | // è®¡ç®ææå æ¾åºåï¼ä¿®æ£é´éé»è¾ï¼ |
| | | 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>æé¢ç§¯ä»å¤§å°å°æåºçæ¯æåéåï¼å½baseZ=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(); |
| | | |
| | | // å½baseZ=0æ¶æ·»å 容å¨åºé¨æ¯æ |
| | | if (baseZ == 0 && blocks.Count == 0) |
| | |
| | | } |
| | | |
| | | 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>妿ä½ç½®ææä¸ä¸ä¸å
¶ä»å·²æ¾ç½®åä½éå åè¿åtrueï¼å¦åè¿åfalse</returns> |
| | | /// <remarks> |
| | | /// æ£æ¥æ¡ä»¶å
æ¬ï¼ |
| | | /// 1. æ¯å¦è¶
åºå®¹å¨å°ºå¯¸éå¶ |
| | | /// 2. Xåæ æ¯å¦è¶
è¿1600éå¶ |
| | | /// 3. å½Xåæ è¶
è¿MaxYä¸é¿åº¦è¶
è¿MaxRotateLengthæ¶çéå¶ |
| | | /// 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 => |
| | | { |
| | |
| | | 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è½´åæ å¨ææèå´å
è¿åtrueï¼å¦åè¿åfalse</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>沿Xè½´æ¹åé¿åº¦ï¼æ¯«ç±³ï¼</summary> |
| | | public int Length { get; } |
| | | |
| | | /// <summary>沿Yè½´æ¹åå®½åº¦ï¼æ¯«ç±³ï¼</summary> |
| | | public int Width { get; } |
| | | |
| | | /// <summary>沿Zè½´æ¹åé«åº¦ï¼æ¯«ç±³ï¼</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> |
| | | /// è¯¥æ¹æ³æ ¹æ®ç©ä½å°ºå¯¸èªå¨éæ©åå¸çæåå¸ç模å¼ï¼ |
| | | /// 并计ç®å¸çä¸å¿ç¹ä½ç½®ï¼åæ¶å¤çè¾¹çæ¡ä»¶éå¶ã |
| | | /// æ¨ªåæ¾ç½®æ¶æå°Yåæ ä¸º155ï¼çºµåæ¶ä¸º350ï¼æå¤§Yåæ ä¸º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; |
| | | } |
| | | } |
| | | } |