# How to make a circle orbit a touch point

How do I make a circle/ellipse orbit in a circle around a touch point?

Here’s a simple way

``````function setup()
spritedist = 120
spritesize = 30
ellsize = 30
ellipseloc = vec2(WIDTH/2,HEIGHT/2)
spriteloc = ellipseloc+vec2(0,spritedist)
tid = nil
col = color(0,0,255)
end
function draw()
background(40, 40, 50)
fill(255,0,0)
ellipse(ellipseloc.x,ellipseloc.y,ellsize)
fill(col)
ellipse(spriteloc.x,spriteloc.y,spritesize)
end
function touched(t)
if spriteloc:dist(vec2(t.x,t.y)) < spritesize/2+5 and t.state == BEGAN then
tid = t.id
col = color(0,255,0)
elseif t.state == MOVING and t.id == tid then
local ang = math.atan2(t.y-ellipseloc.y,t.x-ellipseloc.x)
spriteloc = vec2(0,spritedist):rotate(ang-(math.pi/2))+ellipseloc
elseif t.state == ENDED and t.id == tid then
tid = nil
col = color(0,0,255)
end
end
``````

EDIT: I reread your question and think that my original post is not what you want. Please hold while I slap myself and write another

Here, I THINK this is what you actually meant. Correct me if I’m wrong and I’ll go try again ``````function setup()
print("Hello World!")
lasso = nil
oid = nil
lassolength = nil
shiploc = vec2(WIDTH/2,HEIGHT/2)
simpveloc = 3
shipVelocity = vec2(simpveloc,0)
ctype = 1 --(change to 0 for orbit to change with finger moving)
end
function draw()
background(255)
clacloc()
fill(0,0,255)
ellipse(shiploc.x,shiploc.y,30)
if lasso then
ellipse(lasso.x,lasso.y,10)
end
end
function touched(t)
if t.state == BEGAN and not oid then
oid = t.id
initlasso(t)
end
if t.state == MOVING and oid == t.id then
if ctype == 0 then
initlasso(t)
end
end
if t.state == ENDED and oid == t.id then
end
end
function initlasso(t)
lassolength = vec2(t.x,t.y):dist(shiploc)
lasso = vec2(t.x,t.y)
local circumf = 2*math.pi*lassolength
local offset = lasso - shiploc
local anglebet = math.atan2(offset.y,offset.x)
local tangent = anglebet - (math.pi/2)
if (anglerad - anglebet)%(2*math.pi) > math.pi then
else
anglerad = tangent + math.pi
end
end
function clacloc()
if lasso ~= nil then
end
if lasso ~= nil then
shiploc = lasso + (shiploc - lasso):rotate(angleaddrad)
else
shiploc = shipVelocity:rotate(anglerad) + shiploc
end
end
``````

@Monkeyman32123, no need for such complex code. All you need is a little trigonometry @Acithium, here is a much shorter / easier way of doing it:

``````-- Orbit

function setup()
orbitCenter = vec2(WIDTH / 2, HEIGHT / 2)
orbitRad = WIDTH / 8
orbitAngle = 0
angleIncrement = .1
end

function draw()
background(40, 40, 50)

fill(255, 251, 0, 255) noStroke()
ellipse(orbitCenter.x, orbitCenter.y, 10)

fill(255, 0, 0, 255)
local outX = orbitCenter.x + orbitRad * math.cos(orbitAngle)
local outY = orbitCenter.y + orbitRad * math.sin(orbitAngle)
ellipse(outX, outY, 35)

orbitAngle = orbitAngle + angleIncrement
end

function touched(t)
orbitCenter = vec2(t.x, t.y)
end
``````

@JakAttak You could also use vec2.rotate, which might be a bit less confusing than trigonometry.

``````-- Orbit

-- Use this function to perform your initial setup
function setup()
print("Hello World!")
center = vec2(0, 0)
offset = vec2(100, 0)
end

-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)

-- This sets the line thickness
strokeWidth(5)

-- Do your drawing here
ellipse(center.x + offset.x, center.y + offset.y, 50)
offset = offset:rotate(DeltaTime * 5)
end

function touched(touch)
center.x, center.y = touch.x, touch.y
end

``````

@SkyTheCoder, nice, I didn’t know about that.

@JakAttak
I realize there are easier ways to do rotation around a point (and I often use them myself), but the reason I made mine so complex is because he said an orbit, which, to me at least, makes me think of a gravitational pull. Therefore, I made mine so that the circle would orbit clockwise or counter-clockwise around the touch depending on the origin of the touch point (hence the seemingly needless complexity). Of course, it’d be much simpler to make it rotate in one direction only, but I wasn’t sure what he wanted so I gave what I wanted when I asked this very same question so long ago @Monkeyman32123, Well even to be able to rotate clockwise / counter-clockwise depending in the touch, I would only need to add 2/3 lines.

Oh, my apologies then dear sir. Well, in that case go tell @Andrew_Stacey you’ve found a better way, as he is the one who helped me make it go clockwise and counter-clockwise (and, knowing him, he’d love a way to increase his vast library of general knowledge). But I don’t want to go tell him, his dominating intelligence in the subject of Maths intimidates me. ._.

@Monkeyman32123, LOL. If you wanted to add rotation going both directions, you take my (or @SkyTheCoder’s code) and you add a variable for the direction to turn (1 or -1) which you multiply by the angleIncrement in my code, or the rotation amount in his code.

Then you just need the code in touched function to determine whether that variable should be 1 or -1

@JakAttak if you actually analyse @Monkeyman32123’s code then you’d see that the bit that draws the orbiting ellipse is essentially the same as yours and @SkyTheCoder’s so less of the “it’s pretty simple really” language, please! The extra length in Monkeyman32123’s code is in figuring out what happens if you a) move the touch and b) stop touching and retouch somewhere else. Yours and SkyTheCoder’s code is a bit simplistic there and will simply move the orbiter and maintain the same direction. Monkeyman32123’s ensures that the orbiter moves in a reasonably natural path.

It’s true that this probably is more complicated than @Acithium wants, but unless (s)he explains further then it’s hard to know.

@Andrew_Stacey, you are right I see he is using the rotate function as well Here’s a version that allows multiple orbits. The center is the beginning touch point and the radius is the ending touch point. Also, the orbit speed is determined by the radius size. Keep creating multiple orbits, at least 100.

EDIT: added orbit count

``````
displayMode(FULLSCREEN)

function setup()
tab={}
mov=false
dir=1
end

function draw()
background(40, 40, 50)
fill(255)
text("tap for center and drag for radius size",WIDTH/2,HEIGHT-50)
text("number of orbits  "..#tab,WIDTH/2,HEIGHT-100)
if mov then
stroke(255)
strokeWidth(2)
line(cx,cy,mx,my)
end
for a,b in pairs(tab) do
b:draw()
end
end

function touched(t)
if t.state==BEGAN then
cx=t.x
cy=t.y
end
if t.state==MOVING then
mov=true
mx=t.x
my=t.y
end
if t.state==ENDED then
dir=dir*-1
mov=false
v1=vec2(cx,cy)
ang=math.atan2(t.y-cy,t.x-cx)
end
end

orb=class()

self.cx=cx
self.cy=cy
self.ang=ang
self.col=color(math.random(255),math.random(255),math.random(255))
end

function orb:draw()
fill(self.col)
stroke(self.col)
strokeWidth(2)
ellipse(self.cx,self.cy,5)
ellipse(self.x,self.y,20)
line(self.cx,self.cy,self.x,self.y)
self.ang=self.ang+self.inc
end

``````

Here, here’s a version where I took the question far too literally

``````displayMode(OVERLAY)
displayMode(FULLSCREEN)
backingMode(RETAINED)
function setup()
mpp = 2000000
gravity = false
g = 6.674*(1/(10^11))
planets = {}
planets[#planets+1]=Planet(vec2(WIDTH/2,HEIGHT/2),5.97219*(10^25))
planets[#planets+1]=Planet(vec2(WIDTH/2,HEIGHT/2+(384400000/mpp)),7.34767309*(10^22),1737.4,vec2(.8*2,0))
for i=1, 30 do
--planets[i] = Planet(nil, math.random(0,1000)*(10^23))
end
alive = true
oid = nil
end
function draw()
if alive then
background(255)
end
if alive then
for i=1,#planets do
planets[i]:gravcal()
end
for i=1,#planets do
planets[i]:draw()
end
else
restart()
end
if alive then
local count = 0
for i=1, #planets do
if not planets[i].alive then
count = count + 1
end
end
if count == #planets then
alive = false
end
end
end
function touched(t)
if alive then
if t.state == BEGAN and planets.locv:dist(vec2(t.x,t.y)) < 22 and not oid then
oid = t.id
elseif oid == t.id then
planets.locv = vec2(t.x,t.y)
if t.state == ENDED then
oid = nil
if math.sqrt(t.deltaX^2+t.deltaY^2)>3 then
planets.vel = vec2(t.deltaX,t.deltaY)
else
planets.vel = vec2(0,0)
end
end
end
end
end
Planet = class()
self.locv = loc or vec2(math.random(0,WIDTH),math.random(0,HEIGHT))
self.mass = kg or 5.97219*(10^24)
self.vel = vel or vec2(0,0)
self.alive = true
end
function Planet:draw()
if self.alive then
self.locv = self.locv + self.vel
fill(0)
end
end
function Planet:gravcal()
for i=1, #planets do
if planets[i].alive and self.alive then
if self.locv ~= planets[i].locv then
local f=(g*self.mass*planets[i].mass)/((self.locv:dist(planets[i].locv)*mpp)^2)
local a=vec2(f/self.mass,0)
local offsx = planets[i].locv.x-self.locv.x
local offsy = planets[i].locv.y-self.locv.y
local ang = math.atan2(offsy,offsx)
self.vel = self.vel + a:rotate(ang)
if planets[i].locv:dist(self.locv) < 11 then
self.alive = false
planets[i].alive = false
return
end
end
end
end
end
``````

im seriously behind on math…

@Monkeyman32123 - Thanks for the code snippets. I was working on faux-planetary orbits, and your code really helped out. I’m with @Weisdendarm - seriously behind on math.

@athros thanks, glad I could help! I just learned about calculating planetary orbit radii, orbit velocities, orbit periods, and gravitational accelerations in my physics class and decided to make a little mini-solar-system out of it, and so the code was born.
And it’s ok, I’m seriously behind on math too. If it weren’t for Andrew_stacey I’d still be trying to figure out angles to this very day

@Monkeyman32123 Do a forum search for orbits. There are several programs that already do orbit calculations. Maybe those will help out.

@dave1707 but…what’s wrong with mine :c

@Monkeyman32123 - I have a friend who asked me for a game (something like Conquest: Frontier Wars with some realistic system movement, or Aurora) and I’ve been exploring it with Codea.