This is a read-only archive of the old Scratch 1.x Forums.
Try searching the current Scratch discussion forums.

#26 2012-07-09 18:30:51

amcerbu
Scratcher
Registered: 2009-07-21
Posts: 500+

Re: Circle detection

Okay, here's a solution that uses only math, and doesn't involve pointing in any direction or moving steps.  You may find this over-complicated, but I promise it is reliable, accurate, and compatible with other parts of your program.  Before I post the actual Scratch forum blocks, I'll write out a description that explains the mathematics behind it.  I think it'll be easier for you to do what you want if you understand what exactly the script does.  Please read this post through thoroughly. 


Vectors

A vector is a mathematical object that represents movement between two points in space.  Every vector has a direction and a magnitude (length).  You can imagine a vector as a line segment between an initial point and a terminal point, with an arrow pointing towards the terminal point.  Usually, a vector is represented as a list of components.  Since we're working in two dimensions, the vectors we'll be using will have x- and y-components. 

Notation: For this post, I'll write the names of vectors in bold.  For example, u.  You may also see them written elsewhere as a letters with arrows above.  As I've been taught, the component form is written with angle brackets, like this: <x, y>. 

In Scratch projects, vectors are most often used for velocity.  A coordinate position can also be imagined as a vector connecting the center of the sprite with the origin (0,0).  In every "frame" (repetition of the loop), the velocity vector is added to the position. 


Operations with Vectors

There exist many operations for vectors.  We'll talk about addition, dot product, finding the magnitude, scalar multiplication, and vector projection. 

Addition - The most basic operation is addition.  Adding together two vectors is performed by adding their corresponding components.  That is, you add the x of the first vector to the x of the second vector, and so on. 

Dot Product - The dot product is calculated by adding the products of corresponding elements in two vectors.  For example, the dot product of u and v (I'll write it as (u dot v) for this post) is u.x * v.x + u.y * v.y, where u.x is the x-component of vector u.  It's hard to describe exactly what the dot product represents.  If the dot product equals zero, the two vectors are perpendicular. 

Finding the Magnitude - We can use the Pythagorean theorem formula to find the length of the vector.  The Pythagorean theorem states that, in a right triangle with legs a and b, a^2 + b^2 = c^2.  Therefore, the length of the hypotenuse is equal to sqrt(a^2 + b^2).  In a vector, you can imagine that the x- and y-components are the legs, and the vector itself is the hypotenuse.  Therefore, the magnitude of the vector is equal to sqrt(x^2 + y^2).  The magnitude of some vector u is usually written as ‖u‖ or |u| (when I use this notation later on, know that it means the value of the magnitude).

Scalar Multiplication - By multiplying both components of the vector by a number (a scalar), you can create another vector that points in the same direction, but has a different magnitude.  Likewise, you can divide the components by a scalar.  When you divide a vector by its magnitude, you create what's called a unit vector, which has the same direction as the original vector, but a length of 1. 

Vector Projection - The final operation I'd like to talk about is vector projection.  The projection of u onto v creates a new vector (the resultant vector) with the same direction as v but a magnitude that represents u's length along v.  I'll include an image in a later post that shows what projection looks like. 

Anyway, here's the formula:

w1 = ((u dot v) / (‖v‖)^2) * v

If we subtract the projection (w1) from u, we'll end up with the rejection, which is perpendicular to vector v, and which we'll call w2.  Adding w1 to w2 gives u.

That's all for now.  I'll get back later with the actual block script, and with the diagram of vector projection (or you can search for it yourself, if you want).  I hope this post made sense.  Cheers, amcerbu.

Last edited by amcerbu (2012-07-10 08:54:58)

Offline

 

#27 2012-07-10 00:11:43

AtomicBawm3
Scratcher
Registered: 2009-06-27
Posts: 1000+

Re: Circle detection

I actually do have a project on this...it's not quite the same and it's probably what you're thinking of because it was in the design studio: http://scratch.mit.edu/projects/AtomicBawm3/2550790


http://i50.tinypic.com/j0yw0p.jpg

Offline

 

#28 2012-07-10 10:17:15

Firedrake969
Scratcher
Registered: 2011-11-24
Posts: 1000+

Re: Circle detection

It was this.


Click the sign.
https://s3.amazonaws.com/eterna/eterna2/logo2.png

Offline

 

#29 2012-07-10 12:01:29

amcerbu
Scratcher
Registered: 2009-07-21
Posts: 500+

Re: Circle detection

@Firedrake969- Did you have a chance to read my post?

Last edited by amcerbu (2012-07-10 12:01:56)

Offline

 

#30 2012-07-10 13:48:46

Firedrake969
Scratcher
Registered: 2011-11-24
Posts: 1000+

Re: Circle detection

Yea...  I just don't like really long scripts.  I'll check out a few programs right now...  Actually, I might have an idea...


Click the sign.
https://s3.amazonaws.com/eterna/eterna2/logo2.png

Offline

 

#31 2012-07-10 17:17:54

amcerbu
Scratcher
Registered: 2009-07-21
Posts: 500+

Re: Circle detection

Don't worry, the script itself isn't long.  And there's nothing wrong with long scripts.  Here it is:

This assumes you're using a sprite for the stationary circle and another for the moving one.  This script goes in the moving sprite.  Both objects will behave like circles. 

Here's the example

when gf clicked
set [Bumper.Radius v] to [100] // Radius of stationary sprite (bumper)
set [Ball.Radius v] to [20] // Radius of moving sprite  
set [DesiredDistance v] to ((Ball.Radius) + (Bumper.Radius))
set [Bumper.X v] to [0] // Set this to the x-coordinate of the bumper
set [Bumper.Y v] to [0] // Set this to the y-coordinate of the bumper
set [Ball.X v] to [-10] // Coordinates for the ball (moving object)
set [Ball.Y v] to [50]
set [Velocity.X v] to [1] // X-Velocity of the ball
set [Velocity.Y v] to [-1] // Y-Velocity of the ball
set [Friction v] to [0.9] // Sliding friction between objects
set [Restitution v] to [-0.7] // Velocity absorbed during a collision
forever
change [Ball.X v] by (Velocity.X)
change [Ball.Y v] by (Velocity.Y)
set [Offset.X v] to ((Ball.X) - (Bumper.X)) // X offset
set [Offset.Y v] to ((Ball.Y) - (Bumper.Y)) // Y offset
set [Distance v] to ([sqrt v] of (((Offset.X) * (Offset.X)) + ((Offset.Y) * (Offset.Y))))
if <(Distance) < (DesiredDistance) > // Collision

set [Normal.X v] to ((Offset.X) / (Distance)) // Creates a unit vector called Normal
set [Normal.Y v] to ((Offset.Y) / (Distance)) // Second component of Normal
set [Tangent.X v] to (Normal.Y) // Surface unit vector (magn. = 1)
set [Tangent.Y v] to ((-1) * (Normal.X))

set [DotProduct v] to (((Velocity.X) * (Tangent.X)) + ((Velocity.Y) * (Tangent.Y)))

set [TangentVelocity.X v] to ((DotProduct) * (Tangent.X)) // Projection
set [TangentVelocity.Y v] to ((DotProduct) * (Tangent.Y))
set [NormalVelocity.X v] to ((Velocity.X) - (TangentVelocity.X)) // Rejection
set [NormalVelocity.Y v] to ((Velocity.Y) - (TangentVelocity.Y))

set [Velocity.X v] to (((Restitution) * (NormalVelocity.X)) + ((Friction) * (TangentVelocity.X))) // Bounce
set [Velocity.Y v] to (((Restitution) * (NormalVelocity.Y)) + ((Friction) * (TangentVelocity.Y)))

set [Ball.X v] to ((Bumper.X) + ((Normal.X) * (DesiredDistance))) // Corrects position
set [Ball.Y v] to ((Bumper.Y) + ((Normal.Y) * (DesiredDistance)))

end
go to x: (Ball.X) y: (Ball.Y)
end

Last edited by amcerbu (2012-07-10 17:34:05)

Offline

 

#32 2012-07-10 22:11:39

Firedrake969
Scratcher
Registered: 2011-11-24
Posts: 1000+

Re: Circle detection

This is why I don't like long scripts...  tongue   And I don't need bouncing, just for it to turn away from the circle...


Click the sign.
https://s3.amazonaws.com/eterna/eterna2/logo2.png

Offline

 

#33 2012-07-10 22:30:18

amcerbu
Scratcher
Registered: 2009-07-21
Posts: 500+

Re: Circle detection

If you turn the "Restitution" variable down to 0, it won't bounce off the circle; the bumper object will absorb the force and the ball will continue moving with whatever is left over.  Try that in the sample project that I uploaded.

Offline

 

#34 2012-07-11 13:38:55

Firedrake969
Scratcher
Registered: 2011-11-24
Posts: 1000+

Re: Circle detection

I don't need bouncing.  What I need is simple:  Turn the crab away from the circle...


Click the sign.
https://s3.amazonaws.com/eterna/eterna2/logo2.png

Offline

 

#35 2012-07-11 13:58:00

amcerbu
Scratcher
Registered: 2009-07-21
Posts: 500+

Re: Circle detection

What does "turn away" mean?  If you just want it to turn away from the circle...

when gf clicked
forever
if <touching [circle v]?>
point towards [circle v]
turn cw (180) degrees
wait until <not<touching [circle v]?>>
end
end

Last edited by amcerbu (2012-07-11 13:58:22)

Offline

 

#36 2012-07-13 11:56:22

Firedrake969
Scratcher
Registered: 2011-11-24
Posts: 1000+

Re: Circle detection

That's exactly what I needed.  tongue
Now, another question:  For some reason, it only works if the circle is showing... why?


Click the sign.
https://s3.amazonaws.com/eterna/eterna2/logo2.png

Offline

 

#37 2012-07-13 11:58:38

AtomicBawm3
Scratcher
Registered: 2009-06-27
Posts: 1000+

Re: Circle detection

Firedrake969 wrote:

That's exactly what I needed.  tongue
Now, another question:  For some reason, it only works if the circle is showing... why?

Scratch can't do "touching" calculations if one or the other of the sprites involved is hidden.  You can, however, set one of the sprites to a ghost value of 100...but you cannot set both to 100 if you're using it online in the flash player I believe.


http://i50.tinypic.com/j0yw0p.jpg

Offline

 

#38 2012-07-13 12:07:54

Firedrake969
Scratcher
Registered: 2011-11-24
Posts: 1000+

Re: Circle detection

Ok thanks.


Click the sign.
https://s3.amazonaws.com/eterna/eterna2/logo2.png

Offline

 

#39 2012-07-13 13:03:43

Harakou
Community Moderator
Registered: 2009-10-11
Posts: 1000+

Re: Circle detection

Closed by request of owner.


http://www.blocks.scratchr.org/API.php?action=random&amp;return=image&amp;link1=http://i.imgur.com/OZn2RD3.png&amp;link2=http://i.imgur.com/duzaGTB.png&amp;link3=http://i.imgur.com/CrDGvvZ.png&amp;link4=http://i.imgur.com/POEpQyZ.png&amp;link5=http://i.imgur.com/ZKJF8ac.png

Offline

 

Board footer