How do i translate some x,y,z positions of a cell to fall inside my scene

Hi Team,

I have a group of cells with x,y,z coordinates that i want to create a little circle mesh for each one. And draw them on the scene. But as soon as the mesh is created and added to the scene and the position is set for that mesh, i dont see the mesh any more. It is as if it is drawn somewhere that is not in the field of view of my small scene. How do i translate those coordinates to fall within my small scene.

Thanks

Set the x and y coordinates equal to zero and try different z values (both positive and negative).
Does the camera have some value that may be causing is to look elsewhere?

If you use orbitcontrols, the camera will look at the center and you can rotate the camera around the center or you can move laterally and you should be able to find the little buggers.

it could be alot of things, can you post your code?
are you sure you translate the circle mesh’s position into world coords?

That is what i wanted to figure out. How should i translate the coordinates into world coordinates?
I have three cells with their coordinates from the microscope that i want to display and ensure that they maintain their correct distance from each other when i draw them into the threejs scene.
When i center any of the meshes from these cells i can see the cell. But obviously that is not the right coordinates since it is centered in the scene and that is not what i want. FYI, here is my mesh center code just for reference:
var center = new THREE.Vector3();
mesh.geometry.boundingBox.getCenter(center);
mesh.geometry.center();
mesh.position.copy(center);

so this proves to me that the mesh is in the scene and shows up when i center it. But it also proves to me that my coordinates should be translated into the world coordinate within that scene so i can see them render and also see their position from each other on the scene.

https://threejs.org/docs/#api/en/core/Object3D.getWorldPosition

console log ur coords + a few screenshots of what ur shit looks like would be helpful

Hi @rinzexe

Sure I am pasting my code below. Basically i am creating multiple little scenes with different cell patterns. For simplicity i am just doing one scene with 3 cells in it that is hard coded inside the code in this line so the code does not look to complex:

// Cell1 Cell2 Cell3
let cellArray = [ {x: “73” , y: “271” }, {x: “243” , y: “245” }, {x: “294” , y: “120” }]

The inspiration for this code is from this post:
three.js webgl - multiple elements

I am trying to draw three little circles each circle representing a cell based on above coordinates.

Here is my entire react function. And the main action is in the init() method:

const drawMultiScenes = () => {

      let canvas, renderer;

      const scenes = [];

      init();
      animate();

      function init() {

        canvas = document.getElementById( 'c' );

        const geometries = [
          new THREE.BoxGeometry( 1, 1, 1 ),
          new THREE.SphereGeometry( 0.5, 12, 8 ),
          //new THREE.DodecahedronGeometry( 0.5 ),
          new THREE.IcosahedronGeometry( 0.3, 6 ),
          new THREE.CircleGeometry( 1, 49 ),
          new THREE.CylinderGeometry( 0.5, 0.5, 1, 12 )
        ];

        let numberOfScenes = 1;
        const content = document.getElementById( 'content' );

          // This controls how many little scenes we will have
          for (let i = 0; i < numberOfScenes; i++) {

            const scene = new THREE.Scene();

            //let data = multiFovData[i].data;

            // make a list item
            const element = document.createElement( 'div' );
            element.className = 'list-item';

            const sceneElement = document.createElement( 'div' );
            element.appendChild( sceneElement );

            //const descriptionElement = document.createElement( 'div' );
            //descriptionElement.innerText = 'Scene ' + ( i + 1 );
            //element.appendChild( descriptionElement );

            // the element that represents the area we want to render the scene
            scene.userData.element = sceneElement;
            content.appendChild( element );

            //const camera = new THREE.PerspectiveCamera( 50, 1, 1, 10 );
            const camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.01, 10000 ); 
            camera.position.z = 2;
            scene.userData.camera = camera;

            const controls = new OrbitControls( scene.userData.camera, scene.userData.element );
            controls.minDistance = 2;
            controls.maxDistance = 5;
            controls.enablePan = true;
            controls.enableZoom = true;
            scene.userData.controls = controls;

            // add one random mesh to each scene
            

            const geometry = geometries[2];

            //                   Cell1                  Cell2                  Cell3
            let cellArray = [ {x: "73" , y: "271" }, {x: "243" , y: "245" }, {x: "294" , y: "120" }]

            for (let j=0; j < cellArray.length; j++) {

                      let material = new THREE.MeshStandardMaterial( {
                        color: new THREE.Color().setHSL( Math.random(), 1, 0.75, THREE.SRGBColorSpace ),
                        roughness: 0.0,
                        metalness: 0,
                        flatShading: true
                      } ); 

                       material = new THREE.MeshPhongMaterial( { color: new THREE.Color().setHSL( Math.random(), 1, 0.75, THREE.SRGBColorSpace ), transparent: true, opacity: 1.0} );

                  
                   
                     let x = cellArray[j].x;
                     let y = cellArray[j].y;
                     x = parseFloat( x );
                     y = parseFloat( y)
                     let mesh = new THREE.Mesh( geometry, material );
                     mesh.position.set( x, y, 0 );
                     //mesh.position.set( 0, 0, 0 );
                     scene.add( mesh );  
            }

            scene.add( new THREE.HemisphereLight( 0xaaaaaa, 0x444444, 3 ) );

            const light = new THREE.DirectionalLight( 0xffffff, 1.5 );
            light.position.set( 1, 1, 1 );
            scene.add( light );

            scenes.push( scene );

        }


        renderer = new THREE.WebGLRenderer( { canvas: canvas, antialias: true } );
        renderer.setClearColor( 0xffffff, 1 );
        renderer.setPixelRatio( window.devicePixelRatio );

      }

      function updateSize() {

        const width = canvas.clientWidth;
        const height = canvas.clientHeight;

        if ( canvas.width !== width || canvas.height !== height ) {

          renderer.setSize( width, height, false );

        }

      }

      function animate() {

        render();
        requestAnimationFrame( animate );

      }

      function render() {

        updateSize();

        canvas.style.transform = `translateY(${window.scrollY}px)`;

        renderer.setClearColor( 0xffffff );
        renderer.setScissorTest( false );
        renderer.clear();

        renderer.setClearColor( 0xe0e0e0 );
        renderer.setScissorTest( true );

        scenes.forEach( function ( scene ) {

          //let scene = obj.scene;
          //let controls = obj.controls;
          // so something moves
          scene.children[ 0 ].rotation.y = Date.now() * 0.001;

          // get the element that is a place holder for where we want to
          // draw the scene
          const element = scene.userData.element;

          // get its position relative to the page's viewport
          const rect = element.getBoundingClientRect();

          // check if it's offscreen. If so skip it
          if ( rect.bottom < 0 || rect.top > renderer.domElement.clientHeight ||
             rect.right < 0 || rect.left > renderer.domElement.clientWidth ) {

            return; // it's off screen

          }

          // set the viewport
          const width = rect.right - rect.left;
          const height = rect.bottom - rect.top;
          const left = rect.left;
          const bottom = renderer.domElement.clientHeight - rect.bottom;

          renderer.setViewport( left, bottom, width, height );
          renderer.setScissor( left, bottom, width, height );

          const camera = scene.userData.camera;

          //camera.aspect = width / height; // not changing in this example
          //camera.updateProjectionMatrix();

          scene.userData.controls.update();

          renderer.render( scene, camera );

        } );

      }

   }

Here is the screen shot of this code with the little grey box being empty:

I am setting the position inside the second loop as follows:
mesh.position.set( x, y, 0 );

Now if i replace that statement with this one just to see if i can even see the meshes:
mesh.position.set( 0, 0, 0 );
I will get the following result below. And in this one all three cells are drawn on top of each other because i am using mesh.position.set( 0, 0, 0 ); So that proves to me that my other positions dont fall within the scene. And that is what i am trying to see why. BTW: those other three cells X,Y positions are real coordinates from the microscope for those cells. Anyway let me know if this gives enough depth to the issue for you to see. Do i need to convert those x,y coordinates to workld coordinates somehow? Also for the Z coordinate i am using zero because the cell table does not provide that and for this page it is not neccassary.

Thank you again for your help in advance

Hi Guys, just wondering if there is any more insights after i pasted more code and screen shots. @rinzexe any ideas?

Hey, I’m pretty sure this is “just” a positioning problem.
That is, your camera cannot see the positions where you are putting your meshes.

Here’s a reproduction of your code:

https://7vypx9-5173.csb.app/?component=PositionProblemCanvas

where I’ve simply scaled down the positions:

1 Like

Thank you very much @rob-myers. Oddly enough right after i posted my last question, i started doing the same thing. I divided y by 2000 and x by 1000 to get a proportional cell view and be able to center everything using BufferGeometry. Here is the screen shot:

That being said your suggestion was right on. And thanks for going to the trouble of making an example with code as well.

Regards

Cheers. It might help to make smaller examples, because it’s easy to get lost. Also, if possible, I’d suggest using react-three-fiber which is easier to debug.

Finally, would you mind accepting my answer if it’s correct?

Thanks @rob-myers. Appreciate your help. And yes I did accept your answer.