TWaver3D直线、曲线、曲面的绘制

插播一则广告(长期有效)

TWaver需要在武汉JavaScript工程师若干 
要求:对前端技术(JavasScript、HTML、CSS),对可视化技术(Canvas、WebGL)有浓厚的兴趣 
基础不好的可培养,基础好的可共谋大事 
感兴趣的给我发邮件:[email protected]

————————————————————正文的分割线—————————————————————-

今天来说关于绘图的那些事儿。

先说说绘图引擎的种类。目前市面上绘图引擎大致可以分为两类。一类基于HTML技术,比如TWaver2D/3D引擎。HTML5是业界公认的Web标准和最热门和主流的技术,可以在浏览器中直接创建2D、3D场景,无需安装任何插件,几乎已经应用到所有行业的Web应用中。目前所有的主流浏览器都很好的支持html5技术,包括手机、平板等移动端浏览器的支持。 

还有一种是Unity公司的Unity3D引擎。unity3d需要在浏览器中安装专门的播放器插件才能运行,有点类似正在垂死挣扎的Flash技术。另外,Unity3D主要支持桌面浏览器,并不支持移动端的浏览器插件。由于安装插件不便利,并且有一定的安全隐患,所以Unity3D在企业应用中并不常见,反倒在游戏行业中能够很好地一展身手。 



下面就分享一下如何用 TWaver3D引擎绘图吧。

1. WebGL原生线

WebGL支持绘制点、线、三角;绘制线的方法比较简单,给定顶点,设置绘制方式即可;

假设给定顶点信息为:

var vertices = new Float32Array([
0.0, 0.5, -0.5, -0.5, 0.25, -0.5
]);

  

调用gl.drawArrays(gl.LINE_STRIP, 0, 3);后效果如下:

Chrome: 

Safari: 

另外还有个兼容性问题,在Windows上,绘制线的时候无法指定线宽。OpenGL本身有glLineWidth这个方法,而且在WebGL中也有这个方法。但是在Windows虽然调用不会失败,但是也不会生效,无论是在Chrome还是在FireFox上测试都无效。但是Linux上有效,应该是操作系统的限制问题。这个问题之前就有人提出过,如果有兴趣可以看看https://bugs.chromium.org/p/chromium/issues/detail?id=60124。也许在以后的WebGL版本中会修复这个问题吧。测试网站http://alteredqualia.com/tmp/webgl-linewidth-test/。 
设置lineWidth为10后,Chrome效果不变,Safari线条加粗了. 

测试网站测试:

Chrome不正常 

Safari正常 

FireFox正常: 

是Chrome长期存在的一个Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=60124

 
可以参考WebGL大咖彪叔的文章:WebGL 绘制Line的bug

2. mono.Line类

构造函数: 

实线:

var line = new mono.Line({
vertices:[
new mono.Vec3( -100, 0, 0 ),
new mono.Vec3( 100, 100, 0 ),
],
type:‘mono.LinePieces‘,
styles:{
‘m.color‘:‘red‘,
},
});
box.add(line);

  

虚线: 
原来的参数是通过segments来计算出更多的顶点信息;其实可以通过配置line的style属性,如line.pattern = [10,2]来计算出顶点信息; 
封装了mono.Line.createDottedLine方法,用于根据pattern创建虚线;

var line = new mono.Line({
type:TGL.LinePieces,
styles:{
‘m.color‘:‘green‘,
‘m.type‘: ‘phong‘,
‘m.ambient‘: ‘red‘,
}
});
line = mono.Line.createDottedLine(line,[
new mono.Vec3( -200, 100, -100 ),
new mono.Vec3( 160, 100, 0 ),
new mono.Vec3( 300, -100, 100 ),
new mono.Vec3( -300, -100, 200 ),
new mono.Vec3( -200, 100, 0 ),
new mono.Vec3( -200, 100, -100 ),
],[6,12]);

  

改变pattern后的效果:实线长一点,虚线短些; 

创建矩形:

mono.Line.createRectangle = function(width, height, segments) {
// width:宽度, height:高度, segments:分片数
var line = mono.Line.createRectangle(200,200,10);
line.setType(TGL.LineStrip);
line.setPositionY(-30);
line.setPositionX(20);
line.setStyle(‘m.color‘,‘red‘);
box.add(line);

 

创建椭圆,并分段设置颜色

var line = mono.Line.createEllipse(120,80,100,Math.PI * 2,0,true);
line.setPositionY(0);
line.setPositionX(0);
line.setMaterialStyle(‘vertexColors‘,true);
line.setMaterialStyle(‘linewidth‘,10);
line.setMaterialStyle(‘linejoin‘,‘miter‘);
line.setType(TGL.LinePieces);
var vertices = line.getVertices();
var colors = [], color;
for(var i = 0;i<vertices.length;i++){
var vertex = vertices[i];
if(vertex.x > 0 && vertex.y > 0){
color = new mono.Color(‘red‘);
}else if(vertex.x > 0 && vertex.y < 0){
color = new mono.Color(‘green‘);
}else if(vertex.x < 0 && vertex.y < 0){
color = new mono.Color(‘orange‘);
}else{
color = new mono.Color(‘yellow‘);
}
colors.push(color);
}
line.setColors(colors);
box.add(line);

  

//创建Helix螺旋状线条
//mono.Line.createHelix = function(line,startRadius, endRadius, height, turns, segments)
// startRadius:起始半径, endRadius:结束半径, height:高度, turns:转数, segments:分片数
var line = mono.Line.createHelix(-100,250,200,10,400);
line.setPositionY(30);
line.setPositionX(20);
line.setMaterialStyle(‘linewidth‘,10);
line.setStyle(‘m.color‘,‘red‘);
box.add(line);
//创建Ellipse椭圆线条
// mono.Line.createEllipse(xRadius, yRadius, segments, aStartAngle, aEndAngle, aClockwise)
// xRadius,yRadius:椭圆的半径,segments:分片数量,aStartAngle:起始角度,aEndAngle:结束角度,aClockwise:是否逆时针
var line = mono.Line.createEllipse(120,80,100,0,Math.PI/2,true); //
line.setType(TGL.LinePieces);
line.setPositionY(30);
line.setPositionX(20);
line.setStyle(‘m.color‘,‘red‘);
line.setMaterialStyle(‘linewidth‘,10);
box.add(line);

  

3. mono.LineX类

正如上文所说,Chrome不支持设置线宽,只能自己模拟;于是创建了mono.LineX; 
如图,蓝色的为LineX效果。可用于绘制管线等效果;

var lineX = new mono.LineX([
{x:-180, y:100,z: -100},
{x:120, y:100, z:0},
{x:280, y:-100, z:100},
{x:-280, y:-100, z:200},
{x:-180, y:100, z:0},
{x:-180, y:100, z:-100},
], [‘red‘, ‘red‘, ‘red‘, ‘red‘], 10);
lineX.setStyle(‘m.color‘,‘blue‘);

  

4. mono.PathNode、mono.PathLine、mono.PathCube

路径体(mono.PathNode)这是一种复杂的形状体,由两个任意形状进行控制:切面形状,以及前进走向。最终形状是该切面形状沿着前进走向进行移动而形成的物体。例如,一个圆形切面沿着一个多边形移动,就会形成一个复杂的管线物体。这种形状还可以控制两个端头是否封闭、封闭的形状和尺寸,横切方向是否闭合、闭合角度、闭合样式等。通过控制这些参数,可以创建例如管线、弯管、香肠体、切开的管线等。

 
详细参考TWaver官方文档,本文不再累述。

http://doc.servasoft.com/twaver-document-center/recommended/twaver-html5-3d-v2/using-elements/elements/#monoPathNode

5. mono.NurbsCurve类

权威书籍:《非均匀有理B样条(第2版)》 
非均匀有理B样条,通常简称为NURBS(Non-Uniform Rational B-Splines),实际上已经成为利用计算机处理集合信息时用于形状的表示、设计和数据交换的工业标准。许多国内和国际标准,如IGES,STEP和PHIGS都把NURBS作为集合设计的一个强有力的工具。NURBS取得的巨大成功主要由于以下事实1: 
NURBS为解析曲线曲面(如圆锥截线和二次曲面)和自由型曲线曲面(如汽车车身和船体外形)的表示提供一种统一的数学方法; 
利用NURBS进行设计非常直观,几乎每个工具和算法都有一个易于理解的几何解释; 
NURBS的算法执行速度很快,并且数值稳定; 
NURBS曲线曲面在通常的几何变换(如平移、旋转、平行和透视投影)下是不变的; 
NURBS是非有理B样条、有理以及非有理Bezier曲线曲面的推广;

对于大部分人来说,B样条、有理B样条和NURBS有点神秘,有人成NURBS为无人能理解的有理B样条曲线(NoBody Understand Relation B-Splines); 
研究NURBS的当前首要目的在于呈现三维数据场的可视化,可参考书籍《三维数据场可视化》2
NURBS曲线,貌似比较神秘,其实也非常的容易理解;制作模型的曲线一定要逼真,曲线越逼真,模型就会越真实。而一般的直线,曲线是很难达到这样效果的,所以引入了NURBS曲线。

/**
* {[TGL.Line]} line
* {[Array of vector(3|4)]]} ctrlPoints 曲线的控制点
* {[Number]} degree 曲线的最高指数
* {[Number]} count 曲线每段需要插入点的个数
* {[Object]} ctrlCond 线条控制条件
*/
TGL.Line.createNurbs = function(line, ctrlPoints, degree, count, ctrlCond){}
随机单色波浪线:
var points = [0,-200,500,0,1000,-400,-10,500,-1000,0,0,100,-100,0,0,0,0,0];
var ctrlPoints = [];
for ( var i = 0, j = 10; i < j; i ++ ) {
ctrlPoints.push(
new TGL.Vec3(
-500 + 100 * i ,
points[i],
0));
}
var line = mono.Line.createNurbs(ctrlPoints,3, 50, {
});
line.s({
‘m.type‘: ‘phong‘,
‘m.color‘:‘green‘
});
line.setMaterialStyle(‘linewidth‘,10);
line.setType(TGL.LineStrip);
box.add(line);

  

在实际应用中,我们会根据曲线的高度值,设置不同的颜色,来模拟温度场之类的效果。

var line = mono.Line.createNurbs(ctrlPoints,3, 50, {
skyY : 100,
skyColor : new mono.Color(‘red‘),
horizonY: 0,
horizonColor: new mono.Color(‘yellow‘),
earthY : -100,
earthColor: new mono.Color(‘green‘),
});

  

再制作一个弹簧效果 

这只是用一些数学公式模拟出来的效果,如若使用比较真实的数据,看看效果如何: 

大黄兔正脸照 

侧脸照 

一句话,逼真!

5. mono.NurbsSurface

/**
* NurbsSurface 非均匀有理样条B样条曲面
* NURBS是非有理B样条、有理以及非有理Bezier曲线曲面的推广
* @class mono.NurbsSurface
* @constructor
* @extends mono.Curve
* @param {Number} [degreeU] U方向阶数 <= U点数 - 1
* @param {Number} [degreeV] V方向阶数 <= V点数 - 1
* @param {Number} [ctrlPoints] 曲面的控制点
* @return {mono.NurbsSurface} NurbsSurface对象
* @example
*
*/

  

var ctlPoints = [
[
new mono.Vec4(-200, 0, -200, 1 ),
new mono.Vec4(-200, 100, -100, 1 ),
new mono.Vec4(-200, -100, 100, 1 ),
new mono.Vec4(-200, 0, 200, 1 ),
new mono.Vec4(-200, 100, 200, 1 ),
new mono.Vec4(-200, 0, 300, 1 ),
],
[
new mono.Vec4(0, 0, -200, 1 ),
new mono.Vec4(0, 100, -100, 1 ),
new mono.Vec4(0, -100, 100, 1 ),
new mono.Vec4(0, 0, 200, 1 ),
new mono.Vec4(0, 100, 200, 1 ),
new mono.Vec4(0, 0, 300, 1 ),
],
];
var degreeU = 0;// 阶数 <= 点数 - 1 = 3 -1
var degreeV = 3;//阶数 <= 点数 - 1 = 6 - 1
var nurbsSurface = new mono.NurbsSurface(degreeU, degreeV, ctlPoints);
var surface = window.surface = new mono.Surface(nurbsSurface, 3,150,{
skyY : 100,
horizonY: 0,
earthY : -100,
skyColor : new mono.Color(‘red‘),
horizonColor: new mono.Color(‘gray‘),
earthColor: new mono.Color(‘green‘),
});
surface.s(
{
‘m.type‘: ‘basic‘,
‘m.color‘: ‘white‘,
‘m.side‘:mono.DoubleSide,
‘m.ambient‘: ‘white‘,
// ‘m.texture.image‘:‘./images/collage.jpg‘,
// ‘m.wireframe‘:true,
‘m.wireframeLinewidth‘: 1,
‘m.wireframeLinecolor‘: ‘orange‘,
‘m.wireframeLineopacity‘: 1,
});
surface.setSelectable(false);
box.add(surface);

  

将一幅2D温度云图转换为3D效果: 

结合数学知识,可以展现各种各样的效果: 
番茄天空盒(内嵌温度场) 

图像RGB展示 

引力场 

关于绘图就说到这,TWaver的3D引擎还是挺强大的,个人觉得呈现效果也比较美丽。到目前为止,我遇到的大大小小上百个case,都能用它得到解决。

有兴趣的可以戳网址http://servasoft.com/download.html下载TWaver3D引擎开发包,自己上手玩一把。

6.参考链接:

1.http://codeazur.com.br/experiments/webgl_curve_1/ 
2.https://mattdesl.svbtle.com/drawing-lines-is-hard 
[3].https://www.khronos.org/webgl/wiki/Demo_Repository 
[4].http://nurbscalculator.in/ 
[5].http://omni360.github.io/webcad/Org/three.js-master/examples/webgl_geometry_ctrnurbs2d.html 
[6].https://www.ibiblio.org/e-notes/Splines/Intro.htm 
[7].https://www.ibiblio.org/e-notes/webgl/models.htm#spline

时间: 2024-08-04 06:54:37

TWaver3D直线、曲线、曲面的绘制的相关文章

7.5.5编程实例-Bezier曲线曲面绘制

(a)Bezier曲线                         (b) Bezier曲面 1. 绘制Bezier曲线 #include <GL/glut.h> GLfloat ctrlpoints[4][3] = {{ -4.0, -4.0, 0.0}, { -2.0, 3.0, 0.0}, {2.0, 4.5, 0.0}, {3.0, -3.0, 0.0}}; void init(void) { glClearColor(1.0, 1.0, 1.0, 0.0); glShadeMod

曲线曲面积分的关系

一.背景 这个周末一直在鼓捣曲线曲面积分的一些题目,个人其实感觉这应该是高等数学中对科研最有用的内容了.学院在安排专业培养的时候给我们17级没有设置大学物理,后面18级恰巧赶上工程认证,安排上了大学物理,当时觉得我们真庆幸,现在来看我要是有点大学物理的知识,对理解曲线曲面积分应该会有很大的帮助.我在理解这些积分是总喜欢从物理意义出发,在B站看了一些科普视频,仍有一些半知不解,在这里先简单介绍一下我的一些认识. 二.曲线曲面积分的关系 在知乎看到这样一张图 https://www.zhihu.co

用OpenGL进行曲线、曲面的绘制

实验目的 1)理解Bezier曲线.曲面绘制的基本原理:理解OpenGL中一维.二维插值求值器的用法. 2)掌握OpenGL中曲线.曲面绘图的方法,对比不同参数下的绘图效果差异: 代码1:用四个控制点绘制一条三次Bezier曲线 #include "stdafx.h" #include <stdlib.h> #include <time.h> #include <GL/glut.h> //4个控制点的3D坐标--z坐标全为0 GLfloat ctrl

matlab曲线、图形绘制方法(不断更新)

转载自http://blog.sina.com.cn/s/blog_60ec9dcb0100x4qq.html hold on 是当前轴及图形保持而不被刷新,准备接受此后将绘制 hold off 使当前轴及图形不在具备被刷新的性质 hold on 和hold off,是相对使用的前者的意思是,你在当前图的轴(坐标系)中画了一幅图,再画另一幅图时,原来的图还在,与新图共存,都看得到后者表达的是,你在当前图的轴(坐标系)中画了一幅图,此时,状态是hold off,则再画另一幅图时,原来的图就看不到了

将caffe训练时loss的变化曲线用matlab绘制出来

1. 首先是提取 训练日志文件; 2. 然后是matlab代码: clear all; close all; clc; log_file = '/home/wangxiao/Downloads/43_attribute_baseline.log'; fid = fopen(log_file, 'r'); fid_accuracy = fopen('/home/wangxiao/Downloads/output_accuracy.txt', 'w'); fid_loss = fopen('/hom

canvas绘制贝塞尔曲线

原文:canvas绘制贝塞尔曲线 1.绘制二次方贝塞尔曲线 quadraticCurveTo(cp1x,cp1y,x,y); 其中参数cp1x和cp1y是控制点的坐标,x和y是终点坐标 数学公式表示如下: 二次方贝兹曲线的路径由给定点P0.P1.P2的函数B(t)追踪: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <

canvas教程(三) 绘制曲线

经过 canvas 教程(二) 绘制直线 我们知道了 canvas 的直线是怎么绘制的 而本次是给大家带来曲线相关的绘制 绘制圆形 在 canvas 中我们可以使用 arc 方法画一个圆 context.beginPath(); context.arc(x, y, r, startRadian, endRadian, antclockwise); context.closePath(); 我们是第一次用到 beginPath 和 closePath 这两个方法,首先这两个方法故名思意就是开始路径

C#WPF 如何绘制几何图形 图示教程 绘制sin曲线 正弦 绘制2D坐标系 有图有代码

C#WPF 如何绘制几何图形? 怎么绘制坐标系? 这离不开Path(System.Windows.Shapes)和StreamGeometry(System.Windows.Media)类. 一.建立WPF工程 二.添加代码 MainWindow.xaml 中代码 <Window x:Class="WPFDrawingTraning.MainWindow"         xmlns="<a target=_blank href="http://sche

计算机图形学--曲线及曲面基本定义

曲线曲面基础: 位置矢量: 切矢量: 曲率: 法矢量: 挠率 插值 拟合: 光顺: 原文地址:https://www.cnblogs.com/yangf428/p/9969788.html