Circular motion via the mathematical circle equation?

I’m looking for a way to create a circular motion for an object. I got the linear and wave (sin) motions working fine. I pretty much know their equations, and they’re actual functions (for each point of the graph in x, there’s one and only one corresponding point in y - which is the definition of a function) - But the circle isn’t a function, since foreach point in the graph, there are two corresponding y values.

From my dusty math knowledge, the equation of the circle is:

x^2 + y^2 = r;

How to get this formula to work in code?

What I have is, an abstract Movement class, that other types of movements inherit from, and override the method GetY - so LinearMovement’s GetY just returns the the y value of the velocity, etc. Here’s the virtual moving method in the abstract Movement

protected virtual void Move()
	velocity.y = GetY();
	cachedTransform.localPosition += (velocity + direction) * Time.deltaTime * speed;
        // more unrelated stuff

GetY for the sine movement:

protected override float GetY()
	return Mathf.Sin(2 * Mathf.PI * Time.time * frequency) * wavelength;

GetY for the linear movement:

protected override float GetY()
	return velocity.y;

Now, what I tried to do for my circular movement, is return:

sqrt(r - x * x);

But it didn’t give me the right movement.

Please don’t give answers related to any of the rotation methods (transform.Rotate, transform.RotateAround, etc) - cause that’s not the point of this question.

Thanks for any tips.


if you’re curious where I get direction from:

protected virtual void InitDirection()
	// just get some random orientation for the point/object to face to start moving
	float randZ = Random.Range(minInitialOrientation, maxInitialOrientation);
	direction = Quaternion.Euler(0, 0, randZ) * cachedTransform.right;

I understand now, what you need to use an angle and a radius to calculate the position. you need to increase/decrease the angle every frame, and then calculate the position using these formulas:



for example:

float angle =0;
float speed=(2*Mathf.PI)/5 //2*PI in degress is 360, so you get 5 seconds to complete a circle
float radius=5;
void Update()
	angle += speed*Time.deltaTime; //if you want to switch direction, use -= instead of +=
	x = Mathf.Cos(angle)*radius;
	y = Mathf.Sin(angle)*radius;

I didn’t tested it, but change it to fit your values and it should work.
oh and btw, this is for the center (0,0). if you want the circle center to (a,b) you need to change the formulas to:



Note: I’m not entirely sure I understand the question so if this is off topic please take it with a grain of salt.

Your sin function is generating a Y value as a function of time i.e.:

y =  Mathf.Sin(2 * Mathf.PI * Time.time * frequency) * wavelength

This is also the y position for a point moving in a circle of a radius equal to wavelength at the given frequency.

The equivalent cos function will return the x position given the same parameters i.e.:

x =  Mathf.Cos(2 * Mathf.PI * Time.time * frequency) * wavelength

You were mentioning that a circle is not a capital-F Function due to having two y values for a given x.
While this is true, the y values for a given x can be found by the following:

y =  (+/-) sqrt(r*r - x*x)

Or the x values for a given y:

x =  (+/-) sqrt(r*r - y*y)

The easiest way to implement circular motion in unity would be to create an empty object in the circle center, then make your object a child of that empty object, then rotate the parent empty object every frame, which will cause your object to rotate around it since it’s a child object.

If you want to calculate the motion manually, you can use the physics of circular motion. You can read the formulas here.

Now, to implement it, you could give your object a rigidbody, and then set the velocity to be 90 degrees from the radius (the vector connecting your location and the center. Then, each frame, as the physics engine moves your object according to the velocity, you apply an acceleration towards the center of the circle equal to v^2 / R, where v is the magnitude of rigidbody.velocity, and R is the magnitude of the radius vector.

void ApplyCircularAcceleration(Vector3 center) {
    vector3 toCenter = center - transform.position;
    rigidbody.velocity += toCenter.normalized * rigidbody.velocity.sqrMagnitude / toCenter.magnitude;

if you don’t want to use rigidbody, you could keep your own velocity vector, and move the object each frame according to that velocity.

Glad you found an answer already.

Another thing worth looking into is a “spherical interpolation”, or “slerp” . Unity includes it for use with circular motion and curves.