# Making an object follow another object - FAIL!

**URL:** <https://www.ruby-forum.com/t/making-an-object-follow-another-object-fail/129176>\
**Category:** Ruby\
**Created:** [February 15, 2008, 3:48am UTC](https://www.ruby-forum.com/t/making-an-object-follow-another-object-fail/129176 "2008-02-15T03:48:43Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![fuubi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e95f7d/32.png) [@fuubi](https://www.ruby-forum.com/u/fuubi)\
**Post date:** [February 15, 2008, 3:48am UTC](https://www.ruby-forum.com/t/making-an-object-follow-another-object-fail/129176/1 "2008-02-15T03:48:43Z")

</div>

First of all, I’m new to the forum (and to ruby) so hi everyone!

I’ve started playing around with Ruby, and I decided to see if I could  
do anything fun with the sdl extension library. I started by just  
putting a spinning object on the screen, and then worked out from there.  
I’ve built this program mainly by trial and error, and I haven’t  
bothered with using classes or defs yet, so it’s a bit messy.

Anyway, I’ve gotten so far as to have an object moving randomly around  
the screen, and now I’m trying to make another object follow the first  
one.

My code so far (messy):

require ‘sdl’  
include Math

SDL.init( SDL::INIT\_VIDEO )  
screen = SDL::setVideoMode(640,480,16,SDL::SWSURFACE)

image = SDL::Surface.loadBMP(“icon.bmp”)  
image.setColorKey( SDL::SRCCOLORKEY , image[0,0])  
image = image.displayFormat

angle = 0 #Angle for object 1  
angle2 = 0 #Angle for object 2  
xpos = 100.000000000000000000000 #X-coord for object 1  
ypos = 100.000000000000000000000 #Y-coord for object 1  
x2pos = 100.000000000000000000000 - image.w #X-coord for object 2  
y2pos = 100.000000000000000000000 #Y-coord for object 2  
xspeed = 1 #Speed in X  
yspeed = 1 #Speed in Y  
a\_count = 0 #Counter for determining  
angle  
a\_dur = 100 #sets how long object  
shold spin before changing direction  
a\_change = 0 #determines change in  
angle  
a\_slow = 1 #Determines how slow  
object turns  
a\_update = 0 #same as above

while true

event = SDL::Event2.poll  
case event  
when SDL::Event2::Quit  
exit  
when SDL::Event2::KeyDown  
exit if event.sym == SDL:🔑:ESCAPE  
end

#Determines if the angle should incline or decline,  
#and sets how long before the next change  
a\_count += 1  
if a\_count == a\_dur

```
a_count = 0
a_dur = rand(250) + 50
a_change = rand(3) -1

```

end

#Sets the angle and how slow the object should turn. The higher  
#a\_slow is, the slower it will turn.  
#Also sets the angle for object 2.  
a\_update += 1  
if a\_update == a\_slow

```
angle += a_change
angle2 = (atan((y2pos-ypos) / (x2pos-xpos)))/(PI/180)
a_update = 0

```

end

#Makes sure the angles are always between 1 and 360.  
if angle \> 360  
angle = angle - 360  
end

if angle \< 1  
angle = angle + 360  
end

if angle2 \> 360  
angle2 = angle2 - 360  
end

if angle2 \< 1  
angle2 = angle2 + 360  
end

# puts angle2

#Determines the new X an Y positions for the objects.

xpos = xpos + (cos(angle\*(PI/180))_xspeed )  
ypos = ypos + (sin(angle_(PI/180))\*yspeed )

x2pos = x2pos + (cos(angle2\*(PI/180))_xspeed )  
y2pos = y2pos + (sin(angle2_(PI/180))\*yspeed )

#Makes object 1 bounce

if xpos \>= 640 - image.w/2  
xpos = 638 - image.w/2  
angle = 180 - angle  
end

if xpos \<= 0 + image.w/2  
xpos = 2 + image.w/2  
angle = 540 - angle  
end

if ypos \>= 480 - image.h/2  
ypos =478 - image.h/2  
angle = 360 - angle  
end

if ypos \<= 0 + image.h/2  
ypos = 2 + image.h/2  
angle = 360 - angle  
end

# if x2pos \>= 640 - image.w/2

# x2pos = 638 - image.w/2

# angle2 = 180 - angle2

# end

# if x2pos \<= 0 + image.w/2

# x2pos = 2 + image.w/2

# angle2 = 540 - angle2

# end

# if y2pos \>= 480 - image.h/2

# y2pos =478 - image.h/2

# angle2 = 360 - angle2

# end

# if y2pos \<= 0 + image.h/2

# y2pos = 2 + image.h/2

# angle2 = 360 - angle2

# end

screen.fillRect(0,0,640,480,[100,100,100])

SDL.transformBlit(image,screen,angle,1,1,image.w/2,image.h/2,xpos,ypos,0  
)  
SDL.transformBlit(image,screen,angle2,1,1,image.w/2,image.h/2,x2pos,y2pos,0  
)

screen.updateRect(0,0,0,0)

end

My question is a mathematical one, here we go:

As you can see here " angle2 = (atan((y2pos-ypos) /  
(x2pos-xpos)))/(PI/180)" I determined the angle of the second object by  
calculating the angle between the two objects. It works as long as  
angle2 is less than 90 or more than 270, but if it gets between there it  
breaks away.

Is there any problems with my math, or is there some other problem  
somewhere in the code that makes it behave like that?

---

<div class="post-metadata">

**Author:** ![fuubi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e95f7d/32.png) [@fuubi](https://www.ruby-forum.com/u/fuubi)\
**Post date:** [February 15, 2008, 12:24pm UTC](https://www.ruby-forum.com/t/making-an-object-follow-another-object-fail/129176/2 "2008-02-15T12:24:18Z")

</div>

On Thu, Feb 14, 2008 at 8:48 PM, Lasse S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> My question is a mathematical one, here we go:
> 
> As you can see here " angle2 = (atan((y2pos-ypos) /  
> (x2pos-xpos)))/(PI/180)" I determined the angle of the second object by  
> calculating the angle between the two objects. It works as long as  
> angle2 is less than 90 or more than 270, but if it gets between there it  
> breaks away.
> 
> Is there any problems with my math, or is there some other problem  
> somewhere in the code that makes it behave like that?

I’m not going to help with the math, but is there some reason why you  
don’t just keep a position buffer, the length of which (the length of  
the array) determines the distance between the two sprites? That way,  
it just follows a path instead of an angle.

Todd

---

<div class="post-metadata">

**Author:** ![fuubi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e95f7d/32.png) [@fuubi](https://www.ruby-forum.com/u/fuubi)\
**Post date:** [February 15, 2008, 8:49am UTC](https://www.ruby-forum.com/t/making-an-object-follow-another-object-fail/129176/3 "2008-02-15T08:49:30Z")

</div>

My trig class was a long time ago, but from what I recall certain  
trigonometric functions are only positive in certain quadrants (angle  
ranges). This seems to touch on that:

> **[5. Signs of the Trigonometric Functions](https://www.intmath.com/trigonometric-functions/5-signs-of-trigonometric-functions.php)**
>
> This section explains trig ratios for angles greater than 90 degrees. Also contains an interactive graph applet.

---

<div class="post-metadata">

**Author:** ![fuubi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e95f7d/32.png) [@fuubi](https://www.ruby-forum.com/u/fuubi)\
**Post date:** [February 15, 2008, 12:39pm UTC](https://www.ruby-forum.com/t/making-an-object-follow-another-object-fail/129176/4 "2008-02-15T12:39:32Z")

</div>

Lasse S. wrote:

> My question is a mathematical one, here we go:
> 
> As you can see here " angle2 = (atan((y2pos-ypos) /  
> (x2pos-xpos)))/(PI/180)" I determined the angle of the second object by  
> calculating the angle between the two objects. It works as long as  
> angle2 is less than 90 or more than 270, but if it gets between there it  
> breaks away.

Compare Math.atan and Math.atan2. Math.atan2 relieves you from doing a  
manual branching depending on the angle.

Regards  
Stefan

---

<div class="post-metadata">

**Author:** ![fuubi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e95f7d/32.png) [@fuubi](https://www.ruby-forum.com/u/fuubi)\
**Post date:** [February 15, 2008, 1:38pm UTC](https://www.ruby-forum.com/t/making-an-object-follow-another-object-fail/129176/5 "2008-02-15T13:38:02Z")

</div>

Todd B. wrote:

> I’m not going to help with the math, but is there some reason why you  
> don’t just keep a position buffer, the length of which (the length of  
> the array) determines the distance between the two sprites? That way,  
> it just follows a path instead of an angle.
> 
> Todd

Yeah I had that idea too, but I’d already started trying to figure how  
to use the angle. And I could feel I was close, so I didn’t really want  
to start over with another idea.

Now I’ve done that anyway, and it works, so thanks for the advices.
