# Y position at a certain x position of a moving tubegeomerty

I am very new with three.js and I wanted to do something that looked simple.
I wanted to generate a tube that follows some data points (a sinewave for now) and shift this to the left with a certain speed ( x seconds) . That seems to work but then I want a box, sphere or whatever mesh to not move to the left (x-axis) but only follow the y values (height) of the moving tube. Like if you would shine a spotlight on it. Because I have no clue what the y value is on the path at a certain x value I want to use the raycaster, I looked it up from a few samples etc but I cannot get it to work. Can someone help with this raycaster (see attached code) or has another idea of calculating the y value at a certain x inside the path of a tubegeomerty ? I also tried path.getPointAt(x); but that probably only gives a point at a certain length of the path between 0…1
index.html (2.3 KB)

My first three.js app body { margin: 0; }
``````	    class CustomSinCurve extends THREE.Curve {
constructor( scale = 1 ) {

super();

this.scale = scale;

}

getPoint( t, optionalTarget = new THREE.Vector3() ) {

const tx = t * 3 - 1.5;
const ty = Math.sin( 2 * Math.PI * t );
const tz = 0;

return optionalTarget.set( tx, ty, tz ).multiplyScalar( this.scale );

}

}

// Our Javascript will go here.
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );

const path = new CustomSinCurve( 10 );
const geometryPipe = new THREE.TubeGeometry( path, 70, 2, 16, false );
const materialPipe = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const meshPipe = new THREE.Mesh( geometryPipe, materialPipe );

// Add some lighting to the scene
var light = new THREE.PointLight( 0xffffff, 1, 100 );
light.position.set( 5, 5, 5 );

camera.position.z = 50;

function animate() {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;

meshPipe.position.x -= 0.1;

// Create a new raycaster
var raycaster = new THREE.Raycaster();

// Set the origin of the ray to the x value you're looking for
var x = 0;
raycaster.set(new THREE.Vector3(x, 0, 0), new THREE.Vector3(0, 1, 0));

// Check if the ray intersects with the tube
var intersects = raycaster.intersectObject(meshPipe);
if (intersects.length > 0) {
var y = intersects[0].point.y;
console.log(y);
}

renderer.render( scene, camera );
}
animate();
</script>
</body>
``````

You should not constantly create new objects in animate.

``````new THREE.Raycaster()
(new THREE.Vector3(x, 0, 0), new THREE.Vector3(0, 1, 0))
``````

You can create them once and then use them.

Take a look at the beginner example step 10 from the collection.

getPointAt afaict, takes in a unit from 0 to 1 and gives out a vector in world coordinates at the given unit, so 0.5 would return a world coordinate vector3 half way along the curve. As @hofk has mentioned its probably best to create this vector once and have getPointAt update it as needed…

Thanks ! , these examples look amazing, since I am brand new to three.js I will get through them. The RaycastingToLine is a really helpfull for my project. I am going to try to make it work that way.

Maybe this older example is also helpful?

eXtended eXamples Modify indexed BufferGeometry - @author hofk

see line 548 `function onContainerMouseDown( event ) { ...`

Yes, thank you. All examples are helpfull !