Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Drawing an Arc from point to point

Discussion in 'Scripting' started by Cronnoc, Nov 5, 2020.

  1. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    Hey guys, I've been trying to work this out for hours and I've now given up and am humbly asking for help. I am trying to write a function that will take two positions, an angle, and a direction. The function will then give me a list or array of points to input into a line renderer. These points will cause the line to form an arc that starts at the first position, ends at the last position, and arcs between them in the given direction by the given angle.

    Here is the code that I have been trying recently but it has failed me and is likely to be deleted.
    Code (CSharp):
    1. float radAngle = angle * (Mathf.PI / 180);
    2.  
    3.         List<Vector3> points = new List<Vector3>();
    4.         Vector3 initialDirection = (endLoc - startLoc).normalized;
    5.         Vector3 maxOutDirection = Vector3.RotateTowards(initialDirection, outDirection, radAngle, 0);
    6.  
    7.         Vector3 maxInDirection = Vector3.RotateTowards(initialDirection, outDirection * -1, radAngle, 0);
    8.  
    9.         Vector3 currentDirection = maxOutDirection;
    10.         points.Add(startLoc);
    11.  
    12.         float tChange = linePoints-1;
    13.         tChange /= (linePoints-1) * (linePoints-1);
    14.  
    15.         for (int index = 1; index <= linePoints; index++)
    16.         {
    17.             points.Add(points[index - 1] + (currentDirection/linePoints));
    18.             currentDirection = Vector3.Lerp(maxOutDirection, maxInDirection, (index*tChange));
    19.         }
    20.  
    21.         lineRenderer.positionCount = points.Count;
    22.         lineRenderer.SetPositions(points.ToArray());
    This code is not giving me the desired outcome and any help you could give me, whether fixing my script of providing me with another way of doing it, would be greatly appreciated.

    For reference, I have attached roughly what I want the line to look like arc.PNG .
     
  2. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    I only put 5 points in the picture but I would like the ability to have a variable number of points in the script.
     
  3. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
  4. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    Thank you very much, that isn't exactly what I need but it gives me an amazing start on it. I'll (hopefully) only need to make a few adjustments for it to do what I need.
     
  5. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    So, sorry for bumping, but I'm still struggling with this. The function that was provided by hpjohn (thank you) is amazing, and works if you always want the arc to point up, but as soon as I want the arc to point in another direction it fails. I need to be able to give the arc a direction, and then, it calculates it so that it arcs from the start point to the end point in the direction given.
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    "Arc" is a very generic term. A parabola forms an arc. Another type of arc is a bezier spline arc. Half of a circle is also an arc. Technically a straight line is an arc with zero curvature.

    This to me sounds like perhaps you are looking for either easing or tweening or perhaps a bezier spline. Google up for how to get that kinda action going. There are ready-made packages for each in the Unity asset store.
     
  7. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    Basically, this is what I have
    arc.PNG

    and this is what I need
    target arc.PNG

    The arc should always be the same in the sense that it could form a nice ellipsoid.

    I've had a look into numerous free bezier curve systems and I don't think they are what I need. They are either too complex, or simply unhelpful. I was hoping that someone could assist in modifying the below code (which generated the curve in the top picture) to allow me to face the arc in a direction that wasn't up.

    Code (CSharp):
    1.  
    2. Vector3 SampleParabola(Vector3 start, Vector3 end, float height, float t)
    3.     {
    4.         float parabolicT = t * 2 - 1;
    5.         if (Mathf.Abs(start.y - end.y) < 0.1f)
    6.         {
    7.             //start and end are roughly level, pretend they are - simpler solution with less steps
    8.             Vector3 travelDirection = end - start;
    9.             Vector3 result = start + t * travelDirection;
    10.             result.y += (-parabolicT * parabolicT + 1) * height;
    11.             return result;
    12.         }
    13.         else
    14.         {
    15.             //start and end are not level, gets more complicated
    16.             Vector3 travelDirection = end - start;
    17.             Vector3 levelDirecteion = end - new Vector3(start.x, end.y, start.z);
    18.             Vector3 right = Vector3.Cross(travelDirection, levelDirecteion);
    19.             Vector3 up = Vector3.Cross(right, travelDirection);
    20.             if (end.y > start.y) up = -up;
    21.             Vector3 result = start + t * travelDirection;
    22.             result += ((-parabolicT * parabolicT + 1) * height) * up.normalized;
    23.             return result;
    24.         }
    25.     }
    I'm sorry if I'm not being helpful.

    EDIT: if unclear, the above code was made by hpjohn
     
  8. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    So I feel really stupid now, but my problem has been resolved. I literally just needed to remove a few lines and it works.
    For anyone who might need it, this is the altered code.
    Code (CSharp):
    1.  
    2. Vector3 SampleParabola(Vector3 start, Vector3 end, float height, float t, Vector3 outDirection)
    3.     {
    4.         float parabolicT = t * 2 - 1;
    5.         //start and end are not level, gets more complicated
    6.         Vector3 travelDirection = end - start;
    7.         Vector3 levelDirection = end - new Vector3(start.x, end.y, start.z);
    8.         Vector3 right = Vector3.Cross(travelDirection, levelDirection);
    9.         Vector3 up = outDirection;
    10.         Vector3 result = start + t * travelDirection;
    11.         result += ((-parabolicT * parabolicT + 1) * height) * up.normalized;
    12.         return result;
    13.     }
     
    ahSOLO1, Firn7, kadir_yuksel and 5 others like this.
  9. Firn7

    Firn7

    Joined:
    Dec 11, 2021
    Posts:
    3
    hello, sorry to disrupt you but what is t in the formul?
     
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,531
    Just like in almost all other cases like in Lerp, the t value is simply a generic "time" value in the range 0 to 1 to indicate what point you're interested in. So 0 is the start, 1 is the end and 0.5f would be right in the middle of the arc. Any other value between 0 and 1 would map to the arc accordingly. So when you move t in small increments from 0 to 1 you would move along the arc, from start to the end.