杂记

三维橱柜——厨房户型生成开发方案

chenmo · 3月3日 · 2022年 · 36次已读
三维橱柜——厨房户型生成开发方案

三维橱柜——厨房户型生成开发方案

1.需求背景

需求:span>STORY #8470 厨房户型模型建立

设计稿:暂无

需求要点:

  1. 生成 初始户型预览图
  2. 墙面后有按钮控制墙面是否 显示,有按钮控制是否 增加 新墙面,有按钮控制是否 删除 该墙面;
  3. 输入 墙面角度墙面长度 后,预览页方可生成新墙面;
  4. 墙面数大于1时,最后一个墙面的终点与起始点之间会生成 自动闭合虚线
  5. 墙面的角度和长度均合法时,有 墙面编号 一一对应;
  6. 墙面的角度合法,但长度为空时,显示按合法角度的闪烁的 引导箭头
  7. 墙面角度或长度输入框获取焦点时,对应预览墙面变为 选中状态
  8. 点击完成按钮后,最后的封闭线段由 虚线变为实线,表示该户型已经绘制完毕;
  9. 户型绘制完成后,生成三维墙面前,可重新点击墙面参数输入框直接 再次编辑
  10. 户型绘制完成后,点击生成三维模型,可自动生成并显示 三维模型
  11. 输入三边可求任意角度的组件。

2.实现分析

2.1 初始户型预览图及墙面参数控制

需求分析

生成初始户型预览图

image2022-2-25_15-17-53

a. 左侧参数区预设有3面墙面,且已有角度与长度值;

b. 右侧预览图根据左侧数据实时预览结果;

c. 点击眼睛按钮可以隐藏墙面,点击加号可在该墙面后新增墙面,点击减号可删除该墙面;

实现分析

  • 页面组件实现

    • 左侧墙面参数配置部分,可使用Element-UI表单组件;

    • 右侧预览效果可使用 Fabric.js 进行实时预览

      • 墙面可使用 Fabric.Line 实现;
      • 序号可以使用 Fabric.Text 实现;
      • 箭头可以使用 Fabric.Path + Animation 实现;
  • 左侧参数区 数据结构

  • 生成右侧预览图所需数据的 数据结构

⭐️ 注意:基于Canvas的Fabric.js绘制时的坐标系(左)与用户主观认知的坐标系(右)存在区别,因此在绘制之前,可以统一使用用户主观认知的坐标系坐标(右),在准备绘制时,需要将坐标转换为Canvas的坐标(左)。

image2022-2-25_15-25-50

2.2 角度指引箭头

需求分析

在用户添加墙面后,光标聚焦在一组没有绘制完毕的数据时,可能会不清楚当前设置的角度是哪个角度。因此需要在预览区域添加一个角度指引箭头,用来告知用户当前设置的角度是哪个角度(如图中绿色箭头)。

image2022-3-2_17-51-43

实现分析

可以使用Fabric.js添加图片或使用Fabric.Path进行绘制。

  • 默认箭头角度为 垂直于最后墙面(即90度);
  • 默认箭头长度为 20px;
  • 在预览数据(canvasWallList)中使用 isShowArrow 控制是否显示箭头。

2.3 自动闭合虚线

需求分析

在墙面数量大于1时,期望最后一个墙面的顶点与初始点有一条自动闭合的虚线。

实现分析

可以 监控左侧墙面数据的数量,当其大于1时,自动连接最后一个墙面的结束点与初始起点,且用淡灰色虚线表示。

即当 canvasWallList长度大于1时,将canvasWallList最后一个点的终点与第一个点的起点连接起来。

2.4 墙面选中状态

需求分析

当用户编辑墙面参数时,为方便用户快速知道当前编辑的墙面是哪一个,右侧预览图,采用墙面高亮的形式进行提醒。

实现分析

右侧预览图在生成墙面时,将生成的墙面数据全部保存在数组里。当左侧参数输入框获取焦点时,可根据下标获取对应预览框中的墙面,先清空现有激活的墙面,随后将该墙面改为激活状态,再渲染预览图进行更新。

2.5 2D转3D

需求分析

根据用户绘制的平面房型图,待用户点击【3D化】按钮,输入厨房高度后,需要生成对应的三维模型图,且三维坐标原点应当在三维模型房间下地面中心。

实现分析

  • 根据二维用户对墙面的操作,记录厨房户型墙面的数量、每个墙面的尺寸与角度,计算每个墙面在三维的坐标尺寸角度

    坐标:二维数据(canvasWallList)最终保存的为用户主观坐标系坐标,且已知三维房型高度(用户输入),坐标转换关系如下:

    • X: | 墙面起点的x坐标 – 墙面终点的x坐标 | / 2 – 户型最大宽度 / 2
    • Y: 厨房高度 / 2
    • Z: | 墙面起点的y坐标 – 墙面终点的y坐标 | / 2 – 户型最大深度 / 2

    尺寸:

    • height: 房间高度
    • width: 墙面长度

    旋转:

  • 将墙面结果转换成json配置文件

  • Babylon.js中使用plane根据配置文件创建对应的墙面;

  • Plane有sideOrientation属性可以用来控制墙面是否透明,Demo:Plane Examples

交互设计

  • 当用户设置完2D户型的相关参数时,点击完成按钮,页面出现【3D化】按钮。待用户点击后,页面弹出加载框,页面根据 Json配置文件 进行渲染对应的三维模型。

 

3.方案设计

下载

4.方案对比

4.1 已知起点与旋转角度,求终点坐标方案对比

描述:

image2022-3-2_15-35-40

a. 使用平面旋转

image2022-3-2_15-39-9

思路:

延长OA到B’点,使 AB’ = AB。

  • 已知OA,AB,角a,可求A坐标,B’坐标;

  • 根据A坐标与角b,可通过平面中,一个点绕任意点旋转a度后的点的坐标来求出B坐标

    平面中,一个点(x,y)绕任意点(dx, dy)顺时针旋转a度后的坐标

    • x= (x – dx)cos(-a) – (y – dy)sin(-a) + dx ;
    • y= (x – dx)sin(-a) + (y – dy)cos(-a) +dy ;

    平面中,一个点(x,y)绕任意点(dx,dy)逆时针旋转a度后的坐标

    • x= (x – dx)cos(a) – (y – dy)sin(a) + dx ;
    • y= (x – dx)sin(a) + (y – dy)cos(a) +dy ;

b. 使用向量求解

image2022-3-2_15-55-45

思路:

本质:OB = OA + AB(粗体代表向量)

先在A点建立平面直角坐标系。

  • OA向量用A点坐标(xA, yA)=> (OA * cos a, OA * sin a) 表示;OB向量可以用B点坐标(xB,yB)表示;

  • 在A点的平面直角坐标系中,AB向量可以用B点坐标表示。

  • OB = OA + AB

  • AB 可以看作B点在以A点为坐标系时B的坐标,即(AB * cos c, AB * sin c)

  • c = a + b – 180

  • 所以 OB = OA + AB =(OA * cos a, OA * sin a) +(AB * cos c, AB * sin c)=> (OA * cos a + AB * cos c, OA * sin a + AB * sin c) => (OAcos a + AB cos(a+b-180), OAsin a + AB sin(a+b-180))

  • 即B点坐标:

    • X: OAcos a + AB cos(a+b-180)
    • Y: OAsin a + AB sin(a+b-180)
  • 总结规律:

    X: OA * cos (a + 0180) + AB cos (a+b – 1*180) + BC * cos (a+b+c – 2*180) + CD * cos (a+b+c +d – 3*180)….

    Y: OA * sin (a + 0180) + AB sin (a+b – 1*180) + BC * sin (a+b+c – 2*180) + CD * sin (a+b+c +d – 3*180)….

方案对比

  • a方案:容易理解,所有的点坐标均可先依照第一组数据的角度进行旋转平移求出。但该方案为求出最终结果,中间求出太多无用的数据(以三个点为例);

    • 为求 C 点坐标,需要利用 C’ 的坐标在 B 点旋转 d – 180°的角度。但 C’ 点坐标未知;
  • 为求 C’ 点坐标,需要利用 C” 的坐标在 A 点旋转 180° – b 的角度,此时 C” 点坐标已知;

    可知,为求 C 点坐标,该方案需要求出无用的 C’,C” 坐标。当墙面增多的时候,无用的坐标也会越多,因此舍弃。

  • b方案:

    • 使用向量加法将墙面数据转换为向量,当计算新墙面数据时,需要累加之前的所有数据(例:OE = OA + AB + BC + CD + DE)。

    • 但由于之前所有数据均为有效数据(即OA为A点坐标,AB可转换为B点坐标,并未产生无用数据)

(star) 目前初步 选用b方案 进行开发。

4.2 三维生成墙面方案对比

a. 不规则多边形(Irregular Polygons) + 不规则多边形拉伸(Irregular Polygon Extrusion)

思路:

  • 先使用不规则多边形(Irregular Polygons),通过各个点组成shape绘制出平面户型;
  • 再利用ExtrudePolygon拉伸成三维模型。

Demo:Irregular Polygon Extrusion Examples

b. 规则立方体

思路:

  • 先用规则立方体Mesh按墙面尺寸生成墙面;
  • 调整坐标,旋转角度拼接各个墙面;
  • 利用布尔运算去除相邻墙面相交部分;
  • 利用墙面法向量与照相机的夹角判断是否隐藏墙面(给mesh添加透明材质可以隐藏mesh)。

c. 使用平面

思路:

  • 先获取墙面的尺寸,坐标,角度;
  • 用平面生成各个墙面;
  • 平面自带属性可自动隐藏。

Demo: Plane Examples

方案对比

  • a方案: 尽管a方案由平面直接拉伸成3D十分方便,但a方案由于是一个整体,在墙面透明部分处理起来较麻烦,舍弃;
  • b方案:墙面厚度可自调节;利用布尔运算与法向量可以处理墙面透明需求,但工作量较大;
  • c方案:墙面厚度不可调节;平面自有属性可自动根据照相机情况进行调节墙面透明度情况。

目前初步 选用c方案 进行开发。

5.注意事项

  • 左侧参数的编号:只有当角度值与长度值都合法的情况下才显示编号;
  • 自动闭合墙面的数据不可修改,用灰色提醒,且只有是否显示按钮,没有增加与删除按钮(或不可操作);
  • 光标聚焦在一组没有绘制完毕的数据时,显示箭头表明下一步绘制方向(默认90度),失焦后箭头隐藏;
  • 左侧参数输入框获取焦点后,右侧预览图对应线段变为选中状态,失焦后恢复默认状态;
0 条回应

🎉 总访问量:13186 今日访问量:348 您是今天第:348 个访问者🎉