Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1075929 Posts in 44152 Topics- by 36119 Members - Latest Member: Royalhandstudios

December 29, 2014, 04:01:19 PM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Finding proper position for point-circle-point
Pages: [1]
Print
Author Topic: Finding proper position for point-circle-point  (Read 380 times)
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« on: March 30, 2013, 05:23:48 AM »

Hey.

At first, sorry for not-so-clear topic title. I am not sure what would describe that problem better.

What I need is to find intersection on circle, between two points. This image illustrates it well:



I needed to find red dot, and for this purpose, I made the following alghoritm: (let's call the blue dot in the center of the circle "center" and the other blue dot, let's call it "position")

Code:
float angleRad = atan2((position.x-center.x),(position.y-center.y));
float redDotX = cos(angleRad)*radius + center.x;
float redDotY = sin(angleRad)*radius + center.y;

After I had implemented that, I got this:



(Notice the weirdo jump as I move the thumb towards the right-upper corner of the joystick. That jump is calculated by the alghoritm given. Simply:
- If thumb's center is not trying to get out of the joystick, set it's position to mouse x and y [offset is it's center]
- If thumb's center is trying to get out of the joystick, set it's position using the alghoritm given )

After that, I've tried to use another alghoritm, which was given to me by PompiPompi:

Code:
redDotPosition = (center-position).normalize() * radius + center;

But the result is still the same. The whole thing "jumps".

Now, I am suspicious about aspect ratio (maybe it messes something up?), but I don't really have anything that'd prove it's fault.

Any ideas?


Actual code

Variables:
x - mouse X
y - mouse Y
ax - Joystick X
aw - Joystick Width
ay - Joystick Y
ah - Joystick Height
tx - Thumb X
ty - Thumb Y
tw - Thumb Width
th - Thumb Height
tSpr - thumb sprite
aSpr - joystick sprite


1. Using my alghoritm

Code:
float deltaX = (x) - (ax+aw/2);
float deltaY = (y) - (ay+ah/2);
float angle = atan2(deltaY,deltaX);
float newX = cos(angle)*agk::GetSpriteWidth(aSpr)/2 + ax+aw/2-tw/2;
float newY = sin(angle)*agk::GetSpriteHeight(aSpr)/2 + ay+ah/2-th/2;
agk::SetSpritePosition(tSpr,newX,newY);

2. Using PompiPompi's alghoritm

Code:
translateVector a, b;
a.setVector(x,y);
b.setVector(ax+aw/2,ay+ah/2);
float intersectionX = ((a-b).Normalize() * (aw/2) + b).tx - aw/4;
float intersectionY = ((a-b).Normalize() * (ah/2) + b).ty - ah/4;
agk::SetSpritePosition(tSpr,intersectionX,intersectionY);
Logged

Nothing to do here
Polly
Level 4
****


View Profile
« Reply #1 on: March 30, 2013, 05:36:01 AM »

Why not simply subtract the center ( blue ) point from the input coordinates and then clamp the radius if it's larger then the circle? Ninja
Logged
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #2 on: March 30, 2013, 05:44:50 AM »

Why not simply subtract the center ( blue ) point from the input coordinates and then clamp the radius if it's larger then the circle? Ninja

Um, I'm not sure I understand you here:
Quote
and then clamp the radius if it's larger then the circle

1. I substract position from center (position-center)
2. I get length of that vector ((position-center).length()) and clamp it if it's larger than circle's
3. Now what do I do with it?
Logged

Nothing to do here
Belimoth
Level 10
*****


high-heeled cyberbully


View Profile
« Reply #3 on: March 30, 2013, 05:55:18 AM »

Which of these is correct in your context:
Code:
atan2(dx, dy)

Or

Code:
atan2(dy, dx)
Logged

Polly
Level 4
****


View Profile
« Reply #4 on: March 30, 2013, 05:56:43 AM »

Now what do I do with it?

This?



You don't need any atan, in fact you could even solve this without a sqrt.
Logged
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #5 on: March 30, 2013, 06:01:24 AM »

Which of these is correct in your context:
Code:
atan2(dx, dy)

Or

Code:
atan2(dy, dx)


Mistake, in my code it's right.

Polly, wait. I've got radius, how will I calculate position for my dot? Normally I'd do it simply,

dotX = mouseX
dotY = mouseY

if I have mouseX, Y, center dot position and radius - what's the method to find dot's position, other than using atan2 to measure the angle between mouse and center?

I am not as good as you in maths, I need more explanation Tongue
Logged

Nothing to do here
Belimoth
Level 10
*****


high-heeled cyberbully


View Profile
« Reply #6 on: March 30, 2013, 06:04:25 AM »

Polly is using vector math like Pompi Pompi.

Have you tried testing your code with rendered shapes instead of images? Sometimes image pivots can have strange effects.
Logged

Polly
Level 4
****


View Profile
« Reply #7 on: March 30, 2013, 06:07:54 AM »

I've got radius, how will I calculate position for my dot?

How about adding the center coordinates back to the potentially clamped vector? Wink You only need this to render the "thumb-stick" image, you already have the correct input value at this point.
Logged
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #8 on: March 30, 2013, 06:41:02 AM »

It *almost* works now, except that I'd need to multiply my y somewhere by the display aspect, because, for now, my thumb is moving over an ellipse, not a circle.

Here's my current code (did I interpret it properly?):

Code:
translateVector position(x,y);
translateVector center(ax+aw/2,ay+ah/2);
float diffRadius = (position-center).getLength();
if(diffRadius > s/2) {
diffRadius -= s/2;
translateVector normalized(position-center);
normalized = normalized.Normalize() * diffRadius;
position = position - normalized;
}
agk::SetSpritePosition(tSpr,position.tx-aw/4,position.ty*aspect-ah/4);

Variables remain unchanged. Also, s is radius here.

@EDIT
Just so you know, this is how it looks like:



I've checked and when window is 600x600, it is a perfect circle, so it must be fault of aspect ratio. I've tried to multiply things, at first logically, then anything I could, but it just didn't work out.

Not sure how to make a circle out of that ellipse..

Aspect ratio (windowWidth/windowHeight) is usually ~1.7 (1024x600 window)

(To GL heads - my ortho projection is not of window size, but 100.0, 100.0 is down-right corner and 0.0, 0.0 is left upper corner)
« Last Edit: March 30, 2013, 10:24:04 AM by kamac » Logged

Nothing to do here
Martin 2BAM
Level 10
*****


@iam2bam


View Profile WWW Email
« Reply #9 on: April 01, 2013, 01:57:56 PM »

You must apply the aspect correction before the clamping.
Code:
delta = (position-center);
delta.y *= aspect;
float diffRadius = delta.getLength();
...etc etc using delta instead of "position - center" afterwards...



Also,
Code:
if(diffRadius > s/2) {
 diffRadius -= s/2;

Shouldn't it assign s/2 instead of subtracting it?
EDIT: I get what you're doing, nevermind this.
« Last Edit: April 01, 2013, 02:06:35 PM by nitram_cero (2bam) » Logged

Working on HeliBrawl
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic