Search code examples
unity-game-enginemathgeometryderivative

getting tangent vectors for circle equation points


i'm trying to get the tangent vector for each point on the circle , i tried to use the derivative for the circle equation, but the result looks off in the viewport, so i'm wondering if i can find some help here

the code

public void OnDrawGizmos(){
    step = (360.0f * Mathf.Deg2Rad) / numberOfPoints ;
    CreateVertices();
}


void CreateVertices()
{

    Points.Clear();
    Normals.Clear();
    Tangents.Clear();

    float dynamicAngle = 0.0f;
    for (int i = 0; i <= numberOfPoints; i++)
    {
        Vector3 point;
        point.x = transform.position.x + Radius * Mathf.Cos(dynamicAngle);
        point.y = transform.position.y + Radius * Mathf.Sin(dynamicAngle);
        point.z = transform.position.z;


        dynamicAngle = dynamicAngle + step;
        if (i >= 1)
        {
            Gizmos.color = Color.red;
            Gizmos.DrawLine(Points[i - 1], point);
            Gizmos.color = Color.white;
        }
        Points.Add(point);
        CalculateNormals(dynamicAngle ,point);
        CalculateTangents(dynamicAngle,i  , point);

    }

}

void CalculateNormals(float dynamicAngle , Vector3 point)
{
    Vector3 Normal = (point - transform.position).normalized;

    Gizmos.color = Color.magenta;
    Gizmos.DrawLine(Normal, point);
    Gizmos.color = Color.white;

    Normals.Add(Normal);

}

void CalculateTangents(float dynamicAngle,int i  ,Vector3 point)
{
    Vector3 tangent;

      tangent = new Vector3(-Normals[i].y, Normals[i].x, 0);
      tangent.Normalize();

    Gizmos.color = Color.blue;
    Gizmos.DrawLine(  point, tangent);
    Gizmos.color = Color.white;

    Tangents.Add(tangent);
}

Blue is the tangents purple is the normals, as you can see they are not perpendicular:

img

To understand my issue better here is a gif from unity viewport:

img


Solution

  • Since you already calculated the normals you can use the cross product to get the corresponding tangents

    Vector3 up = new Vector3(0, 0, 1); // up side of your circle
    Vector3 tangent = Vector3.Cross(normal, up);
    

    If you only need to use circles on a specific plane you can also use this simplification

    Vector3 tangent = new Vector3(-normal.y, normal.x, 0);
    

    Edit:

    The normals and tangents are direction vectors. They point from point in the direction the normal / tangent whould point. To draw the tangent, you have to pass the correct start and end points of the line by using

    Gizmos.DrawLine(point, point + tangent);
    

    If you move the GameObject away from the origin you will notice that the normals also get deformed, this has the same reason.