Hi I know this is not Allegro related but I hope that maybe someone will explain me some things about analitical geometry.
I have a line that has a point fixed on certain coordinates and the other one follows the mouse. The next thing that I want to do is when I press the left mouse button , the line is fixed on a certain angle pointing to my mouse and I can move it on the axis formed by the mouse and the fixed point. The mouse event is not a problem , the only thins is I don't know how to write it. Can you give me some hints or ideas how to do this ?
I just want to paraphrase what you are saying so that we're on the same page. So basically what you want is when you have the mouse button pressed, and you move the muse towards the fixed point, the line will get shorter and if you move the mouse away from the fixed point the line will get longer. But so long as the mouse button is held down, the angle the line is on will remain the same.
Is that correct?
If so. The first thing I would do is calculate the x/y ratio. eg:
float ratio = (mouse_x - initial_x) / (mouse_y - initial_y);
and store either the x or y component at this time:
float x_length = mouse_x - initial_x;
Then I would calculate the length (actually, I'd calculate its square to save calculation on times) of the line as it stands right now:
float initial_line_length = (mouse_x - initial_x) * (mouse_x - initial_x) + (mouse_y - initial_y) * (mouse_y - initial_y);
Then do your loop that checks if the mouse is held down, and while it is, keep rechecking the new squared distance from the current position to the initial position:
<code>float current_line_length = (mouse_x - initial_x) * (mouse_x - initial_x) + (mouse_y - initial_y) * (mouse_y - initial_y);
The new x position for the end of the line is now:
float new_x = initial_x + x_length * initial_line_length / current_line_length;
The new y position is now:
float new_y = initial_y + x_length * initial_line_length / current_line_length * ratio;
If that causes the line to shrink and grow too quickly, just multiply the current_line_length value to some number between 0 and 1 until the speed is good for you.
The initial_x and initial_y are the fixed point's coordinates ?
What I want is when I press the mouse button the line won't get shorter it will be moved .Anyway I think your code gave me some help because I think the difference between getting shorter and be moved will be that for the move I also have to modify the fixed point coordinates.
I will try your advice . Thanks in advance.
The initial_x and initial_y are the fixed point's coordinates ?
Yes. I probably should have named them fixed_x and fixed_y.
Anyway I think your code gave me some help because I think the difference between getting shorter and be moved will be that for the move I also have to modify the fixed point coordinates.
That's even easier. First calculate the difference in position from the fixed point to the end of the line when you detect the mouse button is pressed, and store the mouse location:
Now while the mouse is held down, just loop through the following, which determines how far the mouse has moved since you pressed the button and moves the line by that amount:
The new line is drawn form x1, y1 to x2, y2.
So , here's what I did :
But this will make a line (that has an angle of 90+ degrees I don't know why..???) that follows the mouse. I am sorry if I misunderstood what you were trying to explain but I want the line to move on a certain angle even if the mouse is not on the same angle.
I want to make a pool game . This will help me with the cue. When I press the mouse button i want to drag the cue to set the force that will apply on the ball. So first I set the angle when I just move my mouse over the screen and then when I press the mouse button I only move the cue (line) on that angle that the line had immediately before i press the button.
I was thinking to save the mouse coordinates and when I click , I see if the x is decreasing and if yes I will decrease the x coordinate of the line and with the line equation I find the y according to that x coordinate of the line . The problem is i can't seem to make it to work...
I'm sorry if I'm confusing and hard to understand ,I hope you have the patience to explain me my problem
A pool cue is pretty simple.
Here's the pseudocode to get the cue's position:
mouseX and mouseY are the mouse's current position, do not stop updating mouseX and mouseY while the mouse is pressed.
ballX and ballY are the target ball's position
cueAngle is the angle of the cue. Stop updating this when you click. Store it like this:
cueAngle = atan2(mouseY - ballY, mouseX - ballX);
EDIT: I'm guessing you want the cue to start from the ball's position. To do this just store this in a float called ballDist once when you click:
ballDist = sqrt((mouseX-ballX)*(mouseX-ballX) + (mouseY-ballY)*(mouseY-ballY));
Then subtract ballDist from D in the code above.
I have this :
When I run it i Get a line from the top left corner to the ball coordinates.When I press the mouse button I only see a point
that it has a static move or something. Can you tell me how to apply your solution corectly ?
Also Where I use the D variable ?
Whoops, I wrote the code in wrong (it was pseudocode after all
should be:
EDIT: Also, this line should only be done once when you click, you seem to do it continuously when the mouse is down:
ballDist = sqrt((mx-ballX)*(mx-ballX) + (my-ballY)*(my-ballY));
So , I made the modification but now when I press the mouse button it only appears on ...(let's say the ball coordinates are the centre of the screen) 0 angle I mean it's a line from the ball's coordinates and horizontal to right and is blinking.Here is an image of what I got : click to see image
Also ballDist can be optional ? because I have to write an another event so it's calculated only once when the button is pressed.
EDIT: The cue's coordinates are wierd...here's another image with the coordinates that i 'am getting (the point is not very accurate but still )
Without "ballDist" the cue will jump to the mouse's distance relative to the ball instead of relative to the mouse's original position. You don't need another event, you can do something like this:
Try and see if that fixes it.
Here is my code :
What/Where is the problem ??
Also it's ok with that wasMousePressed to be the only expression in that event ? I mean I thought "all the cue logic " should be in the braces of the if function where is the ballDist Atribution.
Change this block of code:
mx=events.mouse.x; my=events.mouse.y; float newAngle = atan2(my - ballY, mx - ballX) - cueAngle; D = sqrt((mx-ballX)*(mx-ballX) + (my-ballY)*(my-ballY)) * cos(newAngle)-ballDist; if(D < 0) D = 0; cueX = ballX + cos(cueAngle)*D; cueY = ballY + sin(cueAngle)*D; cueAngle = atan2(my - ballY, mx - ballX);
to this:
if(MouseState.buttons & 1){ mx=events.mouse.x; my=events.mouse.y; float newAngle = atan2(my - ballY, mx - ballX) - cueAngle; D = sqrt((mx-ballX)*(mx-ballX) + (my-ballY)*(my-ballY)) * cos(newAngle)-ballDist; if(D < 0) D = 0; cueX = ballX + cos(cueAngle)*D; cueY = ballY + sin(cueAngle)*D; }else{ cueAngle = atan2(my - ballY, mx - ballX); }
hopefully this will make it perfect
When I click the line appears on good coordinates but the cue's coordinates are faar long, it keeps blinking and if I want to to move it , it's not any difference it's just blinking .I guess we advanced a little
I think the problem is with the distance . In the console the coordinates for the cue are bad when i keep the mouse pressed and move the mouse , there are some negative/positive numbers with some 'e' .If you can help me with that too , i would be very grateful
EDIT : The D variable when I keep the mouse button pressed is a changing values , even if the mouse is not moving (sometimes is 0 and some infinite values)
Hard to say now, post the full code. I put the logic into a little flash program to test it and it works perfectly. See attached (If you don't have flash player open the file with your internet browser).
Here is the full code :
It might have some unused variables from my other tries )
EDIT : that flash is EXACTLY what I want to do !
The logic seems correct. The only problem I see is that you define newAngle at the top of your code and within the loop, maybe that causes it? Also, you should initialize cueAngle to 0 or something just to be safe.
If I remove from the top I get an error that it wasn't declared.
In the console the cueAngle seems to be okay
The newAngle is not really ok . If I click repeatedly in the same place it takes different values like: 0 , infinite values and sometimes normal numbers.
EDIT: Can you post the flash's source ? Maybe I can find the problem by spending some time analyzing that perfect flash application
Did you remove the declaration of cueAngle before the loop? I meant the declaration of newAngle before the loop instead. Try that first. Here's the full flash code if you want, but it's mostly identical to yours.
So based on your source I made some changes in my program :
In the console the newAngle is always 0. And if I click the cue's coordinates are ok but if i go further than the ball's coordinates the distance between my mouse and the cue's coorinates gets higher.The other point it's just fixed in the center and the line gets shorter or longer and isn't on the same angle. Hope I didn't go backwards but do you see any more differences in my c source code and your flash source code ?
EDIT: Now I declare my newAngle in the loop, and the cueAngle at the top and in the loop.
Maybe take
cueAngle = atan2(my - ballY, mx - ballX);
out of the events.type==ALLEGRO_EVENT_MOUSE_AXES if statement?
Yes, that fixed the angle but the ball's coordinates don't change . I mean the cue doesn't not have a constant lenght and the fixed point just stays there ,fixed, and the line gets shorter or longer.
I think this is only a problem at the screening..how I use the al_draw_line() function ?
you should draw a line from cueX,cueY to a point further down the cue, for example
al_draw_line(cueX,cueY, cueX + cos(cueAngle) * CUELENGTH, cueY + sin(cueAngle) * CUELENGTH,al_map_rgb(200,100,155),2);
set CUELENGTH to some value, for example 100
YES !:D It's working ! Thanks very much I really appreciate your help and sorry if I took much of your time