使用JavaScript函数构建3D模型

本文讨论了WebGeometry函数的几何库在构造复杂多面体模型中的使用。 该库是用Javascript编写的。 带有示例的GitHub链接 ,提供了使用库的简单示例。 欢迎发表评论和批评。



ThreeJS库用于显示使用WebGeometry库中的函数预先计算的模型。 HTML5画布用于显示单个平面模型元素并显示支持信息。

在Internet上使用WebGL技术和基于它创建的WebGL技术和库(例如ThreeJS和BadylonJS)来实现与3D图形有关的各种目的。 但是基本上,它们用于在浏览器中显示现成的三维模型(例如以前在3ds MaxBlender程序中创建的模型)。 如果我们面临创建参数模型的任务,也就是说,在浏览器中显示完成的对象的过程中,我们可以通过设置适当的模型参数(例如,增加特定面的角度)来更改其单个元素的模型,一组几何函数,使您可以创建模型,以便将来可以交互改变模型中各个元素或整个模型的形状。 为了解决这个问题,我们需要使用Javascript语言的一组函数,这些函数将实现解析几何中使用的方法。 该库必须具有创建线,平面和圆,找到其交点的点(或线),创建倾斜平面等功能。 ThreeJS和BadylonJS库具有其中一些功能,但是使用它们执行的动作数量不允许您完成构造参数模型时出现的所有任务。 还有更多的纯数学Javascript库。 其中, glMatrixSylvester使用最广泛。 glMatrix库主要用于处理矢量,矩阵和四元数,但是其中没有用于处理线和平面的函数。 Sylvester库具有这些功能,但是数量很少。 但是,有几本书描述了C / C ++中解析几何方法的实现。 相应的C / C ++程序可用作在Javascript中创建数学库的原型。 因此,当我决定创建钻石切割的三维参数模型以在浏览器中显示它们时,我选择ThreeJS库仅用于显示已经计算出的模型-它不用于计算模型的形状。 为了计算表单本身,创建了WebGeometry库。 该库基于以前使用的C / C ++几何函数,我将其翻译为Java语言。 让我们考虑一下构建金字塔模型(金字塔形钻石切割)的各个阶段。

第一阶段,我们需要绘制模型的预期视图,然后编号其顶点。 下图显示了金字塔切割模型中包含的顶点编号和切割元素的名称。



之后,需要从编号的顶点形成面。 例如,对于站点的脸部和冠部的脸部,编写以下顶点序列(脸部的重复第一个顶点表示脸部已结束):

0, 3, 2, 1, 0; //  0 -  0, 4, 7, 3, 0, //  1 -  1, 5, 4, 0, 1, //  2 -  2, 6, 5, 1, 2, //  3 -  3, 7, 6, 2, 3, //  4 -  

面孔应逆时针旋转。 pyramid_index.js文件包含用于遍历金字塔所有面的源代码和详细注释。 爬网的结果将写入index_cut数组。

第二阶段,我们可以为模型的面孔着色。 如果我们不需要着色,则此步骤是可选的。 假设我们要为金字塔模型着色,如下所示:



为此,创建了facet_colors()函数所在的pyramid_colors.js文件,该文件将所有面孔的颜色写入colors数组。

第三阶段 ,在对所有顶点进行编号并记录面的所有顶点的遍历序列之后,有必要设置模型参数,然后计算其所有顶点的坐标。 当然,假定我们已经为自己概述了构造算法,并弄清楚了模型的所有面将如何定位在空间中。 对于金字塔,我们将选择以下参数,这些参数将确定其各个部分以及整个模型的大小:

 var DEGREE = 0.01745329251994; //      var lw = 1.2; //  /  var r = 0.06; //     var angleA = 50*DEGREE; //    A  var angleB = 60*DEGREE; //    B  var hCrown = 0.3; //   var anglePav = 60*DEGREE; //    A  

参数的选择由模型的开发者确定。 例如,您可以一次为两个角度指定一个参数,而不是为表冠的两个倾斜角度设置两个参数,然后这些角度将始终相同。 您可以输入确定站点大小的参数。 在这种情况下,要么不设定表冠高度,要么不设定其表面的倾斜度。 选择参数的另一种方法是使某些参数可计算。 在这种情况下,当更改某些参数时,某些其他参数可能会更改其初始值。 例如,假设我们为金字塔定义了一个用于设置冠状面的倾斜角度的参数,为冠的高度定义了另一个参数,并且另一个参数将设置区域的大小,那么在更改面的角度时,我们将被迫更改区域的大小或冠高。 另一方面,如果更改设置垫块大小的参数,则设置冠状面的高度或坡度的参数值将自动更改。 在该程序中以及在现场显示的其他切割模型的构造中,未使用与计算参数的应用相关的选项。

第四阶段 ,计算模型顶点的坐标。 计算的初始数据是模型参数的值以及我们如何想象其外观。 pyramid_verts.js文件包含模型的顶点计算功能的源文本(带有详细注释),称为VerticesCalculation。 通过此计算,将在此函数中使用WebGeometry库的函数。 将顶点坐标的计算结果输入到顶点数组中。 请注意,在用于查找顶点坐标的程序中,单独的数字序列用于构成电晕的顶点(四个顶点),构成腰带的顶点(四个顶点)和构成亭子的顶点(在金字塔模型中,亭子中仅包含顶点)。 程序员可以使用这种选择的附加顶点编号来简化切割顶点之间的方向,因为顶点的数量通常超过100。

第五阶段,在完成顶点坐标的计算之后,需要以编程方式构造模型的多面体(polyhedron)。 其构造的初始数据是先前创建的index_cut,颜色和顶点数组。 多面体模型可以简单地表示为在空间中约束多面体的一组面。 CreatePolyhedron函数位于polyhedron.js文件中。 通过该功能的工作,创建了一个三维模型组成的多边形数组。 每个多边形由以下函数描述(实际上,它是构造函数,由创建新多边形时的new运算符调用):

 function Polygon() { this.IndexFacet = []; //      //    this.IndexFacet_1 = []; //      //    this.VertexFacet; // ,    //    this.EdgeFacet = []; // ,  , //    (    //  ) this.IndexTriangle = []; // ,    // ,     this.VertexTriangle = []; // ,    //   ,     this.Faces = []; //      } 

由于WebGL和ThreeJS库是在其基础上创建的,可用于三角形图元,因此会对模型的每个面进行三角剖分。 假定模型的所有面均为凸多边形。 最终,CreatePolyhedron函数采取所有必要的步骤来创建数据结构,以完全描述多面体的所有面,从而可以将它们传递给ThreeJS库函数以在屏幕上显示模型。

第六阶段 ,使用ThreeJS函数将模型显示在屏幕上。 以标准方式创建场景,渲染器和相机。 为了从各个方面检查切割模型,Pyramid程序使用了orbitControls元素。 在创建其他切割模型时,为了从各个方面检查切割,我没有使用orbitControls,而是引入了旋转模型本身的功能。 然后我们创建模型网格。 您可以做两件事。

在第一种方法中,我们将切割模型视为一组单独的面网格。 在这种情况下,每个脸都是一个单独的3D对象。 使用此模型表示,使用名称为raycaster的Three.JS元素选择单个面部的过程非常简单。 同样,可以通过创建与每个面接壤的线段网格来补充此方法。

在第二种方法中,我们将切割模型视为单个对象,仅由一个立即包含模型所有面的​​网格表示。 使用着色器显示模型时,使用此方法很方便。 “金字塔”切割模型中未使用此方法,但可使用该方法来创建八边形,Brilliant和其他切割模型,这些模型可以在我的网站上看到。

第七阶段 ,将创建按钮和与其相连的功能,这些按钮和功能使您可以更改确定模型的形状和大小的参数的值。 当按下按钮时,将调用一个增加或减少相应参数值的功能。 这意味着有必要重新计算模型顶点的坐标值。 重新计数后,将检查新构建的模型的正确性。 例如,确定一些值是否超出公差。 对于菱形切割模型,通常可以归结为检查凸形切割在重建后是否仍然存在。 检查凸起如下。 通过每个面绘制一个平面,该面位于其中,然后确定模型每个顶点相对于该平面的位置。 所有顶点应位于该平面的同一侧。 如果认为模型不正确,则参数将返回其原始值,并再次重建模型。 对于具有非凸腰带的切割模型(仅某些切割的元素(例如“心”)可以是非凸的),分别对冠部和展馆分别检查凸度。 但是,将rundist从检查中排除。 对于简单模型,您可以将自己局限于简单的参数检查。 例如,如果我们正在构建房屋模型,则屋顶的高度不应超过特定高度。 因此,简单地设置此参数的大小限制,即可获得所需的结果。 添加参数按钮后,非常希望在单击按钮后以可视方式显示每个参数的值。 为此,将创建一个HTML5二维画布,并在相应按钮旁边显示参数值。

因此,我们使用金字塔示例检查了构建模型的所有阶段。 对于金字塔(以及网站上的所有其他模型),我创建了另一个程序Pyramid_text.html。 该程序的示例显示了如何显示三维文本以对模型的顶点编号。 如果有人想知道如何构建复杂的模型,则应考虑按以下顺序构建模型(请参阅GitHub)
八边形 。 一个模型,该模型演示了以各种方式创建平面以及如何使用这些平面。 在构建模型时,还使用在空间中处理向量和线时使用的方法。

辉煌的 。 这是经典且最常见的钻石切工。 将来在创建刻面MoonMarquise,MoonPear和Heart时会使用构建此切割的三维模型的一些元素。 在BrilliantGirdlt.html程序中分别显示了如何计算具有超级椭圆形式的切口的腰围。 在此程序中,腰围线建立在二维画布(画布)上。

MoonMarquise 。 侯爵夫人切割,像辉煌,是经典的钻石切割之一。 与这种简单的刻面(侯爵夫人)不同,在亭子的MoonMarquise刻面中添加了所谓的“月亮刻面”。 MoonMarquise刀具由两个椭圆弧组成。 MarquiseGirdle.html程序中显示了此腰带在画布上的详细构造。 该程序的文本对结构有详细的注释。 我们注意到关于腰围线计算的一点-它使用了与椭圆相切的属性。 例如,在“分析几何课程”一书中对此进行了考虑(本书的作者是N.I. Muskhelishvili)。
月亮梨 MoonPear切石斑鱼由三个椭圆的弧形组成。 它的构造基于侯爵夫人切割腰带的构造,但更为复杂。 要查看侯爵夫人的腰封线以及如何将Gundist分割成段,请运行PearGirdle.html程序。

“心”形切口是经典切口之一,但与大多数类型的切口相比,它具有非凸状腰带形状。 切心脏的督导者由两个彼此相对倾斜的梨切割腰带组成。 在画布上,您可以通过运行HeartGirdle.html程序来查看腰围线。 建立心切是一个很大的挑战。

马耳他十字 。 切成的“马耳他十字”的刀具以“枕头”(靠垫)的形式制成。 具有这样的束腰的切割最近已变得广泛。 该腰带的线是八个共轭圆弧-四个侧面与枕头相邻的四个主弧线,四个较小尺寸的弧线在枕头的四个角处与枕头的主弧线成对。 通过运行程序CushionGirdle_1.html和CushionGirdle_2.html,您可以看到腰带的线的形状,设置其形状的所有参数的工作以及腰带的分割。

五角星 。 五角星形切刀由带有上胚轴名称的线形成。 上摆线是与摆线相关的曲线。 在Wavy_Pentagon_Girdle.html程序中,通过更改参数的值,您可以更改腰带的“波纹度”,甚至可以将五边形更改为具有不同数量的突起(“花瓣”)的多边形。 但是,应该记住,此切割本身的模型是为“花瓣数”参数的值等于5而构建的。

如前所述,对于所有上述模型,将创建显示切割顶点数量的程序。 在这些程序中,将在模型的所有顶点的直通显示与分别显示冠,腰带和亭子的顶点编号之间进行切换。 假设在马耳他切割模型中,您想创建一个穿过具有数字84、88和145的顶点的平面。当使用CreatePlaneThreePoints函数创建平面时,与其使用这些数字来标识平面所经过的点,而是使用单独的记录腰带和凉亭的峰编号:

 var plane = new Plane3D(); plane.CreatePlaneThreePoints(girdle[68], girdle[72], crown[1]); 

应该注意的是,显示模型顶点编号的程序运行非常缓慢(至少在我的计算机上)。 完成模型顶点编号的输出可能需要几秒钟。

综上所述,我认为,选择多面体(切割模型)来演示几何函数的操作是最好的选择之一。 检查了以上示例的工作之后,我们可以继续进行与钻石切割建模完全不同的活动领域相关的几何对象的创建。

Source: https://habr.com/ru/post/zh-CN418045/


All Articles