In order to achieve the desired outcome, it is essential to divide your mesh into slices and convert each slice in a similar manner as demonstrated in the following example:
- Smoothly connecting circle centers
Here is an overview of how this process can be accomplished:
Establish a straight coordinate system
Begin by creating a position P0
and three basis vectors X0, Y0, Z0
representing the coordinates of the mesh in a straight form. Let's assume that the axis you intend to bend along is Z0
.
https://i.sstatic.net/9suBC.png
Convert each vertex into local coordinates
This involves transforming any point P
using the formula:
P.x' = dot( P-P0 , X0 )
P.y' = dot( P-P0 , Y0 )
P.z' = dot( P-P0 , Z0 )
Create a coordinate system for bending
Based on the value of P.z'
(which serves as a parameter indicating arclength), calculate the angle of the bended arc and rotate the vectors X0, Y0, Z0
to obtain new vectors X1, Y1, Z1
. If the bending is around the X
axis, X1 = X0
remains unchanged, while the other two vectors need to be rotated.
https://i.sstatic.net/kI4wh.png
Convert vertices into the bended form
To achieve this transformation, apply the following calculations:
P'' = P1 + P.x'*X1 + P.y'*Y1
Now, P''
represents the final vertex of your shape. Once all points have been converted, you can proceed with rendering the mesh. Notably, there is no necessity to calculate the Z1
basis vector - its information has already been encoded within the P1
position.
[Notes]
Be cautious about excessively large bends, as they can potentially distort your mesh topology. Over-bending may lead to self-intersections between the various slices.
All corresponding basis vectors should ideally have the same size, preferably unit length.
The rotation from Y0 -> Y1
is essentially a simple 2D problem. In cases where Y0=(0,1,0)
, the task simplifies even further given that the circle pointer would be at Y1=(cos(a),sin(a),0)
. No complex 2D rotation formulas are needed in such instances.
[Edit1] C++/GL Example
Curious to explore further, I took a generated tube featuring a sinus screw and implemented a bend. Here is the resulting visualization:
https://i.sstatic.net/NcKPl.gif
I rendered both the straight and bended meshes to allow for easy visual comparison. The red point signifies the bend center, connected through a line to P0
. For alignment purposes, I selected P0,X0,Y0,Z0
to align with the unit matrix. Consequently, the example was transformed in a way that corresponds to the images provided here (in an un-animated state). Below is the C++/GL code used:
The mesh and bending file, zavit.h:
//---------------------------------------------------------------------------
//--- tube with sinus screw -------------------------------------------------
//----------------------
const int ca=20;
const int cb=50;
const float r0=0.3;
const float r1=0.35;
const float l1=2.0;
const float nz=5.0;
vec3 pnt0[ca][cb];
vec3 nor0[ca][cb];
vec2 txr0[ca][cb];
//---------------------------------------------------------------------------
vec3 pnt1[ca][cb];
vec3 nor1[ca][cb];
vec2 txr1[ca][cb];
//---------------------------------------------------------------------------
/*Remaining content omitted for brevity*/
//---------------------------------------------------------------------------
For optimal compatibility and accuracy, ensure accurate correspondence with the specified axes, angles, and coordinate transformations. Through meticulous attention to detail, you can effectively execute the process of slicing and converting meshes with precision and efficiency.