Is there a correspondence of d3.linearScale in Three.js?

Hi all, I’m asking if there’s something like d3.linearScale so that I can shrink my Mesh in a fixed dimensions graph and keep the real position of the points so that if I drag some points I still get their position in the original scale…

I hope I explained myself… Thanks!

Are you looking for Object3D.scale? If you scale your 3D object with this property, the respective geometry data do not change.

Hi Mugen, I’ll have a look, do you think is possible to shrink a width of an object to a fixed value? For example I’d like to scale the width of a loaded object to fit 100 keeping its geometry. I don’t want to scale it of 50% or something, I want to scale it such as its width will be 100… If the width is already 100 it should not scale at all, if its width is 200 it should scale of 50%, etc Something like this: those surfaces are “compressed” so that they fit in a “cube” of a fixed dimensions, whatever their dimensions are…

We don’t have the equivalent function to d3.linearScale, since it’s not a common use case for 3D objects. You’ll need to write it yourself.

width of a loaded object

That’s not always obvious with 3d objects. Or rather, it’s pretty hard to calculate, especially for complex objects, and even harder for animated objects.

You can use the bounding box and scale it based on that, then you’ll get a linear scale to fit the object inside a box of width 100. Again, it won’t work for skinned or morphed animated objects, and it will be less accurate for objects that don’t fit easily in a box shape. But if it’s good enough for your use case then that’s the simplest approach.

Yes I was thinking about that…
The object is a simple line or surface, like the previously linked example. So I should find its width and calculate the scale so that it will compress to have a width of 100…

Maybe Matrix4 can help ? Is hard to understand if it’s going to be useful

The object is a simple line or surface

Ok, then the bounding box should be fine. Try this:

object.geometry.computeBoundingBox();

const size = new Vector3();

object.geometry.boundingBox.getSize( size );

const width = size.x;

Once you’ve got the width, you can scale the object as you need based on that width. For example, to make it one unit wide:

// Reset scale 
object.scale.set( 1,1,1 );

// Now the object will be one unit wide
object.scale.multiplyScalar( 1 / width );

To write a linear scale method that matches the D3 method, it’s probably best to start by examining their code.

Maybe Matrix4 can help ?

If you’re comfortable with matrices and know what a 4x4 affine transformation matrix is, you can work with the object’s matrix directly. Otherwise it’s probably best to stick with using the scale.

2 Likes

Thanks! I didn’t know about computeBoundingBox