|
|
import { drawAxis, drawAxis2D } from './drawHistory.js';
|
|
|
let renderer, scene, camera, controls, renderer2D, scene2D, camera2D, controls2D;
|
|
|
|
|
|
let axis = new THREE.Group();
|
|
|
let axis2D = new THREE.Group();
|
|
|
let initAxis = 80;//正值最大值
|
|
|
let minNum = 0;//负值最大值
|
|
|
|
|
|
let planes = [];//截断面
|
|
|
|
|
|
let maxRange = 100;
|
|
|
|
|
|
const lut = new THREE.Lut();
|
|
|
lut.addColorMap('axis', [[0.0, 0x00ee00], [0.25, 0xeeee00], [0.75, 0xee0000], [1.0, 0x4e0211]],);
|
|
|
lut.setColorMap('axis', 500)
|
|
|
|
|
|
let meshList = new THREE.Group();//图例柱子
|
|
|
meshList.name = 'chartsMesh';
|
|
|
const dummy = new THREE.Object3D();
|
|
|
|
|
|
let pointsList = new THREE.Group();//图例散点
|
|
|
pointsList.name = 'chartsPoint';
|
|
|
|
|
|
// 周期,相位 柱子数
|
|
|
let period = 50, phase = 128, count = period * phase;
|
|
|
const geometry = new THREE.BoxGeometry(0.6, 1, 2.5);
|
|
|
geometry.computeVertexNormals();
|
|
|
|
|
|
//非光泽表面的材质,没有镜面高光
|
|
|
//const initInstancedMesh = new THREE.InstancedMesh(geometry, new THREE.MeshLambertMaterial(), count);
|
|
|
//最佳性能材质
|
|
|
const initInstancedMesh = new THREE.InstancedMesh(geometry, new THREE.MeshBasicMaterial(), count);
|
|
|
initInstancedMesh.name = 'initInstancedMesh';
|
|
|
|
|
|
/* prpd初始Instanced点 */
|
|
|
let initInstancedPoints,//prpd实例
|
|
|
pointPositions, pointColors,//PRPS位置及颜色的集合
|
|
|
pointsGeometry = new THREE.BufferGeometry(),
|
|
|
pointCount;
|
|
|
|
|
|
|
|
|
init();
|
|
|
init2D();
|
|
|
render();
|
|
|
render2D();
|
|
|
onWindowResize()
|
|
|
//prps or prpd 切换
|
|
|
$('#prps').click(function () {
|
|
|
$('#box3D1').toggle();
|
|
|
$('#box2D1').toggle();
|
|
|
$(this).toggleClass('ready')
|
|
|
$('#prpd').toggleClass('ready')
|
|
|
})
|
|
|
|
|
|
$('#prpd').click(function () {
|
|
|
$('#box2D1').toggle();
|
|
|
$('#box3D1').toggle();
|
|
|
$(this).toggleClass('ready')
|
|
|
$('#prps').toggleClass('ready')
|
|
|
})
|
|
|
$(window).resize(function () {
|
|
|
window.requestAnimationFrame(function () {
|
|
|
onWindowResize()
|
|
|
})
|
|
|
})
|
|
|
//prps初始化
|
|
|
function init() {
|
|
|
let box = $('#box3D1');
|
|
|
let width = box.width();
|
|
|
let height = box.height();
|
|
|
renderer = new THREE.WebGLRenderer({ logarithmicDepthBuffer: true, antialias: true, preserveDrawingBuffer: true, });//preserveDrawingBuffer保存three.js canvas画布上的信息
|
|
|
renderer.localClippingEnabled = true
|
|
|
let constant = (360 / (initAxis)) * initAxis + 1
|
|
|
planes = [
|
|
|
new THREE.Plane(new THREE.Vector3(0, -1, 0), constant), //y轴正值截取
|
|
|
]
|
|
|
renderer.clippingPlanes = planes
|
|
|
renderer.setSize(width, height);//设置渲染区域尺寸
|
|
|
renderer.setClearColor(0xffffff, 1); //设置背景颜色
|
|
|
//renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
|
|
|
renderer.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果
|
|
|
box?.append(renderer.domElement); //body元素中插入canvas对象
|
|
|
scene = new THREE.Scene();
|
|
|
scene.add(meshList, axis, pointsList);
|
|
|
|
|
|
/* var point = new THREE.PointLight(0xffffff);
|
|
|
point.position.set(600, 600, 600); //点光源位置
|
|
|
scene.add(point); //点光源添加到场景中
|
|
|
var ambient = new THREE.AmbientLight(0x444444);
|
|
|
scene.add(ambient); */
|
|
|
|
|
|
drawAxis(initAxis, minNum, true)
|
|
|
|
|
|
var k = width / height; //窗口宽高比
|
|
|
var s = 420; //三维场景显示范围控制系数,系数越大,显示的范围越大
|
|
|
//创建相机对象
|
|
|
camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1600);
|
|
|
camera.position.set(500, 200, 500); //设置相机位置
|
|
|
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
|
|
|
controls = new THREE.OrbitControls(camera, renderer.domElement);
|
|
|
// 设置左右方向的最大、最小角度限制为 90 度和 0 度
|
|
|
controls.minAzimuthAngle = 0;
|
|
|
controls.maxAzimuthAngle = Math.PI / 2;
|
|
|
// 设置上下方向的最大、最小角度限制为 90 度和 0 度
|
|
|
controls.minPolarAngle = 0;
|
|
|
controls.maxPolarAngle = Math.PI / 2;
|
|
|
//设置放大缩小上下限
|
|
|
controls.minZoom = 0.5;
|
|
|
controls.maxZoom = 2;
|
|
|
//controls.enablePan = false;
|
|
|
//设置控制器中心点
|
|
|
controls.target.set(25, 0, 180);
|
|
|
renderer.render(scene, camera);
|
|
|
|
|
|
//controls.addEventListener('change', render);
|
|
|
}
|
|
|
//prpd初始化
|
|
|
function init2D() {
|
|
|
let box = $('#box2D1');
|
|
|
let width = box.width();
|
|
|
let height = box.height();
|
|
|
renderer2D = new THREE.WebGLRenderer({ logarithmicDepthBuffer: true, antialias: true, preserveDrawingBuffer: true, });//preserveDrawingBuffer保存three.js canvas画布上的信息\
|
|
|
renderer2D.localClippingEnabled = true
|
|
|
let constant = (360 / (initAxis)) * initAxis + 1
|
|
|
planes = [
|
|
|
new THREE.Plane(new THREE.Vector3(0, -1, 0), constant), //y轴正值截取
|
|
|
]
|
|
|
renderer2D.clippingPlanes = planes
|
|
|
renderer2D.setSize(width, height);//设置渲染区域尺寸
|
|
|
renderer2D.setClearColor(0xffffff, 1); //设置背景颜色
|
|
|
renderer2D.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果
|
|
|
box?.append(renderer2D.domElement); //body元素中插入canvas对象
|
|
|
scene2D = new THREE.Scene();
|
|
|
const List = pointsList.clone()
|
|
|
scene2D.add(axis2D, List, pointsList)
|
|
|
drawAxis2D(initAxis, minNum)
|
|
|
// 辅助坐标系 参数250表示坐标系大小,可以根据场景大小去设置
|
|
|
// let axisHelper = new THREE.AxesHelper(250);
|
|
|
// scene2D.add(axisHelper);
|
|
|
var k = width / height; //窗口宽高比
|
|
|
var s = 380; //三维场景显示范围控制系数,系数越大,显示的范围越大
|
|
|
//创建相机对象
|
|
|
camera2D = new THREE.OrthographicCamera(-s * k - 200, s * k - 200, s + 160, -s + 160, 1, 1200);
|
|
|
camera2D.position.set(600, 0, 0); //设置相机位置
|
|
|
camera2D.lookAt(scene2D.position); //设置相机方向(指向的场景对象)
|
|
|
controls2D = new THREE.OrbitControls(camera2D, renderer2D.domElement);
|
|
|
controls2D.enablePan = false//右键位移禁用
|
|
|
controls2D.enableZoom = false//放大缩小禁用
|
|
|
//设置放大缩小上下限
|
|
|
controls2D.minZoom = 0.5;
|
|
|
controls2D.maxZoom = 2;
|
|
|
controls2D.enableRotate = false
|
|
|
renderer2D.render(scene2D, camera2D);
|
|
|
controls2D.addEventListener('change', render2D);
|
|
|
}
|
|
|
function onWindowResize() {
|
|
|
let h = $(window).height();
|
|
|
let w = $(window).width();
|
|
|
$(".loading-box").css('height', h * 0.95)
|
|
|
let box = $('#box3D1');
|
|
|
let width = box.width();
|
|
|
|
|
|
let height = box.height();
|
|
|
let k = width / height; //窗口宽高比
|
|
|
let s = 350; //三维场景显示范围控制系数,系数越大,显示的范围越大
|
|
|
|
|
|
camera.left = -s * k - 20;
|
|
|
camera.right = s * k - 20;
|
|
|
camera.top = s + (minNum ? -80 : 60);
|
|
|
camera.bottom = -s + (minNum ? -80 : 60);
|
|
|
camera.aspect = k;
|
|
|
camera.updateProjectionMatrix();
|
|
|
renderer.setSize(width, height);
|
|
|
renderer.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果
|
|
|
|
|
|
let s2D = 270;
|
|
|
camera2D.left = -s2D * k - 200;
|
|
|
camera2D.right = s2D * k - 200;
|
|
|
camera2D.top = s2D + (minNum ? -30 : 155);
|
|
|
camera2D.bottom = -s2D + (minNum ? -30 : 155);
|
|
|
camera2D.aspect = k;
|
|
|
camera2D.updateProjectionMatrix();
|
|
|
renderer2D.setSize(width, height);
|
|
|
renderer2D.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果
|
|
|
}
|
|
|
function render() {
|
|
|
// 获取摄像机的视锥体
|
|
|
const frustum = new THREE.Frustum();
|
|
|
const cameraViewProjectionMatrix = new THREE.Matrix4();
|
|
|
camera.updateMatrixWorld(); // 确保摄像机的世界矩阵已更新
|
|
|
cameraViewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
|
frustum.setFromProjectionMatrix(cameraViewProjectionMatrix);
|
|
|
|
|
|
// 遍历场景中的每个对象,并根据视锥体进行剔除
|
|
|
scene.traverse((object) => {
|
|
|
if (object.isMesh) {
|
|
|
object.visible = frustum.intersectsObject(object);
|
|
|
}
|
|
|
});
|
|
|
// 更新帧率显示器
|
|
|
//stats.update();
|
|
|
renderer.render(scene, camera);
|
|
|
requestAnimationFrame(render)
|
|
|
}
|
|
|
function render2D() {
|
|
|
//scene.rotateY(0.001);//每次绕y轴旋转0.01弧度
|
|
|
requestAnimationFrame(render2D)
|
|
|
renderer2D.render(scene2D, camera2D);
|
|
|
}
|
|
|
|
|
|
export { scene, axis, meshList, pointsList, axis2D, scene2D } |