两个步骤:第一步,导入已有户型图,第二部:系统自动智能设计。我们刨析一下实现原理。首先我们总结一下设计规律,智能匹配户型与家具无外乎两种情况:1-同户型不同家具,2-同家具不同户型。所以我们在导入户型图自动设计的时候必须先解决这两个问题:

一:假如我有若干套相同的户型,该如何自动设计不同的设计风格和设计方案?

二:假如我已有一套设计方案(所有硬装、软装家具)该如何自动智能的布置到不同的户型里?

(文末会提供实现的算法思路和源码,完整介绍如何实现‘从导入户型图到自动设计’的整个流程及原理)

我们首先看算法运行结果,即第一个问题的实际图解:(我找了几种典型户型图作为案例)

以上是相同户型图不同的家具的设计结果,由图可看出,在设计的合理性方面是不存在很大的问题的,这里面会涉及到一些算法的影响因素:房间面积、房间形状、最小区域面积、房间朝向、房间形状重心点……

下面罗列相同家具放到不同房间里的效果,这种在算法复杂度上会有较大提升,为了实现设计的合理性,我们的考量因素会更多,我们先看图,最后剖析算法实现原理和设计规律:

其实单单从图解上已经不难看出设计规律,即每一个区域设计的合理性考量。正常大脑思维对房间的设计考量因素无非:房间面积、区域面积、房间功能分块、流通性、规整等。也可加入其它考量因素例如审美相关:留白、不对称、(颜色、风格等因素本章不做探讨)视觉偏差、视觉残像等。除此之外,甚至可以加入风水考量因素:房间正朝向、软硬装家具摆放方位、八卦方位、五行方位等。

好了,图解完成,最后由具体变抽象,将实际问题转化成数学模型,通过代码描述一下具体实现:

算法思路:

考虑到文中所讲的设计合理性考量,我们需要对整个房间提取特征数据,房间中可以提取到的特征数据为:房间各个顶点的坐标、各个顶点的坐标id、墙体id、墙体长度、房间面积、房间重心点。(风格、房间类型不必纳入特征数据中)

此时设计师大脑中幻想出了一套设计方案,想通过我们的系统进行记录,则应转化成具体数据,也就是转化成如上所提取的特征数据来存储,我们通过具体图解来理解算法原理

我们分步骤讲解这两个户型中沙发茶几组合是如何由上面的房间位置自动匹配到下面的房间位置里。

一:找到距原房间沙发茶几组合的中心点最近的墙体的定比分点比例

二:由中心点向墙体做垂线,计算出垂足点距离墙体两端的距离比例,并作记录 X :Y

三:找到沙发茶几组合所距离最近墙体的距离比例,并作记录 向量DO :向量OP

四:将两个定比分点的比例转换成代码的方式:

五:程序中动态计算并存储的算法实现:

/// <summary>
    /// 获得当前家具在房间里的放置位置
    /// </summary>
    /// <param name="position">单个家具所在坐标</param>
    /// <param name="floor">家具所在房间</param>
    /// <param name="hsd_fd">家具可序列化信息</param>
    /// <returns></returns>
    public SetScorePoint GetPoint(Vector3 position, Floor floor)
    {
        //定比分点
        SetScorePoint Point = new SetScorePoint();
        //临时数据
        List<float> distancelist = new List<float>();
        //墙体集合
        List<KeyValuePair<float, Wall>> idlist = new List<KeyValuePair<float, Wall>>();
        //当前点距离墙的距离
        float tempdistance = 0;
        //对应墙体的索引
        int index = 0;
        //家具和距离最近的那面墙的垂足点坐标
        Vector3 point = new Vector3();
        //距离最近的那面墙
        Wall wall = new Wall();
        //保存所有当前点距离墙的距离
        for (int i = 0; i < floor.VHWall_List.Count; i++)
        {
            tempdistance = Vector3.Distance(position, mathf.PointForPointToABLine(position, floor.VHWall_List[i].Vector_Start, floor.VHWall_List[i].Vector_End));
            distancelist.Add(tempdistance);
            idlist.Add(new KeyValuePair<float, Wall>(tempdistance, floor.VHWall_List[i]));
        }
        //对距离排序
        distancelist.Sort();
        //获得距离最近的墙idlist[distancelist[0]],和所在墙的距离比例
        for (int i = 0; i < idlist.Count; i++)
        {
            if (idlist[i].Key == distancelist[0])
            {
                wall = idlist[i].Value;
                index = i;
                point = mathf.PointForPointToABLine(position, wall.Vector_Start, wall.Vector_End);
                break;
            }
        }
            //获得墙体id
            Point.wallid = index;
            //获得所在墙比例
            Point.i = Vector3.Distance(point, wall.Vector_Start) / Vector3.Distance(wall.Vector_End, wall.Vector_Start);
            //获得所在墙到对面墙比例
            LayerMask mask = 1 << (LayerMask.NameToLayer("Wall"));
            Ray ray = new Ray(new Vector3(position.x, 0.5f, position.z), (new Vector3(position.x, 0, position.z) - new Vector3(point.x, 0, point.z)).normalized);
            RaycastHit[] hits = Physics.RaycastAll(ray, 500, mask);
            if (hits.Length > 0)
            {
                Point.j = Vector3.Distance(position, point) / Vector3.Distance(point, hits[0].point);
            }
        }
        return Point;
    }

六:程序中具体应用设计的算法实现:

/// <summary>
    /// 定比分点算法获得位置
    /// </summary>
    /// <param name="spa"></param>
    /// <param name="room"></param>
    /// <returns></returns>
    public Vector3 GetPosition(BaseData data, VertexHelperUI_Floor room)
    {
        Point spa = data as Score;
        //最终坐标
        Vector3 position = Vector3.zero;
        //对应墙体
        Wall wall_i = new Wall();
        //定比分点在对应墙体上的坐标
        Vector3 Score_i = new Vector3();

if (spa.wallid < room.VHWall_List.Count)
        {
            wall_i = room.VHWall_List[spa.wallid];
        }
        else
        {
            wall_i = room.VHWall_List[spa.wallid % room.VHWall_List.Count];
        }

//获得定比分点墙体上坐标
        Score_i = wall_i.Vector_Start + (wall_i.Vector_End - wall_i.Vector_Start) * spa.i;
        LayerMask mask = 1 << (LayerMask.NameToLayer("Wall"));
        //顺时针转90度方向
        Vector3 forward_0 = Quaternion.AngleAxis(90, Vector3.up) * (wall_i.Vector_End - Score_i);
        Ray ray_0 = new Ray(new Vector3(Score_i.x, 0.5f, Score_i.z), new Vector3(forward_0.x, 0, forward_0.z));
        RaycastHit[] hits_0 = Physics.RaycastAll(ray_0, 500, mask);
        if (hits_0.Length > 0)
        {
            for (int i = 0; i < room.VHWall_List.Count; i++)
            {
                if (IWallManager.Instance.GetWall(hits_0[0].transform.gameObject).id == room.VHWall_List[i].ID)
                {
                    position = Score_i + (hits_0[0].point - Score_i) * spa.j;
                    return position;
                }
            }
        }

//逆时针转90度方向
        Vector3 forward_1 = Quaternion.AngleAxis(90, Vector3.down) * (wall_i.Vector_End - Score_i);
        Ray ray_1 = new Ray(new Vector3(Score_i.x, 0.5f, Score_i.z), new Vector3(forward_1.x, 0, forward_1.z));
        RaycastHit[] hits_1 = Physics.RaycastAll(ray_1, 500, mask);
        if (hits_1.Length > 0)
        {
            for (int i = 0; i < room.VHWall_List.Count; i++)
            {
                if (IWallManager.Instance.GetWall(hits_1[0].transform.gameObject).id == room.VHWall_List[i].ID)
                {
                    position = Score_i + (hits_1[0].point - Score_i) * spa.j;
                    return position;
                }
            }
        }
        return position;
     }

一切就绪,大家可以尝试把算法套用到自己的工程里,实现一下。现在先实现了初级阶段,即:仅考虑墙面的定比分点比例的自动设计,后续文章会陆续介绍如何根据房间面积、设计风格、审美、风水等因素所实现的自动设计算法思路,欢迎小伙伴们继续关注、订阅支持,谢谢。

C9:Unity3D制作智能家居设计软件——导入户型图自动设计(算法剖析+源码实现篇)相关推荐

  1. C1:Unity3D制作智能家居设计软件——前沿

    产品视频简介 智能家装设计软件 2017年还在做服装定制行业,2018莫名其妙进入了家具行业,使用Unity3D引擎从0到1做了个智能家居设计软件,接下来的篇幅会详细介绍此软件开发过程中的各个实现细节 ...

  2. C8:Unity3D制作智能家居设计软件——智能装修(三)

    设计属于艺术的范畴,但并非仅仅是设计师拥有的技能.掌握了审美规律,艺术类的工作都有规律可循. 室内设计第一步该从线条开始,设计一个房间需要考虑的因素无非面积.体积.风格.颜色.比例.想象力-- 上图为 ...

  3. C6:Unity3D制作智能家居设计软件——智能装修(一)

    ------对设计师友好------ 智能装修领域水太深,个体户正常的装修流程是:找装修公司--找设计师--设计师出效果图--用户看效果--提修改需求--设计师加班出效果图--用户看效果--提修改需求 ...

  4. C10:Unity3D制作智能家居设计软件——三步实现家具生长动画

    收到很多设计师朋友吐槽,用3Dmax做家具生长动画又慢又麻烦,能否在我的软件里出一个自动生成家具生长动画的功能? 那当然是OK的啊!设计师是我的上帝,当然要满足上帝的需求. 这篇文章是作为家具生长动画 ...

  5. C11:Unity3D制作智能家居设计软件——实现一键智能设计

    智能设计 不用动手设计???一键智能设计??? 这是人工智能AI ??? 是的,人工智能好玩的地方就在这里,AI-智能化模拟人类思考方式,合理的例用AI思维可以给各产业带来更高效的工作方式,家装设计领 ...

  6. C13:Unity3D制作智能家居设计软件——定制系统

    橱柜定制系统 大衣柜 "定制"是个庞大的工程.却又可以渗透入微.普通家庭室内装修,可用于定制的区域一般为:厨房的橱柜.卫生间卫浴.卧室衣柜.书房书柜.玄关柜.地台.榻榻米等.而这些 ...

  7. Sanliao智能家居平台软件设计

    1,本设计版权归本人所有:2.本博客禁止转载或者用本博客技术用于商业用途. 还有个重要原因我不喜欢写博客,因为linux下编辑太痛苦了.所有 的这些图纸都是我用一个叫"DIA"的软 ...

  8. 基于Unity3D的智能家居仿真系统——户型绘制基本功能介绍

    本篇我们来介绍一下左侧工具栏中基本绘制的应用. 一.墙体绘制 直墙 & 矩形墙 绘制墙体时,可以看到上方的工具栏中对墙体进行参数的设定. 弧形墙 在建筑版的户型工具中,增加了弧形墙的绘制功能, ...

  9. 基于STM32单片机的智能家居烟雾温度火灾防盗报警的设计与实现

    功能介绍 以STM32单片机作为主控系统: LCD1602液晶显示屏来显示显示测得的值: SR501人体红外感应是否有人进行防盗: 通过烟雾传感器MQ-2获取前的烟雾值: 通过DHT11温湿度传感器来 ...

  10. 活动策划书用什么计算机软件,各行业主流设计软件有哪些?(设计人员请进)...

    随着各类软件的发展,电脑在各岗位上广泛应用.由于各个岗位需求不同,所用的软件也是不同的.对于还在读书或刚进入职场的新人来说,其所在岗位需要应用到哪些软件可能并不清楚.下面将各岗位所用主流软件及软件特点 ...

最新文章

  1. 如何构造强度较高的密码
  2. 合适么?现在学ASP.NET Core入门编程……
  3. Windows 8 应用开发 - 应用栏
  4. 解决树莓派Virtualenv虚拟环境下GPIO问题
  5. 【好文收藏】k8s中Pod 无法正常解析域名:部署 DNS 调试工具排查
  6. Python 获取系统信息模块psutil(转载)
  7. -1交替c语言代码,排序(1)---------选择排序(C语言实现)(示例代码)
  8. GMP类有哪些最新发表的毕业论文呢?
  9. 你知道项目管理有哪些分类和体系吗?
  10. Unicode(全世界每个国家字符的唯一编码0x000000 到 0x10FFFF)与UTF-8的区别
  11. DCDC--开关频率的选择
  12. 美元指数的变化对国际黄金有哪些影响
  13. 数据中台技术架构方案
  14. Clickhouse 在云原生场景下的部署和使用
  15. Word删除下划线上的文字
  16. ICP-AES测试基本原理及优缺点
  17. csharp可以用来做网页吗_Csharp网页应用程序
  18. 看源码,看源码,看源码!--所有C语言函数的源代码
  19. c语言笔记:c的四舍五入
  20. Windows磁盘克隆软件推荐

热门文章

  1. C/C++编程笔记:浪漫流星雨表白程序,七夕想表白,我教你啊!
  2. 福布斯发布区块链50强 这5家中国公司上榜
  3. 八人抢答器讲解_八人智力竞赛抢答器课程设计报告
  4. 数学基础30讲:第一讲 高等数学预备知识
  5. 【FiddlerScript】利用FiddlerScript抓包保利威下载
  6. 通俗易懂讲解什么是Java分布式
  7. javacv截取视频截图-1.5.7版本精简包
  8. 改手机为自动开机的车载导航仪
  9. 《App后台开发运维和架构实践》推荐序
  10. SCT9320STDR,3.8V-32V输入,2A,低EMI,超低功耗同步降压DCDC转换器