- Home /
how to position vertices around a center vertex?
I am creating a bezier tube as meshes. Have created a center line which is the bezier curve. Now, I want to position some vertices around the center line's vertices to create a tube.You can look at the images below
My code to place the vertices is:
for (int k = 0, l = 0; k < nbCentVerts; k++, l += nbSideVerts) //the loop for creating side vertices
{
for (int j = 0; j < nbSideVerts; j++)
{
vertices[nbCentVerts + j + l] = vertices[k] + new Vector3(Mathf.Sin(j * angle), Mathf.Sin(j * angle), Mathf.Cos(j * angle)) * 0.1f;
}
}
Now the problem is the side vertices are not in a perpendicular plane to the center curve. You can see from the picture that at some points the side vertices touched the center curve. Some suggested me to use vector3.cross to find out the perpendicular and I did. But how would I place my vertices along that direction/plane?? Or, if anyone have any other solution then please help me. Thanks in advance.
Answer by Bunny83 · Aug 15, 2015 at 08:55 AM
A circle is a 2d construct. It exists within a 2d plane. This plane doesn't need to be parallel to a worldspace plane. The easiest way is, like mentioned in the article of @cjdev , to calculate two perpendicular unit vectors for each point on the curve. Those vectors define a 2d plane where your circle will be located.
Step by step i would do:
Take the first 3 points of your curve and construct two direction vectors out of them.
Calculate the cross product of those two directions and normalize the result to get our first unit vector "a". (*note1)
to get the second vector "b" just calculate the cross product again with the first direction vector of your curve and "a".
Now we have "a" and "b" and can calculate the circle within that plane (*note2)
(*note1): There's a special case when your curve doesn't "curve" at all (so it represents a line). In that case the cross product will return a vector with a length close to or equal to (0,0,0). In that case you need to try a different reference vector (like world up, world forward or world right).
(*note2): To calculate the actual vertices you just do this:
for (int j = 0; j < nbSideVerts; j++)
{
vertices[nbCentVerts + j + l] = vertices[k] + (Mathf.Sin(j * angle) * a + Mathf.Cos(j * angle) * b ) * 0.1f;
}
To get a more continous orientation you might want to calculate the "a" and "b" vectors for the next point from the directions of the old "a" and "b" which were used by the previous point. This is important to have the rings around each point rotated the same way, otherwise you'll have a hard time connecting the rings appropriately.
Vector3 d; // direction from the previous point to the current point on the curve.
Vector3 a; // old "a"
Vector3 b; // old "b"
a = Vector3.Cross(b, d).normalized; // new "a"
b = Vector3.Cross(d, a).normalized; // new "b"
Keep in mind that Unity uses a left-handed system. So the crossproduct uses the left-hand-rule (first vector == thumb, second vector == index finger, result == middle finger).
Answer by cjdev · Aug 15, 2015 at 07:18 AM
As it stands you're just making a circle of points around each vertex without accounting for the curve. To take the curve's direction into account you'd need to use a parametric equation with the axis being the vector pointing towards your next point in the curve. This answer has an explanation on the technique used for this process.
Your answer
Follow this Question
Related Questions
Alternative Ways of Finding Vertices 2 Answers
mask one gameObject mesh by another mesh vertex transparency 1 Answer
Mirror vertices procedurally 2 Answers