当前位置:网站首页>Three 之 three.js (webgl)简单实现根据点绘制线/弧线(基于LineGeometry / Line2 / LineMaterial,绘制两点基于圆心的弧线段)
Three 之 three.js (webgl)简单实现根据点绘制线/弧线(基于LineGeometry / Line2 / LineMaterial,绘制两点基于圆心的弧线段)
2022-04-23 05:17:00 【仙魁XAN】
Three 之 three.js (webgl)简单实现根据点绘制线/弧线(基于LineGeometry / Line2 / LineMaterial,绘制两点基于圆心的弧线段)
目录
Three 之 three.js (webgl)简单实现根据点绘制线/弧线(基于LineGeometry / Line2 / LineMaterial,绘制两点基于圆心的弧线段)
一、简单介绍
Three js 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。
本节介绍, three.js (webgl)中绘制线段的功能,主要根据 LineGeometry 进行点的设置,然后使用 Line2 进行绘制点组成的线段,绘制线实现方式很多,这里仅供思路提供,如果有不足之处,欢迎指出,或者你有更好的方法,欢迎留言。
二、案例简单示意图

三、实现原理
1、向量 angleTo 计算 A 向量与 B 向量之间的角度
2、然后根据sin(),cos() 方式获得弧线的点
3、把点给 LineGeometry,使用 Line2 结合材质把线段绘制出来
四、注意事项
1、这里是基于原点(0,0,0)的,如果圆点不在原点(0,0,0),在计算弧线点的时候添加上圆点位置;(一些思路提供)
2、这里是在 X Y 平面绘制的圆弧,如果不是,可以根据计算一些角度(通过 z 点得到旋转角度),然后在 X Y 平面绘制的圆弧 在根据得到的角度旋转即可;(一些思路提供)
3、绘制弧线分段精度可控,并且还可以设置弧线每个点的颜色
五、该案例的大概实现步骤
该案例基于Threejs GitHub - mrdoob/three.js: JavaScript 3D Library.
工程框架创建实现的
1、创建脚本,引入 Three,创建基本的 Three 环境,添加场景,摄像机,光等


2、添加进行绘制弧线的演示的 3D 物体
3、根据一些点的向量得到对应的一些绘制角度

4、根据得到的角度,结合圆弧回执函数(sin/cos),生成圆弧位置点,最后,通过 LineGeometry 、Line2 绘制圆弧

5、在函数中调用对应函数,然后就可以在浏览器中查看效果了

六、关键代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>11TestCurveLine</title>
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "../../../build/three.module.js"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from '../../jsm/controls/OrbitControls.js';
import Stats from '../../jsm/libs/stats.module.js';
import { LineMaterial } from '../../jsm/lines/LineMaterial.js';
import { LineGeometry } from '../../jsm/lines/LineGeometry.js';
import { Line2 } from '../../jsm/lines/Line2.js';
let scene, camera, renderer, stats;
let POSITION_A;
let POSITION_B;
let POSITION_Center;
let targetDegreeT1;
let targetDegreeT2;
const radius = 5;
init();
animate();
function init() {
// scene
initScene();
// camera
initCamera();
// light
initLight();
// renderer
initRenderer();
// OrbitControls
initOrbitControls();
stats = new Stats();
document.body.appendChild( stats.dom );
// onWindowResize
window.addEventListener( 'resize', onWindowResize );
axiesHelper();
stats = new Stats();
document.body.appendChild( stats.dom );
// window.location.href = renderer.domElement.toDataURL( 'image/png' );
addTestRoateLineObject();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function initScene() {
scene = new THREE.Scene();
}
function initCamera() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 200 );
camera.position.set( 0, 0, 25 );
}
function initLight() {
const ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
scene.add( ambientLight );
const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.6 );
directionalLight.position.set( - 1, 1, 100 );
scene.add( directionalLight );
}
function initRenderer() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setClearColor( 0xcccccc );
document.body.appendChild( renderer.domElement );
}
function initOrbitControls() {
const controls = new OrbitControls( camera, renderer.domElement );
controls.minDistance = 5;
controls.maxDistance = 50;
controls.enablePan = false; // 移动 禁止
}
function animate() {
requestAnimationFrame( animate );
stats.update();
render();
}
function axiesHelper() {
var helper = new THREE.AxesHelper( 20 );
scene.add( helper );
}
function render() {
renderer.render( scene, camera );
}
function addTestRoateLineObject() {
const Degree_A = Math.PI / 4 * 3;
POSITION_A = new THREE.Vector3( radius * Math.cos( Degree_A ), radius * Math.sin( Degree_A ), 0 );
const Degree_B = Math.PI / 8;
POSITION_B = new THREE.Vector3( radius * Math.cos( Degree_B ), radius * Math.sin( Degree_B ), 0 );
POSITION_Center = new THREE.Vector3( 0, 0, 0 );
var geometry = new THREE.SphereGeometry( 4, 30 ); //矩形平面
var material = new THREE.MeshPhongMaterial( {} );
var spheremesh1 = new THREE.Mesh( geometry, material );
spheremesh1.position.set( POSITION_Center.x, POSITION_Center.y, POSITION_Center.z );
scene.add( spheremesh1 );
var geometryA = new THREE.SphereGeometry( 1, 30 ); //矩形平面
var materialA = new THREE.MeshPhongMaterial( {
color: '#cc0000'
} );
var spheremeshA = new THREE.Mesh( geometryA, materialA );
spheremeshA.position.set( POSITION_A.x, POSITION_A.y, POSITION_A.z );
scene.add( spheremeshA );
var geometryB = new THREE.SphereGeometry( 1, 30 ); //矩形平面
var materialB = new THREE.MeshPhongMaterial( {
color: '#cc00cc'
} );
var spheremeshB = new THREE.Mesh( geometryB, materialB );
spheremeshB.position.set( POSITION_B.x, POSITION_B.y, POSITION_B.z );
scene.add( spheremeshB );
rotateLineDataT1T2();
}
function rotateLineDataT1T2() {
const v1T1 = new THREE.Vector3( POSITION_A.x, POSITION_A.y, POSITION_A.z );
const v2T1 = new THREE.Vector3( POSITION_B.x, POSITION_B.y, POSITION_B.z );
targetDegreeT1 = v1T1.angleTo( v2T1 );
console.log( 'targetDegreeT1 ' + targetDegreeT1 );
const fromDegreeT1 = v2T1.angleTo( new THREE.Vector3( radius, 0, 0 ) );
console.log( 'fromDegreeT1 ' + fromDegreeT1 );
const toDegreeT1 = fromDegreeT1 + targetDegreeT1;
const v1T2 = new THREE.Vector3( POSITION_A.x, POSITION_A.y, POSITION_A.z );
const v2T2 = new THREE.Vector3( POSITION_B.x, POSITION_B.y, POSITION_B.z );
targetDegreeT2 = v2T2.angleTo( v1T2 );
console.log( 'targetDegreeT2 ' + targetDegreeT2 );
const modifyDegree = Math.PI * 2 - targetDegreeT2;
console.log( modifyDegree );
const fromDegreeT2 = toDegreeT1;
const toDegreeT2 = modifyDegree + fromDegreeT2;
scene.add(drawCurveLine( radius, 50, fromDegreeT1, toDegreeT1, 1, 0, 0 ));
scene.add(drawCurveLine( radius, 100, fromDegreeT2, toDegreeT2, 0, 1, 0 ));
}
function drawCurveLine( radius, segment, fromDegree, toDegree, colorR, colorG, colorB ) {
var geometry = new LineGeometry(); //声明一个几何体对象Geometry
var R = radius; // 圆弧半径
var N = segment; // 分段数量
const perAddDegree = ( toDegree - fromDegree ) / segment;
console.log( 'perAddDegree ' + perAddDegree );
const positionArray = [];
const colors = [];
// 批量生成圆弧上的顶点数据
for ( let i = 0; i < N; i ++ ) {
var angle = fromDegree + perAddDegree * i;
var x = R * Math.cos( angle );
var y = R * Math.sin( angle );
var z = 0;
positionArray.push( x, y, z );
colors.push( colorR, colorG, colorB );
}
geometry.setPositions( positionArray );
geometry.setColors( colors );
const matLine = new LineMaterial( {
color: 0xffffff,
linewidth: 0.01, // in world units with size attenuation, pixels otherwise
vertexColors: true,
//resolution: // to be set by renderer, eventually
dashed: false,
alphaToCoverage: true,
} );
const line = new Line2( geometry, matLine );
return line;
}
</script>
</body>
</html>
版权声明
本文为[仙魁XAN]所创,转载请带上原文链接,感谢
https://blog.csdn.net/u014361280/article/details/124349641
边栏推荐
- 好的测试数据管理,到底要怎么做?
- MySQL uses or to query SQL, and SQL execution is very slow
- 了解 DevOps,必读这十本书!
- What role do tools play in digital transformation?
- Simple application of parallel search set (red alarm)
- 即将毕业的大学生找技术开发工作的焦虑根源
- The concept of meta universe is popular. Is virtual real estate worth investing
- On distributed lock
- Three 之 three.js (webgl)旋转属性函数的简单整理,以及基于此实现绕轴旋转的简单案例
- Restful toolkit of idea plug-in
猜你喜欢

Redis data type usage scenario

Basic concepts of multithreading (concurrency and parallelism, threads and processes) and entry cases

Deep learning notes - data expansion

At pgconf Asia Chinese technology forum, listen to Tencent cloud experts' in-depth understanding of database technology

JSP -- Introduction to JSP

What are the reasons for the failure of digital transformation?

The applet calls the function of scanning QR code and jumps to the path specified by QR code

2022年最热门的招聘技术技能是什么,您绝对想不到

Traversal of tree

Deep learning notes - object detection and dataset + anchor box
随机推荐
[2021] Spatio-Temporal Graph Contrastive Learning
Basic concepts of multithreading (concurrency and parallelism, threads and processes) and entry cases
Data management of basic operation of mairadb database
scp命令详解
Using PHP post temporary file mechanism to upload arbitrary files
即将毕业的大学生找技术开发工作的焦虑根源
What are the reasons for the failure of digital transformation?
7-4 is it too fat (10 points) PTA
At pgconf Asia Chinese technology forum, listen to Tencent cloud experts' in-depth understanding of database technology
Traversal of tree
Swing display time (click once to display once)
Summary of MySQL knowledge points
【openh264】cmake: msopenh264-static
2022年最热门的招聘技术技能是什么,您绝对想不到
Independent station operation | Facebook marketing artifact - chat robot manychat
Study notes: unity customsrp-12-hdr
JS array common methods
Interview summary
Basic theory of Flink
Luogu p2731 horse riding fence repair