星系模拟。改变一个点的颜色,并在鼠标移动时显示文字。

问题描述 投票:2回答:1

我正在尝试创建 模拟 最近的4673个星系的位置的。

这些星系都是点。

我想在鼠标移动时给一个点上色,并加载星系的名称。

我花了很多天的时间来实现这个目标。我可以改变颜色,也可以进行基本的光线投射,但是,我无法单独对各个点进行光线投射。所有的点都是作为一个组来进行光线投射和着色的,如图所示。当前版本.

我应该怎么做才能改正?非常感谢您的时间和对一个初学者的耐心。

完整的代码是可用的 此处.

相关代码如下。

window.addEventListener( "mousemove", onDocumentMouseMove, false );

var selectedObject = null;

function onDocumentMouseMove( event ) {

    event.preventDefault();
    if ( selectedObject ) {

        selectedObject.material.color.set( '#fff' );
        selectedObject = null;

    }

    var intersects = getIntersects( event.layerX, event.layerY );
    if ( intersects.length > 0 ) {

        var res = intersects.filter( function ( res ) {

            return res && res.object;

        } )[ 0 ];

        if ( res && res.object ) {

            selectedObject = res.object;
            selectedObject.material.color.set( '#69f' );

        }

    }

}

var raycaster = new THREE.Raycaster();
var mouseVector = new THREE.Vector3();

function getIntersects( x, y ) {

    x = ( x / window.innerWidth ) * 2 - 1;
    y = - ( y / window.innerHeight ) * 2 + 1;

    mouseVector.set( x, y, 0.5 );
    raycaster.setFromCamera( mouseVector, camera );

    return raycaster.intersectObject( dots, true );

}
javascript three.js point raycasting
1个回答
3
投票

首先要做的是设置 raycaster.params.Points.threshold 等于你的点的大小。这使得当用户悬停在任何点上时,所有点的颜色都会改变。

(我增加了你的点的大小以方便悬停):

<html>
<head>
  <meta charset="UTF-8">
  <style>
    body { margin: 0; }
  </style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
  <script src="https://rawcdn.githack.com/mrdoob/three.js/f32e6f14046b5affabe35a0f42f0cad7b5f2470e/examples/js/controls/TrackballControls.js"></script>
</head>

<body>
<script>

// Create an empty scene
var scene = new THREE.Scene();

// Create a basic perspective camera
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.x = 200;

// Create a renderer with Antialiasing
var renderer = new THREE.WebGLRenderer({antialias:true});

// Configure renderer clear color
renderer.setClearColor("#000000");

// Configure renderer size
renderer.setSize( window.innerWidth, window.innerHeight );

// Append Renderer to DOM
document.body.appendChild( renderer.domElement );

//Add Milky Way
var dotGeometry = new THREE.Geometry();
dotGeometry.vertices.push(new THREE.Vector3( 0, 0, 0));

var rawFile = new XMLHttpRequest();
rawFile.open("GET", "https://rawcdn.githack.com/RiteshSingh/galaxies/9e6a4e54b37647e5a9a1d6f16c017769533fe258/galaxydata.txt", false);
rawFile.onreadystatechange = function ()
{
	if(rawFile.readyState === 4)
	{
		if(rawFile.status === 200 || rawFile.status == 0)
		{
			var allText = rawFile.responseText;
			var data = allText.split("\n");

			for (var i = 0; i < 4672; i++) {
				var parts = data[i].split("\t");

				var D = parts[0];
				var glon = parts[1]*3.1416/180;
				var glat = parts[2]*3.1416/180;

				var z = D*Math.sin(glat);
				var xy = D*Math.cos(glat);
				var x = xy*Math.cos(glon);
				var y = xy*Math.sin(glon);

				dotGeometry.vertices.push(new THREE.Vector3( x, y, z));
			}
		}
	}
}
rawFile.send(null);

var size = 0.32;
var dotMaterial = new THREE.PointsMaterial( { size: size } );
var dots = new THREE.Points( dotGeometry, dotMaterial );
scene.add( dots );

var controls = new THREE.TrackballControls( camera, renderer.domElement );

// Render Loop
var render = function () {
  requestAnimationFrame( render );
  controls.update();
  // Render the scene
  renderer.render(scene, camera);
};
render();

window.addEventListener( "mousemove", onDocumentMouseMove, false );

var selectedObject = null;

function onDocumentMouseMove( event ) {

	event.preventDefault();
	if ( selectedObject ) {

		selectedObject.material.color.set( '#fff' );
		selectedObject = null;

	}

	var intersects = getIntersects( event.layerX, event.layerY );
	if ( intersects.length > 0 ) {

		var res = intersects.filter( function ( res ) {

			return res && res.object;

		} )[ 0 ];

		if ( res && res.object ) {

			selectedObject = res.object;
			selectedObject.material.color.set( '#69f' );

		}

	}

}

var raycaster = new THREE.Raycaster();
raycaster.params.Points.threshold = size;
var mouseVector = new THREE.Vector3();

function getIntersects( x, y ) {

	x = ( x / window.innerWidth ) * 2 - 1;
	y = - ( y / window.innerHeight ) * 2 + 1;

	mouseVector.set( x, y, 0.5 );
	raycaster.setFromCamera( mouseVector, camera );

	return raycaster.intersectObject( dots, true );

}

</script>
</body>
</html>

然后你只需要让它变成只有被悬停的点会改变颜色。

<html>
<head>
  <meta charset="UTF-8">
  <style>
    body { margin: 0; }
  </style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
  <script src="https://rawcdn.githack.com/mrdoob/three.js/f32e6f14046b5affabe35a0f42f0cad7b5f2470e/examples/js/controls/TrackballControls.js"></script></script>
</head>

<body>
<script>

// Create an empty scene
var scene = new THREE.Scene();

// Create a basic perspective camera
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.x = 200;

// Create a renderer with Antialiasing
var renderer = new THREE.WebGLRenderer({antialias:true});

// Configure renderer clear color
renderer.setClearColor("#000000");

// Configure renderer size
renderer.setSize( window.innerWidth, window.innerHeight );

// Append Renderer to DOM
document.body.appendChild( renderer.domElement );

//Add Milky Way
var dotGeometry = new THREE.Geometry();
dotGeometry.vertices.push();

var colors = [];

var rawFile = new XMLHttpRequest();
rawFile.open("GET", "https://rawcdn.githack.com/RiteshSingh/galaxies/9e6a4e54b37647e5a9a1d6f16c017769533fe258/galaxydata.txt", false);
rawFile.onreadystatechange = function ()
{
	if(rawFile.readyState === 4)
	{
		if(rawFile.status === 200 || rawFile.status == 0)
		{
			var allText = rawFile.responseText;
			var data = allText.split("\n");

			for (var i = 0; i < 4672; i++) {
				var parts = data[i].split("\t");

				var D = parts[0];
				var glon = parts[1]*3.1416/180;
				var glat = parts[2]*3.1416/180;

				var z = D*Math.sin(glat);
				var xy = D*Math.cos(glat);
				var x = xy*Math.cos(glon);
				var y = xy*Math.sin(glon);

				dotGeometry.vertices.push(new THREE.Vector3( x, y, z));

				colors.push(new THREE.Color(0xFF0000));
			}
		}
	}
}
rawFile.send(null);

dotGeometry.colors = colors;

var size = 0.32;
var dotMaterial = new THREE.PointsMaterial({
	size: size,
	vertexColors: THREE.VertexColors,
});
var dots = new THREE.Points( dotGeometry, dotMaterial );
scene.add( dots );

var controls = new THREE.TrackballControls( camera, renderer.domElement );

// Render Loop
var render = function () {
  requestAnimationFrame( render );
  controls.update();
  // Render the scene
  renderer.render(scene, camera);
};
render();

window.addEventListener( "mousemove", onDocumentMouseMove, false );

var selectedObject = null;

function onDocumentMouseMove( event ) {

	event.preventDefault();
	if ( selectedObject ) {

		selectedObject.material.color.set( '#fff' );
		selectedObject = null;

	}

	var intersects = getIntersects( event.layerX, event.layerY );
	if ( intersects.length > 0 ) {
		var idx = intersects[0].index;
		dots.geometry.colors[idx] = new THREE.Color(0xFFFFFF);
		dots.geometry.colorsNeedUpdate = true;
		console.log(idx)
	}
}

var raycaster = new THREE.Raycaster();
raycaster.params.Points.threshold = size;
var mouseVector = new THREE.Vector3();

function getIntersects( x, y ) {

	x = ( x / window.innerWidth ) * 2 - 1;
	y = - ( y / window.innerHeight ) * 2 + 1;

	mouseVector.set( x, y, 0.5 );
	raycaster.setFromCamera( mouseVector, camera );

	return raycaster.intersectObject( dots, true );

}

</script>
</body>
</html>

你会看到用户鼠标移过点后,点会变成白色。

我将把它作为一个教学练习留给你,让你决定如何在鼠标退出某个点后将点变回红色:)

© www.soinside.com 2019 - 2024. All rights reserved.