Angles.. and Rotation...
by Lawrence Benedicto · in Torque Game Builder · 05/26/2007 (3:14 pm) · 5 replies
Bah. I grow weary of you, T2D angles.
Here's the situation:
We have a player-avatar on the screen, who can walk all the way around an object (his gravity is relative to the object he's walking on). This character has sort of a grappling hook type weapon which we want to fire within a specific angle based on his rotation.
For example:
If the player-character were oriented with his feet on the ground, the angle of fire would be 45 degrees to the left or right of the angle directly above him. Sort of a \/ right above the character. When the player goes into "aiming" mode, the player's cursor gets moved into the \/ targeting range. If the player attempts to move his cursor out of this range, it gets pushed back in range.
Of course, this range is going to change, relative to his rotation. Here's how we're going about solving it:
(Notes: The character in question is "spider". $target is a crosshair overlay)
The line
It seems that the angle retrieved from
I don't get it.. When the player is oriented at specific angles, the aiming range is all wonky. If anyone has any insight, please let me know.
Here's the situation:
We have a player-avatar on the screen, who can walk all the way around an object (his gravity is relative to the object he's walking on). This character has sort of a grappling hook type weapon which we want to fire within a specific angle based on his rotation.
For example:
If the player-character were oriented with his feet on the ground, the angle of fire would be 45 degrees to the left or right of the angle directly above him. Sort of a \/ right above the character. When the player goes into "aiming" mode, the player's cursor gets moved into the \/ targeting range. If the player attempts to move his cursor out of this range, it gets pushed back in range.
Of course, this range is going to change, relative to his rotation. Here's how we're going about solving it:
(Notes: The character in question is "spider". $target is a crosshair overlay)
function sceneWindow2D::onMouseMove(%this, %modifier, %worldPos, %mouseClicks)
{
if($gamestarted == 1)
{
if((spider.state $= "aiming") || (spider.state $= "grappled"))
{
%x = getWord(%worldPos, 0);
%y = getWord(%worldPos, 1);
%startX = spider.getPositionX() + 5
* mcos(mdegtorad(spider.getRotation() - 85));
%startY = spider.getPositionY() + 5
* msin(mdegtorad(spider.getRotation() - 85));
%firingAngle = mradtodeg(matan(%y - %startY, %x - %startX));
if(spider.rotation > 180)
%firingAngle = %firingAngle + 360;
if(%firingAngle < spider.rotation - 45 && %firingAngle > spider.rotation - 135)
{
canvas.hideCursor();
$target.setPosition(%worldPos);
%objects = myscenegraph.pickPoint(%x, %y);
if(getWord(%objects, 1).class $= "puzzlePiece")
$target.setImageMap(GRAPPLEoverlayTargetLockImageMap);
else if($target.getImageMap() $= "GRAPPLEoverlayTargetLockImageMap")
$target.setImageMap(GRAPPLEoverlayTargetImageMap);
spider.oldCursorPos = canvas.getCursorPos();
}
else
{
canvas.setCursorPos(spider.oldCursorPos);
}
}
}
}The line
if(spider.rotation > 180) %firingAngle = %firingAngle + 360;is of some significance..
It seems that the angle retrieved from
%firingAngle = mradtodeg(matan(%y - %startY, %x - %startX));is not in the correct format. This angle starts to the right, continues clockwise from 0 to 180. Once it hits 180 it turns into a negative scale from -179 back to zero.
I don't get it.. When the player is oriented at specific angles, the aiming range is all wonky. If anyone has any insight, please let me know.
About the author
#2
those are all valid angles.
if you want the angles to be in the range [0, 360] you'll need to do something like:
05/29/2007 (11:47 am)
Quote:This angle starts to the right, continues clockwise from 0 to 180. Once it hits 180 it turns into a negative scale from -179 back to zero.
those are all valid angles.
if you want the angles to be in the range [0, 360] you'll need to do something like:
while (%angle < 0)
%angle += 360;
while (%angle > 360)
%angle -= 360;
#3
Have you checked that the arguments to atan are the ones you want? With TGB's coordinate system (positive Y is down, angles are measured clockwise from the negative Y axis) I almost always mess up my trig, so that may be a place to start.
05/29/2007 (11:59 am)
@Lawrence - Can you be more specific about what your problem or question is? It's hard to know how to help you starting from "it's all wonky".Have you checked that the arguments to atan are the ones you want? With TGB's coordinate system (positive Y is down, angles are measured clockwise from the negative Y axis) I almost always mess up my trig, so that may be a place to start.
#4
I attempted an "if(%angle < 0) { %angle+=360 };" but it wouldn't give the desired result all of the time. I can't exactly remember what went wrong with it, I believe there was a small angle that acted as a dead space.
Sorry about not being more specific on what exactly is happening:
If I remove the line
I believe I'm using Atan correctly, I'm using it for other things that are working just fine. :\
05/29/2007 (4:02 pm)
Orion-- I attempted an "if(%angle < 0) { %angle+=360 };" but it wouldn't give the desired result all of the time. I can't exactly remember what went wrong with it, I believe there was a small angle that acted as a dead space.
Sorry about not being more specific on what exactly is happening:
If I remove the line
if(spider.rotation > 180) %firingAngle = %firingAngle + 360;then the code restricts my angle correctly while the avatar has a rotation from 0-230. From the angles 230-360 the code seems to restrict my mouse movement more and more until it can't move at all. The line of code mentioned above was just a small fix, but it doesn't seem to work all that well either.
I believe I'm using Atan correctly, I'm using it for other things that are working just fine. :\
#5
..
If anyone's interested, that's the final product.
Even when restricting all angles to the range [0, 360], there were situations where the MaxRange would be less than the MinRange. This made moving the mouse impossible. The solution was to use a nested if() for that particular situation.
Sorry to anyone if I sounded bent out of shape, this problem has had me frustrated over the past few days x_x.
05/29/2007 (5:19 pm)
Ah, I fixed it. There are a lot of conditionals now so it looks sort of ugly, but anyway..
function sceneWindow2D::onMouseMove(%this, %modifier, %worldPos, %mouseClicks)
{
if($gamestarted == 1)
{
if((spider.state $= "aiming") || (spider.state $= "grappled"))
{
%x = getWord(%worldPos, 0);
%y = getWord(%worldPos, 1);
%startX = spider.getPositionX() + 5
* mcos(mdegtorad(spider.getRotation() - 90));
%startY = spider.getPositionY() + 5
* msin(mdegtorad(spider.getRotation() - 90));
%firingAngle = mradtodeg(matan(%y - %startY, %x - %startX));
if(%firingAngle < 0)
%firingAngle = %firingAngle + 360;
if(%firingAngle > 360)
%firingAngle = %firingAngle - 360;
// Area directly above the spider
%spiderNormal = spider.rotation - 90;
if(%spiderNormal < 0)
%spiderNormal = %spiderNormal + 360;
if(%spiderNormal > 360)
%spiderNormal = %spiderNormal - 360;
%minRange = %spiderNormal - 45;
%maxRange = %spiderNormal + 45;
if(%minRange < 0)
%minRange = %minRange + 360;
if(%minRange > 360)
%minRange = %minRange - 360;
if(%maxRange < 0)
%maxRange = %maxRange + 360;
if(%maxRange > 360)
%maxRange = %maxRange - 360;
if(%minRange > %maxRange)
{
if(%firingAngle > %minRange || %firingAngle < %maxRange)
{
canvas.hideCursor();
$target.setPosition(%worldPos);
%objects = myscenegraph.pickPoint(%x, %y);
if(getWord(%objects, 1).class $= "puzzlePiece")
$target.setImageMap(GRAPPLEoverlayTargetLockImageMap);
else if($target.getImageMap() $= "GRAPPLEoverlayTargetLockImageMap")
$target.setImageMap(GRAPPLEoverlayTargetImageMap);
spider.oldCursorPos = canvas.getCursorPos();
}
else
{
canvas.setCursorPos(spider.oldCursorPos);
}
}
else
if(%firingAngle < %spiderNormal + 45 && %firingAngle > %minRange)
{
canvas.hideCursor();
$target.setPosition(%worldPos);
%objects = myscenegraph.pickPoint(%x, %y);
if(getWord(%objects, 1).class $= "puzzlePiece")
$target.setImageMap(GRAPPLEoverlayTargetLockImageMap);
else if($target.getImageMap() $= "GRAPPLEoverlayTargetLockImageMap")
$target.setImageMap(GRAPPLEoverlayTargetImageMap);
spider.oldCursorPos = canvas.getCursorPos();
}
else
{
canvas.setCursorPos(spider.oldCursorPos);
}
}
}
}If anyone's interested, that's the final product.
Even when restricting all angles to the range [0, 360], there were situations where the MaxRange would be less than the MinRange. This made moving the mouse impossible. The solution was to use a nested if() for that particular situation.
Sorry to anyone if I sounded bent out of shape, this problem has had me frustrated over the past few days x_x.
Torque Owner Lawrence Benedicto