# Line drawing: How can I interpolate between points to create a smooth arc?

I’m using the line renderer to create a line on screen based off user input. Think finger drawing.

The problem is that when a user draws too quickly, there isn’t enough fidelity captured per frame to create a smooth line - it looks jaggy. I have an array of x,y point values in Javascript.

I’d like to figure out a simple way to take my array and smooth it out before sending the values to the line renderer by interpolating between the points I have. Any ideas?

Here is an example array that I’m working with based off user input:

``````var user_touch_input = [(16.6, 7.4, 0.0),(15.5, 7.2, 0.0),(14.4, 7.1, 0.0),(13.5, 7.1, 0.0),(12.4, 7.7, 0.0)];
``````

Thanks to [this site][1], I was able to create the following script:

``````using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Curver : MonoBehaviour {
//arrayToCurve is original Vector3 array, smoothness is the number of interpolations.
public static Vector3[] MakeSmoothCurve(Vector3[] arrayToCurve,float smoothness){
List<Vector3> points;
List<Vector3> curvedPoints;
int pointsLength = 0;
int curvedLength = 0;

if(smoothness < 1.0f) smoothness = 1.0f;

pointsLength = arrayToCurve.Length;

curvedLength = (pointsLength*Mathf.RoundToInt(smoothness))-1;
curvedPoints = new List<Vector3>(curvedLength);

float t = 0.0f;
for(int pointInTimeOnCurve = 0;pointInTimeOnCurve < curvedLength+1;pointInTimeOnCurve++){
t = Mathf.InverseLerp(0,curvedLength,pointInTimeOnCurve);

points = new List<Vector3>(arrayToCurve);

for(int j = pointsLength-1; j > 0; j--){
for (int i = 0; i < j; i++){
points <em>= (1-t)*points _+ t*points[i+1];_</em>
``````

* }*
* }*

* }*

* return(curvedPoints.ToArray());*
* }*
}
To use this just call Curver.MakeSmoothCurve(theArrayYouWantToCurve,numberOfInterpolations). Example:
//javascript/unityscript example
#pragma strict
var points : Vector3[];

var lineRenderer : LineRenderer;
var c1 : Color = Color.yellow;
var c2 : Color = Color.red;

function Start () {
* points = Curver.MakeSmoothCurve(points,3.0);*

* lineRenderer.SetColors(c1, c2);*
* lineRenderer.SetWidth(0.5,0.5);*
* lineRenderer.SetVertexCount(points.Length);*
* var counter : int = 0;*
* for(var i : Vector3 in points){*
lineRenderer.SetPosition(counter, i);
* ++counter;*
}
}
Notes:
1. Place in a folder that will be compiled earlier than your scripts if you are using unityscript/javascript. A “Plugins” folder will probably work.
2. smoothness is rounded.
_*[1]: http://ibiblio.org/e-notes/Splines/Bezier.htm*_

There is a lot of spline algorithms and spline code on the net you could adapt. If you are looking for something easier, iTween comes with smoothed Path that you could use to calculate the positions for additional points. There are also packages at the Asset store. Vectrosity will handle both the smoothing and line drawing. I’ve never used it, but I’ve read some good things about SuperSplines.

Codetastic’s answer provides Bezier curves which don’t reach middle points. Using iTween.PointOnPath gives you Catmull-Rom spline which is better in some situations.

Am new to line renderer and is it possible I can use this code and assign to the device’s x y z motion to draw like a graph thing. @ensomniac. thanks in advance.