直线、椭圆、圆弧、基类 Curve

优质
小牛编辑
176浏览
2023-12-01

本节课通过介绍直线、圆弧线,以及这些曲线的基类Curve

圆弧线ArcCurve

圆弧线ArcCurve的基类是椭圆弧线EllipseCurve,关于圆弧线的使用方法可以查看threejs文档中的椭圆弧线。

ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise )
参数含义
aX, aY圆弧圆心坐标
aRadius圆弧半径
aStartAngle, aEndAngle起始角度
aClockwise是否顺时针绘制,默认值为false
//参数:0, 0圆弧坐标原点x,y  100:圆弧半径    0, 2 * Math.PI:圆弧起始角度
var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);

曲线Curve方法.getPoints()

.getPoints()是基类Curve的方法,圆弧线ArcCurve的基类是椭圆弧线EllipseCurve,椭圆弧线的基类是曲线Curve,所以圆弧线具有Curve的方法.getPoints()

通过方法.getPoints()可以从圆弧线按照一定的细分精度返回沿着圆弧线分布的顶点坐标。细分数越高返回的顶点数量越多,自然轮廓越接近于圆形。方法.getPoints()的返回值是一个由二维向量Vector2或三维向量Vector3构成的数组,Vector2表示位于同一平面内的点,Vector3表示三维空间中一点。

var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);
//getPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组
var points = arc.getPoints(50);//分段数50,返回51个顶点

几何体方法.setFromPoints()

.setFromPoints()是几何体Geometry的方法,通过该方法可以把数组points中顶点数据提取出来赋值给几何体的顶点位置属性geometry.vertices,数组points的元素是二维向量Vector2或三维向量Vector3。

BufferGeometry和Geometry一样具有方法.setFromPoints(),不过区别是提取顶点数据后赋值给geometry.attributes.position属性。

// setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
console.log(geometry.vertices);
// 如果几何体是BufferGeometry,setFromPoints方法改变的是.attributes.position属性
// console.log(geometry.attributes.position);

绘制圆弧线案例

使用threejs的API圆弧线ArcCurve绘制一个圆弧轮廓。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
//参数:0, 0圆弧坐标原点x,y  100:圆弧半径    0, 2 * Math.PI:圆弧起始角度
var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);
//getPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组
var points = arc.getPoints(50);//分段数50,返回51个顶点
// setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
//材质对象
var material = new THREE.LineBasicMaterial({
  color: 0x000000
});
//线条模型对象
var line = new THREE.Line(geometry, material);
scene.add(line); //线条对象添加到场景中

和上面绘制圆弧线代码实现的功能相同,不过没有借助圆弧线THREE.ArcCurve,通过三角函数计算生成圆弧线上的顶点。设置这个案例的目的就是,你可以通过对比两个代码案例,明白Threejs一些曲线API本质上就是通过某种算法得到了沿着特定轨迹的顶点数据。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
var R = 100; //圆弧半径
var N = 50; //分段数量
// 批量生成圆弧上的顶点数据
for (var i = 0; i < N; i++) {
  var angle = 2 * Math.PI / N * i;
  var x = R * Math.sin(angle);
  var y = R * Math.cos(angle);
  geometry.vertices.push(new THREE.Vector3(x, y, 0));
}
// 插入最后一个点,line渲染模式下,产生闭合效果
// geometry.vertices.push(geometry.vertices[0])
//材质对象
var material = new THREE.LineBasicMaterial({
  color: 0x000000
});
//线条模型对象
var line = new THREE.Line(geometry, material);
scene.add(line); //线条对象添加到场景中

绘制直线效果

直接给几何体Geometry设置两个顶点数据。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
var p1 = new THREE.Vector3(50, 0, 0); //顶点1坐标
var p2 = new THREE.Vector3(0, 70, 0); //顶点2坐标
//顶点坐标添加到geometry对象
geometry.vertices.push(p1, p2);
var material = new THREE.LineBasicMaterial({
  color: 0xffff00,
});//材质对象
//线条模型对象
var line = new THREE.Line(geometry, material);
scene.add(line); //线条对象添加到场景中

通过LineCurve3绘制一条三维直线。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
var p1 = new THREE.Vector3(50, 0, 0); //顶点1坐标
var p2 = new THREE.Vector3(0, 70, 0); //顶点2坐标
// 三维直线LineCurve3
var LineCurve = new THREE.LineCurve3(p1, p2);
// 二维直线LineCurve
var LineCurve = new THREE.LineCurve(new THREE.Vector2(50, 0), new THREE.Vector2(0, 70));
var pointArr = LineCurve.getPoints(10);
geometry.setFromPoints(pointArr);

通过LineCurve绘制一条二维直线。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
var p1 = new THREE.Vector2(50, 0); //顶点1坐标
var p2 = new THREE.Vector2(0, 70); //顶点2坐标
// 二维直线LineCurve
var LineCurve = new THREE.LineCurve(p1, p2);
var pointArr = LineCurve.getPoints(10);
geometry.setFromPoints(pointArr);