Skip to content

Instantly share code, notes, and snippets.

@niksg
Last active December 20, 2015 15:28
Show Gist options
  • Save niksg/6153815 to your computer and use it in GitHub Desktop.
Save niksg/6153815 to your computer and use it in GitHub Desktop.
Have you ever dreamed of rotating points around other points by amounts? Have you also or instead dreamt of drawing a smooth curve between two points the l̶a̶z̶y̶ lazy way? Do you use Unity3D with C#? Then boy do I have a deal for you
using UnityEngine;
using System.Collections;
public class SmoothCurveDraw : MonoBehaviour {
public Vector2 curveStart;
public float curveAngle = 90;
public int smoothValue = 1;
public Color rayColor = Color.blue;
void Update() {
//clamp between zero and 180 because Vector2.Angle doesn't return anything above 180
//getting around this using a third vector is messy and weird but possible
curveAngle = Mathf.Clamp(curveAngle, 0, 180);
//draws a curve between the starting point you supply and the angle of the curve
//as rotated around a pivot point which you also supply
//by a smoothing value between 0 and 3 which you supply again
Vector2 endPos = rotatePointAroundPoint(curveStart, Vector2.zero, curveAngle);
//if smoothness is too high bad things happen
smoothValue = Mathf.Clamp(smoothValue, 0, 3);
//no smoothing is pretty straight so just do it here (0 is actually first level smoothing in the draw function below)
if (smoothValue == 0)
Debug.DrawRay(curveStart, endPos - curveStart, rayColor);
else
drawCurveBetweenPoints(curveStart, endPos, Vector2.zero, (float)smoothValue-1);
}
//this function draws the curve between two points and therefore is named aptly
void drawCurveBetweenPoints(Vector2 p1, Vector2 p2, Vector2 pivot, float smoothness) {
Vector2 midpoint = rotatePointAroundPoint(p1, pivot, Vector2.Angle(p1,p2)/2);
//the idea is splitting it in two every time, and it takes an int, so:
smoothness -= 0.5f;
//done smoothing
if (smoothness < 0) {
Debug.DrawRay(p1, midpoint-p1, rayColor);
Debug.DrawRay(midpoint, p2-midpoint, rayColor);
return;
}
//recursion is here
drawCurveBetweenPoints(p1, midpoint, pivot, smoothness);
drawCurveBetweenPoints(midpoint, p2, pivot, smoothness);
}
//rotates point p1 around a pivot point (p2) by a rotation angle
Vector2 rotatePointAroundPoint(Vector2 p1, Vector2 p2, float rotAngle) {
//math
rotAngle *= Mathf.Deg2Rad;
return new Vector2 ((Mathf.Cos(-rotAngle) * (p1.x - p2.x) +
Mathf.Sin(-rotAngle) * (p1.y - p2.y)) + p2.x,
(Mathf.Sin(-rotAngle) * (p2.x - p1.x) -
Mathf.Cos(-rotAngle) * (p2.y - p1.y)) + p2.y);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment