# Adding functionality to make individual anchor points of bezier continuous or non-continuous

I am creating bezier curves with the following code. The curves can be extended to join several bezier curves by shift clicking in the scene view. My code has functionality for making the whole curve continuous or non-continuous. I realised that I need to make individual points (specifically anchor points) have this functionality.

I believe the most ideal way to go about this is creating a new class for the points with this functionality (making points continuous or non-continuous) since this can be used to add other properties that might be specific to the points. How can do this?

Path

[System.Serializable]
public class Path {

[SerializeField, HideInInspector]
List<Vector2> points;

[SerializeField, HideInInspector]
public bool isContinuous;

public Path(Vector2 centre)
{
points = new List<Vector2>
{
centre+Vector2.left,
centre+(Vector2.left+Vector2.up)*.5f,
centre + (Vector2.right+Vector2.down)*.5f,
centre + Vector2.right
};
}

public Vector2 this[int i]
{
get
{
return points[i];
}
}

public int NumPoints
{
get
{
return points.Count;
}
}

public int NumSegments
{
get
{
return (points.Count - 4) / 3 + 1;
}
}

public void AddSegment(Vector2 anchorPos)
{
points.Add(points[points.Count - 1] * 2 - points[points.Count - 2]);
points.Add((points[points.Count - 1] + anchorPos) * .5f);
points.Add(anchorPos);
}

public Vector2[] GetPointsInSegment(int i)
{
return new Vector2[] { points[i * 3], points[i * 3 + 1], points[i * 3 + 2], points[i * 3 + 3] };
}

public void MovePoint(int i, Vector2 pos)
{

if (isContinuous)
{

Vector2 deltaMove = pos - points[i];
points[i] = pos;

if (i % 3 == 0)
{
if (i + 1 < points.Count)
{
points[i + 1] += deltaMove;
}
if (i - 1 >= 0)
{
points[i - 1] += deltaMove;
}
}
else
{
bool nextPointIsAnchor = (i + 1) % 3 == 0;
int correspondingControlIndex = (nextPointIsAnchor) ? i + 2 : i - 2;
int anchorIndex = (nextPointIsAnchor) ? i + 1 : i - 1;

if (correspondingControlIndex >= 0 && correspondingControlIndex < points.Count)
{
float dst = (points[anchorIndex] - points[correspondingControlIndex]).magnitude;
Vector2 dir = (points[anchorIndex] - pos).normalized;
points[correspondingControlIndex] = points[anchorIndex] + dir * dst;
}
}
}
}

else {
points[i] = pos;
}
}


PathCreator

public class PathCreator : MonoBehaviour {

[HideInInspector]
public Path path;

public void CreatePath()
{
path = new Path(transform.position);
}
}


PathEditor

[CustomEditor(typeof(PathCreator))]
public class PathEditor : Editor {

PathCreator creator;
Path path;

public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUI.BeginChangeCheck();

bool continuousControlPoints = GUILayout.Toggle(path.isContinuous, "Set Continuous Control Points");
if (continuousControlPoints != path.isContinuous)
{
Undo.RecordObject(creator, "Toggle set continuous controls");
path.isContinuous = continuousControlPoints;
}

if (EditorGUI.EndChangeCheck())
{
SceneView.RepaintAll();
}
}

void OnSceneGUI()
{
Input();
Draw();
}

void Input()
{
Event guiEvent = Event.current;
Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin;

if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift)
{
Undo.RecordObject(creator, "Add segment");
path.AddSegment(mousePos);
}
}

void Draw()
{

for (int i = 0; i < path.NumSegments; i++)
{
Vector2[] points = path.GetPointsInSegment(i);
Handles.color = Color.black;
Handles.DrawLine(points, points);
Handles.DrawLine(points, points);
Handles.DrawBezier(points, points, points, points, Color.green, null, 2);
}

Handles.color = Color.red;
for (int i = 0; i < path.NumPoints; i++)
{
Vector2 newPos = Handles.FreeMoveHandle(path[i], Quaternion.identity, .1f, Vector2.zero, Handles.CylinderHandleCap);
if (path[i] != newPos)
{
Undo.RecordObject(creator, "Move point");
path.MovePoint(i, newPos);
}
}
}

void OnEnable()
{
creator = (PathCreator)target;
if (creator.path == null)
{
creator.CreatePath();
}
path = creator.path;
}
}


## 1 Answer

If you want control over whether individual points are continuous or not you could replace your bool isContinuous in your Path class with a List<bool>. Each element in the list would store whether or not the corresponding point in your points list is continuous.

• That would work, but it doesn't seem like an efficient way. Also, I will definitely be adding more functionality apart from continuity. – SuperHyperMegaSomething Jun 19 '18 at 12:00
• @Super So make each point its own class or struct. Then you can extend the functionality however you want. – S. Tarık Çetin Jul 23 '18 at 5:12
• @SuperHyperMegaSomething in what way are you expecting to get more efficient than storing a single bool per control point? That looks pretty darn minimal, if you have two states to distinguish for each of them... – DMGregory Aug 27 '18 at 3:36