# Drawing an Arc from point to point

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.

``````float radAngle = angle * (Mathf.PI / 180);

List<Vector3> points = new List<Vector3>();
Vector3 initialDirection = (endLoc - startLoc).normalized;
Vector3 maxOutDirection = Vector3.RotateTowards(initialDirection, outDirection, radAngle, 0);

Vector3 maxInDirection = Vector3.RotateTowards(initialDirection, outDirection * -1, radAngle, 0);

Vector3 currentDirection = maxOutDirection;

float tChange = linePoints-1;
tChange /= (linePoints-1) * (linePoints-1);

for (int index = 1; index <= linePoints; index++)
{
currentDirection = Vector3.Lerp(maxOutDirection, maxInDirection, (index*tChange));
}

lineRenderer.positionCount = points.Count;
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

.

I only put 5 points in the picture but I would like the ability to have a variable number of points in the script.

Heres a thread from 7 years ago where I posted some code for getting points on a parabola

Doesnt take an angle, instead takes the height of the peak of parabola. Might B helpful

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.

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.

“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.

Basically, this is what I have

and this is what I need

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.

``````Vector3 SampleParabola(Vector3 start, Vector3 end, float height, float t)
{
float parabolicT = t * 2 - 1;
if (Mathf.Abs(start.y - end.y) < 0.1f)
{
//start and end are roughly level, pretend they are - simpler solution with less steps
Vector3 travelDirection = end - start;
Vector3 result = start + t * travelDirection;
result.y += (-parabolicT * parabolicT + 1) * height;
return result;
}
else
{
//start and end are not level, gets more complicated
Vector3 travelDirection = end - start;
Vector3 levelDirecteion = end - new Vector3(start.x, end.y, start.z);
Vector3 right = Vector3.Cross(travelDirection, levelDirecteion);
Vector3 up = Vector3.Cross(right, travelDirection);
if (end.y > start.y) up = -up;
Vector3 result = start + t * travelDirection;
result += ((-parabolicT * parabolicT + 1) * height) * up.normalized;
return result;
}
}
``````

I’m sorry if I’m not being helpful.

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

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.

``````Vector3 SampleParabola(Vector3 start, Vector3 end, float height, float t, Vector3 outDirection)
{
float parabolicT = t * 2 - 1;
//start and end are not level, gets more complicated
Vector3 travelDirection = end - start;
Vector3 levelDirection = end - new Vector3(start.x, end.y, start.z);
Vector3 right = Vector3.Cross(travelDirection, levelDirection);
Vector3 up = outDirection;
Vector3 result = start + t * travelDirection;
result += ((-parabolicT * parabolicT + 1) * height) * up.normalized;
return result;
}
``````
10 Likes

hello, sorry to disrupt you but what is t in the formul?

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.