Search Unity

Help drawing a circle which follows a curve, please!!

Discussion in 'Scripting' started by ytrew, Mar 10, 2017.

  1. ytrew

    ytrew

    Joined:
    Feb 22, 2013
    Posts:
    20
    Okay, so I have created a curved path and store points at an arbitrary interval along the path. At each point, I run the code below to generate a circle around said point The circles are drawn correctly on the x/y axis, but no not take into account the z and changes along the curve.

    Code (CSharp):
    1.  
    2. Theta = 0f;
    3. Size = (int)((1f / ThetaScale) + 1f);
    4. for (int i = 0; i < Size; i++)
    5. {
    6.     Theta += (2.0f * Mathf.PI * ThetaScale);
    7.     float x = PathPointArray[j].x + radius * Mathf.Cos(Theta);
    8.     float y = PathPointArray[j].y + radius * Mathf.Sin(Theta);
    9.     float z = PathPointArray[j].z;
    10.  
    11.     nodes.Add(new Vector3(x, y, z));
    12. }
    13.  
    As you can see below, the problem I am having is that the circles do not match the orientation/direction of the curve to accommodate for the z values:

    Any help is much appreciated. axis-1.PNG axis-2.PNG axis-3.PNG
     
  2. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    first you need the three points current, previous, and next point. calculate the directions of current->next and previous->current and then average those two together. this averaged direction is the look direction the circle needs to be. if working on the first or last point then its only one direction so theres no averaging needed.

    Code (CSharp):
    1. Vector3 direction = Vector3.forward; //default to forward incase theres not enough points
    2. Vector3 center = PathPointArray[j];
    3.  
    4.  
    5. if(j>0)
    6. {
    7.     Vector3 previous= PathPointArray[j-1];
    8.     direction = (center - previous);
    9. }
    10. if(j<PathPointArray.length-2)
    11. {
    12.     Vector3 next= PathPointArray[j+1];
    13.     direction +=  (next - center);
    14. }
    15. direction .Normalize();
    16. Quaternion facingDirection = Quaternion.LookRotation(direction,direction);
    17.  

    I'm assuming that each circle is a node made up of multiple vector3 points. And they are offset from the point in PathPointArray that serves as the centerpoint of each circle. Thus you need to add the center point, plus use the facingDirection to rotate offset location of the circle point before adding it to the center point

    Code (CSharp):
    1. for (int i = 0; i < Size; i++)
    2. {
    3.     Theta += (2.0f * Mathf.PI * ThetaScale);
    4.  
    5.     Vector3 offsetPoint = new Vector3( Mathf.Cos(Theta),Mathf.Sin(Theta),0 ) * radius;
    6. //Quaternion * Vector3 is a special operation that rotates a point around its origin by an angle of the Quaternion.
    7. // in otherwords we orient the offset in local space then add it to the centerpoint which is in world space
    8.     nodes.Add(center + facingDirection *  offsetPoint );
    9. }
     
    Last edited: Mar 10, 2017
    ytrew likes this.
  3. ytrew

    ytrew

    Joined:
    Feb 22, 2013
    Posts:
    20
    You sir are amazing! Thank you, I really appreciate the time you took to explain the solution you provided...and well the fact that it worked like a charm.

    3.PNG
    1.PNG 2.PNG
     
  4. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    no problem. It just helped that I've done procedural meshes recently and generating rope-like meshes has very similar code to what you've posted.