How can I scale a round rectangle without distortion?

I need to scale a round rectangle either horizontally or vertically by moving the vertices at the round corners in order to avoid distortion. The round rectangle has been created with lineto/moveto/quadraticCurveTo as a shape, then it was converted to a mesh.

So obviously I need to select eg the vertices that belong to the left 10% of the total rectangle length in order to move them to the left or right, or the top 10% ones in order to move them upwards or downwards.

Any ideas how can I do that?

Or if I can list them, I can figure out which ones to select for each axis.

1 Like

Any link to your project? Or a live code example?
If it’s not classified :slight_smile:

It’s rather …highly classified+ :slight_smile: And it’s not online.
It’s also a bit complicated and >1600 lines (for the time being) -shaders aside.

I tried to re-create the geometry every frame by disposing it first, but aside the stuttering I get while scaling it, it usually leads to problems and instability. So I’m trying to do it more smoothly by just changing existing parameters like the vertices.

Instead of re-building the geometry on each frame, do it on mouse events only (at the moment when you really need a new geometry).
Have a look at the source code of this example:
http://discourse.threejs.hofk.de/interactiveShape/interactiveShape.html

2 Likes

You could also do it via shader, by using a 1x1x1 cube and a size uniform you’ll set in the onBeforeRender callback. I’ve used it in a configurator, the side segments required a rounding, this way there is no reconstruction and only 1 rounded cube geometry used.

I’d never recommend to construct geometries in a per frame manner, besides it being CPU intensive it will also cause memory issues and especially with low RAM quickly crash. It’s different if the geometry is actually a buffer and getting reused, but this isn’t designed this way internally by THREE.

3 Likes

can you illustrate what a “round rectangle” is with an image at least?

The one in the middle @pailhead
edit: i think he means an actual 2D rounded rectangle though

Lol, i think there are several solutions floating around.

I’ve got this, but @prisoner849 (?) did a few more elegant ones.

If it’s 2d, this could easily be done with something like this

const myDirs = [
  new THREE.Vector3(1,0,0),
  new THREE.Vector3(0,1,0),
  new THREE.Vector3(-1,0,0),
  new THREE.Vector3(0,-1,0),
]

const myVerts = []
const vertNumPerCorner = 16

for ( let corner = 0 ; corner < 4 ; corner ++ ){
  const offset = corner * Math.PI / 2 
  for ( let i = 0 ; i < vertNum ; i ++ ){
    let a = i / (vertNum - 1)  
    a *= Math.PI / 2
    a += offset
    myVerts.push(
      Math.cos(a),
      Math.sin(a),
      0
    )
  }
}

const myDynamicVerts = myVerts.map(vert=>vert.clone())

//make one rounded rectangle with:
const myCornerRadius = 2
const myRectSize = new THREE.Vector2(10,20)

myDynamicVerts.forEach((vertex,vertexIndex)=>{
  const quadrant = myDirs[ Math.floor( vertexIndex / vertNumPerCorner ) ]
  vertex.copy(myVerts[vertexIndex])
  vertex.multiplyScalar(myCornerRadius)
  vertex.x += quadrant.x * (myRectSize.x / 2 - myCornerRadius)
  vertex.y += quadrant.y * (myRectSize.y / 2 - myCornerRadius)
})

I believe that this should arrange the vertices in a desired shape.

3 Likes

@prisoner849
Nice example, thanks! I did use raycaster too, but I did it slightly differently. I also see a number of neat tricks in your example -an opportunity to expand my knowledge and methodology.
Still, I’d prefer a simple change vs a full reconstruction if it can be done easily.

@Fyrestar

It’s different if the geometry is actually a buffer and getting reused, but this isn’t designed this way internally by THREE.

Really? That’s pitty. Well, I’ll have to do such things on my own -I have spent a year to implement things not included and resolve issues anyway (incl. the time and effort required for the steep learning curve, but I still have a lot to learn and do).
BTW, nothing can surpass the beauty of optimization, it can make all the difference. High-optimization (for speed, efficiency, usability) is a must in order for our 3D websites to be embraced by the public and succeed -and optimization can also be addicting. :slightly_smiling_face:

edit: i think he means an actual 2D rounded rectangle though

Correct, I did mention “rounded rectangle”, not rounded box.

@pailhead

If it’s 2d, this could easily be done with something like this

That’s a different approach, I’ll study this and see what I can do, thanks!