I have a data structure that creates child planes within the parent plane when some threshold is met. I would like to curve all these planes such that each child plane matches its parent curvature seamlessly/evenly.
this is what my data structure looks like:
this is the curvature result I am looking to accomplish:
Hi!
each child plane curvature matches it parents?
By setting the same length for vectors of vertices?
yes, but how could I accomplish that?
Somehow like this:
var pos = geometry.attributes.position;
var v3 = new THREE.Vector3();
for(let i = 0; i < pos.count; i++) {
v3.fromBufferAttribute(pos, i).setLength( _desired_radius_ );
pos.setXYZ( i, v3.x, v3.y, v3.z);
}
sorry if I didn’t make my problem clear but
this is the result I got.
This is the result I’m looking for. Just a curved plane and the higher resolution child plane is also curved
It’s perfectly clear. Translate your geometry _desired_radius_
units on Z-axis (with .translate()
method of BufferGeometry
) before deformation.
Ok, so I’m able to get the plane to curve. But I run into a problem where the plane starts to move towards the background after setting plane.geometry.translate(0,0,desired_radius). I’m guessing this is because I’m using the planes BufferGeometry.translate() in a for loop. Is there a workaround to this problem?
Don’t call .translate()
in loop. Call it once before you start the loop.
I would but my algorithm needs to run in a loop. I’m checking if a distance threshold is meet every frame to create the child plane with a higher resolution so .translate() needs to be called for every plane
this code that I found you helped someone with a similar problem but I didn’t want to just copy and paste the code.
function planeCurve(planeGeometry ,z){
let p = planeGeometry.parameters;
console.log(planeGeometry)
let hw = planeGeometry.geometry.parameters.width * 0.5;
//Here three points are defined, the left edge, right edge and the z bend in y direction.
//These three points touch the circle with radius r at its border.
let a = new THREE.Vector2(-hw,0);
let b = new THREE.Vector2(0,z);
let c = new THREE.Vector2(hw,0);
let ab = new THREE.Vector2().subVectors(a,b);
let bc = new THREE.Vector2().subVectors(b,c);
let ac = new THREE.Vector2().subVectors(a,c);
//formula for finding a circle which contains all points on its edge.
let r = (ab.length() * bc.length() * ac.length()) / (2 * Math.abs(ab.cross(ac)));
//Calculation of the center of the circle. The center of the circle has to be at z - r, because r is the radius of the circle and b is positioned on the edge of the circle with (0,z)
let center = new THREE.Vector2(0, z - r);
//Generates a vector from the central point to the point to the left bottom.
let baseV = new THREE.Vector2().subVectors(a, center);
//And this is where i fail to get your code... Why these calculations?
let baseAngle = baseV.angle() - (Math.PI * 0.5);
let arc = baseAngle * 2;
let uv = planeGeometry.geometry.attributes.uv;
let pos = planeGeometry.geometry.attributes.position;
let mainV = new THREE.Vector2();
for(let i = 0; i < uv.count; i++){
//Why the 1 - uv.getX(i)? I don't understand it.
let uvRatio = 1 - uv.getX(i);
let y = pos.getY(i);
mainV.copy(c).rotateAround(center, (arc * uvRatio));
pos.setXYZ(i, mainV.x, y, mainV.y);
}
pos.needsUpdate = true;
return planeGeometry;
}
here it almost works but as you can see the child plane isn’t evenly (if that’s the right word to use) laying on the parents
Would dividing your arc by the mesh width work maybe?
This is called an “LOD” problem.
And it appears, you are not talking about “Planes” in the Three.js sense, but rather about “surfaces”.
Try to formulate a mathematical description of the surface. Then you’ll be free to compute vertices within that surface description at ever smaller intervals, as necessary.
Here is an example of how you can bend planes of different segmentation to form a spherical “segment”: https://codepen.io/prisoner849/full/ZEaVzvX
1 Like
Obviously, as soon as you know it’s a spherical surface, you have its mathematical description right on a silver platter. I think, the OP was referring to a more generalized kind of surface. I could imagine a digital elevation model or something of that kind.
This is exactly what I was looking for, thank you. My only issue is when I brought the code over from addeventlistener function to a regular js function I run into the same issue as before where I had to use .translate() but .translate() isn’t an option because my code has to run in a loop.
So, I think I have found the issue. I decided to put the code that was in btnBend.addEventListener function into use setTimeout function and it worked. I’m not sure why I had to do that, I would like to know?
is there a way to edit the z vertex position? Currently, if try to add some height (random number) at each z vertex position it becomes flattened along the curve.