15-画曲线

43 阅读5分钟

画曲线

  • 用到 划线的Api
  • 曲线 API 是一些计算曲线坐标的公式,从中取出一些点,用点模型或者线模型画出来

EllipseCurve 画椭圆曲线

  • 用来画规则曲线用的
  • new THREE.EllipseCurve(0, 0, 100, 50, 0, Math.PI / 2)
    • 椭圆中心是 0,0,长短半轴长分别是 100、50
    • 弧度 从0°画到90°
  • 例子1椭圆
  • line1.js
import * as THREE from "three";

const arc = new THREE.EllipseCurve(0, 0, 100, 50);
// getPoints 方法从中取出一些点的坐标,传入的是分段数,20 段就是 21 个点。
const pointsList = arc.getPoints(20);

// 21 个点的坐标设置为 BufferGeometry 的顶点,通过 setFromPoints 方法
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsList);

const material = new THREE.PointsMaterial({
  color: new THREE.Color("skyblue"),
  size: 10,
});

const points = new THREE.Points(geometry, material);

console.log(points);

export default points;

-main.js

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

import * as THREE from "three";
import mesh from "./line1";

const scene = new THREE.Scene();

scene.add(mesh);

const axesHelper = new THREE.AxesHelper(200);
scene.add(axesHelper);

const width = window.innerWidth;
const height = window.innerHeight;

const camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);
camera.position.set(0, 100, 200);
camera.lookAt(0, 0, 0);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);

function render() {
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

render();

document.body.append(renderer.domElement);

const controls = new OrbitControls(camera, renderer.domElement);
  • 效果图入校 image.png
  • 详解 image.png
  • 换线模型
    • line1.js
import * as THREE from "three";

const arc = new THREE.EllipseCurve(0, 0, 100, 50);
// getPoints 方法从中取出一些点的坐标,传入的是分段数,20 段就是 21 个点。
const pointsList = arc.getPoints(20);

// 21 个点的坐标设置为 BufferGeometry 的顶点,通过 setFromPoints 方法
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsList);

// 换成线模型
const material = new THREE.LineBasicMaterial({
  color: new THREE.Color("orange"),
});
const line = new THREE.Line(geometry, material);
console.log(line);

export default line;
  • 如下图: image.png

  • 会看到不是很圆润,是因为分段数不够的原因我给80的时候如下 image.png

  • 第三个第四个参数一样就是圆了

    • line1.js
import * as THREE from "three";

const arc = new THREE.EllipseCurve(0, 0, 100, 100);
// getPoints 方法从中取出一些点的坐标,传入的是分段数,20 段就是 21 个点。
const pointsList = arc.getPoints(80);

// 21 个点的坐标设置为 BufferGeometry 的顶点,通过 setFromPoints 方法
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsList);
// 换成线模型
const material = new THREE.LineBasicMaterial({
  color: new THREE.Color("orange"),
});
const line = new THREE.Line(geometry, material);

export default line;
  • 如下图: image.png
  • 添加弧度
    • line1.js
// 修改这一行
const arc = new THREE.EllipseCurve(0, 0, 100, 100, 0, Math.PI / 2);

image.png

SplineCurve

  • 这个是用来画不规则曲线用的
  • new THREE.SplineCurve(arr)
    • arr: 坐标集合
  • line2.js
import * as THREE from "three";

// 坐标点集合
const arr = [
  new THREE.Vector2(-100, 0),
  new THREE.Vector2(-50, 50),
  new THREE.Vector2(0, 0),
  new THREE.Vector2(50, -50),
  new THREE.Vector2(100, 0),
];

const curve = new THREE.SplineCurve(arr);//画曲线
const pointsArr = curve.getPoints(20);//分断

const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);

const material = new THREE.LineBasicMaterial({
  color: new THREE.Color("skyblue"),
});
const line = new THREE.Line(geometry, material);

export default line;
  • 效果如下: image.png
  • 点线连珠的效果:
    • line2.js
//增加
const pointsMaterial = new THREE.PointsMaterial({
    color: new THREE.Color('yellow'),
    size: 5
});
const points = new THREE.Points(geometry, pointsMaterial);
line.add(points);//添加到线里面去
  • 效果图如下: image.png
  • 根据自己的要求加点坐标
    • line2.js
// 点集合
const arr = [
  new THREE.Vector2(-100, 0),
  new THREE.Vector2(-50, 50),
  new THREE.Vector2(0, 0),
  new THREE.Vector2(50, -50),
  new THREE.Vector2(70, 50),
  new THREE.Vector2(90, 10),
  new THREE.Vector2(100, 0),
];

image.png

  • 把点直线连接
import * as THREE from "three";

const arr = [
  new THREE.Vector2(-100, 0),
  new THREE.Vector2(-50, 50),
  new THREE.Vector2(0, 0),
  new THREE.Vector2(50, -50),
  new THREE.Vector2(70, 50),
  new THREE.Vector2(90, 10),
  new THREE.Vector2(100, 0),
];

const curve = new THREE.SplineCurve(arr);
const pointsArr = curve.getPoints(20);

const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);

const material = new THREE.LineBasicMaterial({
  color: new THREE.Color("orange"),
});

const line = new THREE.Line(geometry, material);

const pointsMaterial = new THREE.PointsMaterial({
  color: new THREE.Color("yellow"),
  size: 5,
});
const points = new THREE.Points(geometry, pointsMaterial);
line.add(points); //添加到线里面去

// 把点用直线连接
const geometry2 = new THREE.BufferGeometry();
geometry2.setFromPoints(arr);
const material2 = new THREE.PointsMaterial({
  color: new THREE.Color("green"),
  size: 10,
});
const points2 = new THREE.Points(geometry2, material2);
const line2 = new THREE.Line(geometry2, new THREE.LineBasicMaterial()); //直线连接
line.add(points2, line2);

export default line;
  • 效果如下:(有没有那味了嘻嘻) image.png

QuadraticBezierCurve

贝塞尔曲线: 控制曲率,达到自己想要的效果

  • 就是3个点为基础,第二点作为控制点
    • 三个点形成的角度越小,曲率越大
import * as THREE from "three";

const p1 = new THREE.Vector2(0, 0);
const p2 = new THREE.Vector2(50, 100);
const p3 = new THREE.Vector2(100, 0);

// 画曲线
const curve = new THREE.QuadraticBezierCurve(p1, p2, p3);
const pointsArr = curve.getPoints(20);

const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);
const material = new THREE.LineBasicMaterial({
  color: new THREE.Color("orange"),
});
const line = new THREE.Line(geometry, material);

// 直线连接点
const geometry2 = new THREE.BufferGeometry();
geometry2.setFromPoints([p1, p2, p3]);
const material2 = new THREE.PointsMaterial({
  color: new THREE.Color("pink"),
  size: 5,
});
const points2 = new THREE.Points(geometry2, material2);
const line2 = new THREE.Line(geometry2, new THREE.LineBasicMaterial());
line.add(points2, line2);

export default line;
  • 效果图如下: image.png

CubicBezierCurve3

三次贝塞尔曲线: 在三维上的贝塞尔曲线,上面的是二维的

  • line4.js
import * as THREE from "three";

// 这里的是三维坐标点
const p1 = new THREE.Vector3(-100, 0, 0);
const p2 = new THREE.Vector3(50, 100, 0);
const p3 = new THREE.Vector3(100, 0, 100);
const p4 = new THREE.Vector3(100, 0, 0);

// 画三维贝塞尔曲线
const curve = new THREE.CubicBezierCurve3(p1, p2, p3, p4);
const pointsArr = curve.getPoints(20);

const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);

const material = new THREE.LineBasicMaterial({
  color: new THREE.Color("orange"),
});
const line = new THREE.Line(geometry, material);

const geometry2 = new THREE.BufferGeometry();
geometry2.setFromPoints([p1, p2, p3, p4]);
const material2 = new THREE.PointsMaterial({
  color: new THREE.Color("pink"),
  size: 5,
});
const points2 = new THREE.Points(geometry2, material2);
const line2 = new THREE.Line(geometry2, new THREE.LineBasicMaterial());
line.add(points2, line2);

export default line;
  • 效果图如下: image.png

image.png

CurvePath

一条曲线可能是由多条曲线复合而成的,就能用这个api组合多条曲线

import * as THREE from "three";

const p1 = new THREE.Vector2(0, 0);
const p2 = new THREE.Vector2(100, 100);
const line1 = new THREE.LineCurve(p1, p2);
const arc = new THREE.EllipseCurve(0, 100, 100, 100, 0, Math.PI);

const p3 = new THREE.Vector2(-100, 100);
const p4 = new THREE.Vector2(0, 0);
const line2 = new THREE.LineCurve(p3, p4);
const curvePath = new THREE.CurvePath();
curvePath.add(line1);
curvePath.add(arc);
curvePath.add(line2);

const pointsArr = curvePath.getPoints(20);
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);

const material = new THREE.LineBasicMaterial({
  color: new THREE.Color("pink"),
});

const line = new THREE.Line(geometry, material);

export default line;
  • 效果如下: image.png
  • 把点描出来
  • line5.js
import * as THREE from "three";

const p1 = new THREE.Vector2(0, 0);
const p2 = new THREE.Vector2(100, 100);
const line1 = new THREE.LineCurve(p1, p2);
const arc = new THREE.EllipseCurve(0, 100, 100, 100, 0, Math.PI);

const p3 = new THREE.Vector2(-100, 100);
const p4 = new THREE.Vector2(0, 0);
const line2 = new THREE.LineCurve(p3, p4);
const curvePath = new THREE.CurvePath();
curvePath.add(line1);
curvePath.add(arc);
curvePath.add(line2);

const pointsArr = curvePath.getPoints(20);
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr);

const material = new THREE.LineBasicMaterial({
  color: new THREE.Color("pink"),
});

const line = new THREE.Line(geometry, material);

// 把点描出来
const geometry2 = new THREE.BufferGeometry();
geometry2.setFromPoints([p1, p2, p3]);
const material2 = new THREE.PointsMaterial({
  color: new THREE.Color("blue"),
  size: 5,
});
const points2 = new THREE.Points(geometry2, material2);
line.add(points2);
export default line;
  • 效果图如下: image.png

学习来源 神光小测和官网