求C# 矩形排版源码 有愿意分享或接外包的 私信

dovei 2021-02-05 02:47:50
二维最化排版,例:
输入大板材长*宽:1500*2000
输入小板长*宽-数量:100*150-20、30*50-26、36.5*84-19…… 只有矩形和圆形

然后开始计算排版、生成排版图,如:

有愿意分享或接外包的 来私信
...全文
1079 31 打赏 收藏 举报
写回复
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
dovei 2021-04-29
顶一下看看,
  • 打赏
  • 举报
回复
泡泡龙 2021-04-29
年年都有搞这个的,我不建议大家接这个,因为复杂程度会超出你们的想象。 勉强做出来,也会被人说不合格
  • 打赏
  • 举报
回复
luj_1768 2021-02-10
介绍一个思路:1. 计算几种不同尺寸各自的总面积,用于确认料是否够用;2. 把需要裁剪尺寸按从大到小排队,面积、长、宽优先递次;3. 按尺寸大的满方优先分配,尺寸小的插边分配,进行试凑;4. 试凑成功的话,输出自上到下、自左到右排列,并打印图形。
  • 打赏
  • 举报
回复
luj_1768 2021-02-10
下料,按矩形算一般都是粗胚,确实可以不考虑锯线宽。另外,可以把锯线宽加到尺寸中。
  • 打赏
  • 举报
回复
吉普赛的歌 2021-02-09
楼主,建议你还是弄清楚需求。 锯片宽度一般要留 5mm 出来,这个要考虑的了。
  • 打赏
  • 举报
回复
把初始阴影列表(大板)改一下
          var a = new MyList { { 250, 400 } };
你可以看到小板的排列位置也改变了。 主要的技术就是搞懂那个“算法”方法。 同时要搞懂 .net 的“迭代器”技术,它能帮助你写出精炼的查找算法的对外接口。这里也使用到了 Linq for object(where、min、max 等),帮助你精炼地写查找算法的内部逻辑。 这里也用了c#语言的针对集合结构的 Add 方法的“语法糖”,方便自己简化地书写集合对象的初始化代码(使用大括号语法来设置初始值)。
  • 打赏
  • 举报
回复
给你写一下算法例子:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {

            var s = new MyList { { 100, 200 }, { 100, 200 }, { 100, 1500 }, { 30, 50 }, { 40, 80 } };
            var a = new MyList { { 250, 800 } };
            var result = 排列(a.List, s.List);
            Console.WriteLine("输出排列:");
            var cnt = 0;
            foreach (var r in result)
            {
                Console.WriteLine($"第 {++cnt,2} 块:x={r.X}   y={r.Y}   w={r.Width}   h={r.Height}");
            }
        }

        static IEnumerable<Block> 排列(List<Block> 阴影, List<Block> 待排列)
        {
            foreach (var x in 待排列)
            {
                var 宽度适配 = 阴影.Where(b => b.Width >= x.Width).ToList();
                if (宽度适配.Count > 0)
                {
                    var 最小宽度 = 宽度适配.Min(b => b.Width);
                    var 高度适配 = 阴影.Where(b => b.Width == 最小宽度 && b.Height >= x.Height).ToList();
                    if (高度适配.Count > 0)
                    {
                        var 最小高度 = 高度适配.Min(b => b.Height);
                        var find = 阴影.Where(b => b.Width == 最小宽度 && b.Height == 最小高度).FirstOrDefault();  //要把x放入这块儿矩形里边
                        if (find != null)      //如果当前的x无法放入,则跳过它
                        {
                            阴影.Remove(find);
                            if (find.Width - x.Width > 0)
                                阴影.Add(new Block { X = find.X + x.Width, Y = find.Y, Width = find.Width - x.Width, Height = x.Height });
                            if (find.Height - x.Height > 0)
                                阴影.Add(new Block { X = find.X, Y = find.Y + x.Height, Width = x.Width, Height = find.Height - x.Height });
                            if (find.Width - x.Width > 0 && find.Height - x.Height > 0)
                                阴影.Add(new Block { X = find.X + x.Width, Y = find.Y + x.Height, Width = find.Width - x.Width, Height = find.Height - x.Height });
                            x.X = find.X;
                            x.Y = find.Y;
                            yield return x;
                        }
                    }
                }
            }
        }
    }

    public class MyList : IEnumerable<Block>
    {
        public void Add(int w, int h)
        {
            List.Add(new Block { Width = w, Height = h });
        }

        public List<Block> List = new List<Block>();

        public IEnumerator<Block> GetEnumerator()
        {
            return List.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }


    public class Block
    {
        public int X;
        public int Y;
        public int Width;
        public int Height;
    }
}
这里,首先假设“大阴影”只有一块,宽和高为250x800,要放入5块小板,调用算法“排列”来输出所有能放入阴影的小板列表。 从输出可以看到,输出了4块小板,分别在原来小板 Block 数据结构中填写上了 .X 和 .Y 坐标属性值。而有一块小板无法放入。 算法其实是很简单的贪心算法:首先寻找宽度最小的阴影,然后在宽度最小的那些阴影中寻找高度最小的阴影,最后将小板放入这块阴影(将阴影从列表中Remove掉,替换插入1、3、0个新的阴影)。如此迭代遍历所有小板。
  • 打赏
  • 举报
回复
“留宽度”通常就是指“数据一致化”,例如小板的尺寸是一定数值的整倍数,这样就能让结果看起来更整齐。
  • 打赏
  • 举报
回复
dovei 2021-02-09
引用 23 楼 以专业开发人员为伍 的回复:
把初始阴影列表(大板)改一下
          var a = new MyList { { 250, 400 } };
你可以看到小板的排列位置也改变了。 主要的技术就是搞懂那个“算法”方法。 同时要搞懂 .net 的“迭代器”技术,它能帮助你写出精炼的查找算法的对外接口。这里也使用到了 Linq for object(where、min、max 等),帮助你精炼地写查找算法的内部逻辑。 这里也用了c#语言的针对集合结构的 Add 方法的“语法糖”,方便自己简化地书写集合对象的初始化代码(使用大括号语法来设置初始值)。
非常非常感谢热心的技术大咖
  • 打赏
  • 举报
回复
dovei 2021-02-09
引用 24 楼 吉普赛的歌 的回复:
楼主,建议你还是弄清楚需求。 锯片宽度一般要留 5mm 出来,这个要考虑的了。
非常确定,不需要锯片宽度
  • 打赏
  • 举报
回复
dovei 2021-02-08
引用 14 楼 以专业开发人员为伍 的回复:
[quote=引用 11 楼 longsky 的回复:]不需要考虑板间缝隙吗?实际下料锯缝不小的。
我举的“图片流”的“高100宽80”的例子既是类似的考虑,适当放大并且对数据一致化整理,会让操作结果少一写烦恼。[/quote] 嗯嗯,现在脑袋还是一团浆糊,懵得一B,无从下手
  • 打赏
  • 举报
回复
引用 11 楼 longsky 的回复:
不需要考虑板间缝隙吗?实际下料锯缝不小的。
我举的“图片流”的“高100宽80”的例子既是类似的考虑,适当放大并且对数据一致化整理,会让操作结果少一写烦恼。
  • 打赏
  • 举报
回复
xuzuning 2021-02-08
按剩余矩形法为基础展开思路,二维下料算法之所以被称为世界性难题,就是因为他没有现成的算法,二总是有人试图一劳永逸的解决他
  • 打赏
  • 举报
回复
SkyLee708 2021-02-08
mark一下,学习
  • 打赏
  • 举报
回复
dovei 2021-02-08
引用 11 楼 longsky 的回复:
不需要考虑板间缝隙吗?实际下料锯缝不小的。
不用的。
  • 打赏
  • 举报
回复
Leo1970 2021-02-08
我在2014年就写过几乎和你这个需求一模一样的demo,其实算法还是比较复杂的,写了我2个小时,包含图形化结果,当时也是一位网友提出的问题,具体请参考: https://q.cnblogs.com/q/64457/ 我还将这个算法开源了,挂到GitHub上了: https://github.com/leotsai/BlockCalculator 下面是计算结果,如果看不懂或者需要定制开发,可以加我QQ,当然,收费 哈。
  • 打赏
  • 举报
回复
xuzuning 2021-02-08
画出来的图形?换个位置再画
  • 打赏
  • 举报
回复
dovei 2021-02-08
引用 16 楼 xuzuning 的回复:
怎么能无从下手?只要你在区域里放下第一块,区域就会呈现田字形,被分割成 四块。那些空闲的区域就是所谓剩余矩形,对于每一个 剩余矩形都去尝试放一个下去.......就是你要的答案
请教版主另外一个问题,Gdi+画出来的图形,目前解决了拖动和旋转,有什么方法可以 在 拖动时 提示对齐的辅助线么?类似这样的
  • 打赏
  • 举报
回复
dovei 2021-02-08
引用 16 楼 xuzuning 的回复:
怎么能无从下手?只要你在区域里放下第一块,区域就会呈现田字形,被分割成 四块。那些空闲的区域就是所谓剩余矩形,对于每一个 剩余矩形都去尝试放一个下去.......就是你要的答案
只会简单的循环,其他高阶写法 还没掌握。。
  • 打赏
  • 举报
回复
xuzuning 2021-02-08
怎么能无从下手?只要你在区域里放下第一块,区域就会呈现田字形,被分割成 四块。那些空闲的区域就是所谓剩余矩形,对于每一个 剩余矩形都去尝试放一个下去.......就是你要的答案
  • 打赏
  • 举报
回复
加载更多回复(11)
相关推荐
发帖
C#

10.8w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
帖子事件
创建了帖子
2021-02-05 02:47
社区公告

让您成为最强悍的C#开发者