Browse Source

Merge pull request #123 from WilliamLeeSims/development

Minor Angle Cleanup
Mike Lilligreen 12 years ago
parent
commit
50af7a100c

+ 2 - 2
engine/source/2d/core/Vector2.h

@@ -86,8 +86,8 @@ struct Vector2 : b2Vec2
     inline Vector2 operator = (const b2Vec2 &p)                         { x = p.x; y = p.y; return *this; }
 
     /// Utility.
-    inline void setAngle(const F32 radians)                             { x = mSin(radians); y = mCos(radians); }
-    inline void setPolar(const F32 radians,F32 length)                  { x = mSin(radians)*length; y = mCos(radians)*length; }
+    inline void setAngle(const F32 radians)                             { x = mCos(radians); y = mSin(radians); }
+    inline void setPolar(const F32 radians,F32 length)                  { x = mCos(radians)*length; y = mSin(radians)*length; }
     inline void setString(const char* pString )
     {
         const U32 elementCount = Utility::mGetStringElementCount(pString);

+ 2 - 2
engine/source/2d/core/Vector2_ScriptBinding.h

@@ -263,7 +263,7 @@ ConsoleFunctionWithDocs( Vector2AngleBetween, ConsoleFloat, 3, 3, (Vector2 v1, V
 /*! Angle from one point to another.
 	@return the angle from p1 to p2.
 */
-ConsoleFunctionWithDocs( Vector2AngleToPoint, ConsoleFloat, 3, 3, (Vector2 p1, Vector2 p1))
+ConsoleFunctionWithDocs( Vector2AngleToPoint, ConsoleFloat, 3, 3, (Vector2 p1, Vector2 p2))
 {
     // Check Parameters.
     if (Utility::mGetStringElementCount(argv[1]) < 2 ||Utility::mGetStringElementCount(argv[2]) < 2 )
@@ -276,7 +276,7 @@ ConsoleFunctionWithDocs( Vector2AngleToPoint, ConsoleFloat, 3, 3, (Vector2 p1, V
     Vector2 p2( argv[2] );
 
     // Do Operation.
-    return mRadToDeg( mAtan((p2.x - p1.x), (p1.y - p2.y)) );
+    return mRadToDeg( mAtan((p2.x - p1.x), (p2.y - p1.y)) );
 }
 
 //-----------------------------------------------------------------------------

+ 2 - 2
engine/source/2d/sceneobject/ParticlePlayer.cc

@@ -1432,14 +1432,14 @@ void ParticlePlayer::integrateParticle( EmitterNode* pEmitterNode, ParticleSyste
     if ( pParticleAssetEmitter->getKeepAligned() && pParticleAssetEmitter->getOrientationType() == ParticleAssetEmitter::ALIGNED_ORIENTATION )
     {
         // Yes, so calculate last movement direction.
-        F32 movementAngle = mRadToDeg( mAtan( pParticleNode->mVelocity.x, -pParticleNode->mVelocity.y ) );
+        F32 movementAngle = mRadToDeg( mAtan( pParticleNode->mVelocity.x, pParticleNode->mVelocity.y ) );
 
         // Adjust for negative ArcTan quadrants.
         if ( movementAngle < 0.0f )
             movementAngle += 360.0f;
 
         // Set new Orientation Angle.
-        pParticleNode->mOrientationAngle = -movementAngle - pParticleAssetEmitter->getAlignedAngleOffset();
+        pParticleNode->mOrientationAngle = movementAngle - pParticleAssetEmitter->getAlignedAngleOffset();
 
     }
     else

+ 1 - 1
engine/source/2d/sceneobject/SceneObject.cc

@@ -1656,7 +1656,7 @@ bool SceneObject::rotateTo( const F32 targetAngle, const F32 speed, const bool a
     const F32 relativeAngle = targetAngle - getAngle();
 
     // Calculate delta angle.
-    const F32 deltaAngle = mAtan( mSin( relativeAngle ), mCos( relativeAngle ) );
+    const F32 deltaAngle = mAtan( mCos( relativeAngle ), mSin( relativeAngle ) );
 
     // Set angular velocity.
     setAngularVelocity( deltaAngle > 0.0f ? speed : -speed );

+ 2 - 2
engine/source/2d/sceneobject/SceneObject_ScriptBinding.h

@@ -1643,7 +1643,7 @@ ConsoleMethodWithDocs(SceneObject, setLinearVelocityPolar, ConsoleVoid, 4, 4, (f
     mSinCos( angle, sin, cos );
 
     // Set Gross Linear Velocity.
-    object->setLinearVelocity( Vector2( sin*speed, -cos*speed ) );
+    object->setLinearVelocity( Vector2( cos*speed, sin*speed ) );
 }
 
 //-----------------------------------------------------------------------------
@@ -1660,7 +1660,7 @@ ConsoleMethodWithDocs(SceneObject, getLinearVelocityPolar, ConsoleString, 2, 2,
     char* pBuffer = Con::getReturnBuffer(32);
 
     // Format Buffer.
-    dSprintf(pBuffer, 32, "%g %g", mRadToDeg(mAtan(linearVelocity.x, -linearVelocity.y)), linearVelocity.Length() );
+    dSprintf(pBuffer, 32, "%g %g", mRadToDeg(mAtan(linearVelocity.x, linearVelocity.y)), linearVelocity.Length() );
 
     // Return Velocity.
     return pBuffer;

+ 1 - 1
engine/source/2d/sceneobject/Scroller_ScriptBinding.h

@@ -229,7 +229,7 @@ ConsoleMethodWithDocs(Scroller, setScrollPolar, ConsoleVoid, 4, 4, (angle, scrol
     F32 scrollSpeed = dAtof(argv[3]);
 
     // Set Scroll.
-    object->setScroll( mSin(mDegToRad(angle))*scrollSpeed, -mCos(mDegToRad(angle))*scrollSpeed );
+    object->setScroll( mCos(mDegToRad(angle))*scrollSpeed, mSin(mDegToRad(angle))*scrollSpeed );
 }
 
 //------------------------------------------------------------------------------

+ 2 - 14
engine/source/math/mMathFn.h

@@ -408,7 +408,7 @@ inline F32 mAcos(const F32 val)
 
 inline F32 mAtan(const F32 x, const F32 y)
 {
-   return (F32) atan2(x, y);
+   return (F32) atan2(y, x);
 }
 
 inline void mSinCos(const F32 angle, F32 &s, F32 &c)
@@ -465,7 +465,7 @@ inline F64 mAcos(const F64 val)
 
 inline F64 mAtan(const F64 x, const F64 y)
 {
-   return (F64) atan2(x, y);
+   return (F64) atan2(y, x);
 }
 
 inline void mSinCos(const F64 angle, F64 &sin, F64 &cos)
@@ -610,18 +610,6 @@ inline F64 mRadToDeg(F64 r)
    return (r * 180.0) / M_PI;
 }
 
-/// Get an angle flipping the Y (along the X axis).
-inline F32 mGetFlippedXAngle( const F32 radians )
-{
-    return mAtan(-mSin(radians), mCos(radians));
-}
-
-/// Get an angle flipping the Y (along the X axis).
-inline F32 mGetFlippedYAngle( const F32 radians )
-{
-    return mAtan(mSin(radians), -mCos(radians));
-}
-
 /// Precision Rounding.
 inline F32 mRound(const F32& value, const F32 epsilon = 0.5f) { return value > 0.0f ? mFloor(value + epsilon) : mCeil(value - epsilon); }
 

+ 37 - 21
engine/source/math/math_ScriptBinding.cc

@@ -164,65 +164,81 @@ ConsoleFunctionWithDocs( mLog, ConsoleFloat, 2, 2, ( val ))
    return(mLog(dAtof(argv[1])));
 }
 
-/*! Use the mSin function to get the sine of the radian angle val.
-    @param val A value between -3.14159 and 3.14159.
+/*! Use the mSin function to get the sine of the angle val.
+    @param val A value in degrees.
     @return Returns the sine of val. This value will be in the range [ -1.0 , 1.0 ].
     @sa mAsin
 */
 ConsoleFunctionWithDocs( mSin, ConsoleFloat, 2, 2, ( val ))
 {
-   return(mSin(dAtof(argv[1])));
+   return(mSin(mDegToRad(dAtof(argv[1]))));
 }
 
-/*! Use the mCos function to get the cosine of the radian angle val.
-    @param val A value between -3.14159 and 3.14159.
+/*! Use the mCos function to get the cosine of the angle val.
+    @param val A value in degrees.
     @return Returns the cosine of val. This value will be in the range [ -1.0 , 1.0 ].
     @sa mAcos
 */
 ConsoleFunctionWithDocs( mCos, ConsoleFloat, 2, 2, ( val ))
 {
-   return(mCos(dAtof(argv[1])));
+   return(mCos(mDegToRad(dAtof(argv[1]))));
 }
 
-/*! Use the mTan function to get the tangent of the radian angle val.
-    @param val A value between -3.14159/2 and 3.14159/2.
+/*! Use the mTan function to get the tangent of the angle val.
+    @param val A value in degrees.
     @return Returns the tangent of val. This value will be in the range [ -inf.0 , inf.0 ].
     @sa mAtan
 */
 ConsoleFunctionWithDocs( mTan, ConsoleFloat, 2, 2, ( val ))
 {
-   return(mTan(dAtof(argv[1])));
+   return(mTan(mDegToRad(dAtof(argv[1]))));
 }
 
-/*! Use the mAsin function to get the inverse sine of val in radians.
+/*! Use the mAsin function to get the inverse sine of val in degrees.
     @param val A value between -1.0 and 1.0 equal to the sine of some angle theta.
-    @return Returns the inverse sine of val in radians. This value will be in the range [ - 3.14159/2 , 3.14159/2 ].
+    @return Returns the inverse sine of val in degrees. This value will be in the range [ -90, 90 ].
     @sa mSin
 */
 ConsoleFunctionWithDocs( mAsin, ConsoleFloat, 2, 2, ( val ))
 {
-   return(mAsin(dAtof(argv[1])));
+   return(mRadToDeg(mAsin(dAtof(argv[1]))));
 }
 
-/*! Use the mAcos function to get the inverse cosine of val in radians.
+/*! Use the mAcos function to get the inverse cosine of val in degrees.
     @param val A value between -1.0 and 1.0 equal to the cosine of some angle theta.
-    @return Returns the inverse cosine of val in radians. This value will be in the range [ 0 , 3.14159 ].
+    @return Returns the inverse cosine of val in radians. This value will be in the range [ 0 , 180 ].
     @sa mCos
 */
 ConsoleFunctionWithDocs( mAcos, ConsoleFloat, 2, 2, ( val ))
 {
-   return(mAcos(dAtof(argv[1])));
+   return(mRadToDeg(mAcos(dAtof(argv[1]))));
 }
 
-/*! Use the mAtan function to get the inverse tangent of rise/run in radians.
-    @param rise Vertical component of a line.
-    @param run Horizontal component of a line.
-    @return Returns the slope in radians (the arc-tangent) of a line with the given rise and run.
+/*! Use the mAtan function to get the inverse tangent of rise/run in degrees.
+    May be called as mAtan( deltaX, deltaY ) or mAtan( "deltaX deltaY" ).
+    @param x-axis run Horizontal component of a line.
+    @param y-axis rise Vertical component of a line.
+    @return Returns the slope in degrees (the arc-tangent) of a line with the given run and rise.
     @sa mTan
 */
-ConsoleFunctionWithDocs( mAtan, ConsoleFloat, 3, 3, ( val ))
+ConsoleFunctionWithDocs( mAtan, ConsoleFloat, 2, 3, ( val ))
 {
-   return(mAtan(dAtof(argv[1]), dAtof(argv[2])));
+   F32 xRun, yRise;
+   if( argc == 3 )
+   {
+      xRun = dAtof( argv[1] );
+      yRise = dAtof( argv[2] );
+   }
+   else if( StringUnit::getUnitCount( argv[1], " " ) == 2 )
+   {
+     dSscanf( argv[1], "%g %g", &xRun, &yRise );
+   }
+   else
+   {
+     Con::warnf( "mAtan - Invalid parameters." );
+     return 0;
+   }
+   return(mRadToDeg(mAtan(xRun, yRise)));
 }
 
 /*! Use the mRadToDeg function to convert radians to degrees.

+ 298 - 0
modules/AngleToy/1/main.cs

@@ -0,0 +1,298 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+function AngleToy::create( %this )
+{        
+    // Reset the toy initially.
+    AngleToy.reset();
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::destroy( %this )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::reset( %this )
+{
+    // Clear the scene.
+    SandboxScene.clear();
+    
+    // Create background.
+    %this.createBackground();
+    
+    // Create the target.
+    %this.createTargets();
+    
+    // Create Mathematical Objects/Labels
+    %this.createMathematicalObjects();
+    
+    AngleToy.repointTarget = "0 0";
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::createBackground( %this )
+{    
+    // Create the Polar Coordinate Background
+    %axisColor = "0.4 0.4 0.4";
+    %circleColor = "0.2 0.2 0.2";
+    %textColor = "1 1 0";
+    
+    // X-Axis
+    %object = new ShapeVector();
+    %object.setBodyType( static );
+    %object.Position = "0 0";
+    %object.Size = "100 0";
+    %object.SceneLayer = 31;
+    %object.LineColor = %axisColor;
+    %object.FillMode = false;
+    %object.setPolyCustom( 2, "-1 0 1 0" );
+    SandboxScene.add( %object );    
+  
+    // Y-Axis
+    %object = new ShapeVector();
+    %object.setBodyType( static );
+    %object.Position = "0 0";
+    %object.Size = "0 25";
+    %object.SceneLayer = 31;
+    %object.LineColor = %axisColor;
+    %object.FillMode = false;
+    %object.setPolyCustom( 2, "0 -1 0 1" );
+    SandboxScene.add( %object );
+    
+    // Radius Circles
+    for( %i = 1; %i <= 2; %i++ )
+    {
+        %object = new ShapeVector();
+        %object.setBodyType( static );
+        %object.Position = "0 0";
+        %object.Size = "20 20";
+        %object.SceneLayer = 31;
+        %object.LineColor = %circleColor;
+        %object.FillMode = false;
+        %object.IsCircle = true;
+        %object.CircleRadius = %i * 10;
+        SandboxScene.add( %object );
+    }
+    
+    // Angle Labels
+    for( %i = -165; %i <= 180; %i += 15 )
+    {
+        %object = new ImageFont();
+        %object.Image = "ToyAssets:Font";
+        %object.Position = Vector2Direction( %i, 30 ); // Polar ( 30, %i° )
+        %object.Angle = %i - 90;
+        %object.FontSize = "1.5 2";
+        %object.TextAlignment = "Center";
+        %object.BlendColor = %textColor;
+        %object.Text = %i;
+        SandboxScene.add( %object );    
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::createTargets( %this )
+{
+    // Create the sprite.
+    %object = new Sprite() { class = "MagicTarget"; };
+    AngleToy.TargetObject = %object;
+    %object.Image = "ToyAssets:hollowArrow";
+    %object.Size = 5;
+    %object.setBodyType( dynamic );
+    %object.startTimer( repoint, 100 );
+    SandboxScene.add( %object );
+
+    %effect = new ParticleAsset();
+    %effect.AssetName = "DirectedParticles";
+    
+    %emitter = %effect.createEmitter();
+    AngleToy.EmitterParameters = %emitter;
+    %emitter.EmitterName = "AngledParticles";
+    %emitter.setKeepAligned( true );
+    %emitter.setOrientationType( ALIGNED );
+    %emitter.Image = "ToyAssets:Crosshair3";
+    %emitter.selectField( "Lifetime" );
+    %emitter.addDataKey( 0, 1 );
+    %emitter.selectField( "Quantity" );
+    %emitter.addDataKey( 0, 250 );
+    %emitter.selectField( "Speed" );
+    %emitter.addDataKey( 0, 4 );
+    %emitter.selectField( "EmissionAngle" );
+    %emitter.addDataKey( 0, 0 );
+    %emitter.selectField( "EmissionArc" );
+    %emitter.addDataKey( 0, 0 );
+    %emitter.selectField( "EmissionForceVariation" );
+    %emitter.addDataKey( 0, 0 );
+    %emitter.deselectField();
+    
+    %assetId = AssetDatabase.addPrivateAsset( %effect );
+    
+    %object = new ParticlePlayer();
+    AngleToy.TargetParticles = %object;
+    %object.BodyType = static;
+    %object.Particle = %assetId;
+    
+    SandboxScene.add( %object );      
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::createMathematicalObjects( %this )
+{
+    %lineSegmentColor = "0.25 0.25 0.75";
+  
+    %object = new Sprite() { class = "LineSegment"; };
+    AngleToy.SinLineSegment = %object;
+    %object.Image = "ToyAssets:Blank";
+    %object.setBodyType( static );
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+    
+    %object = new Sprite() { class = "LineSegment"; };
+    AngleToy.CosLineSegment = %object;
+    %object.Image = "ToyAssets:Blank";
+    %object.setBodyType( static );
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );    
+    
+    %object = new Sprite() { class = "LineSegment"; };
+    AngleToy.TanLineSegment = %object;
+    %object.Image = "ToyAssets:Blank";
+    %object.setBodyType( static );
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+    
+    %object = new ImageFont();
+    AngleToy.SinLabel = %object;
+    %object.Image = "ToyAssets:Font";
+    %object.FontSize = "1.5 1.5";
+    %object.TextAlignment = "Center";
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+    
+    %object = new ImageFont();
+    AngleToy.CosLabel = %object;
+    %object.Image = "ToyAssets:Font";
+    %object.FontSize = "1.5 1.5";
+    %object.TextAlignment = "Center";
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+    
+    %object = new ImageFont();
+    AngleToy.TanLabel = %object;
+    %object.Image = "ToyAssets:Font";
+    %object.FontSize = "1.5 1.5";
+    %object.TextAlignment = "Center";
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::onTouchMoved(%this, %touchID, %worldPosition)
+{
+    // Used to let the repointing target kno  
+    AngleToy.repointTarget = %worldPosition;
+
+    // Calculate the angle to the mouse.
+    %angle = mAtan( %worldPosition );
+    
+    // "Point" particles towards cursor
+    AngleToy.EmitterParameters.selectField( "EmissionAngle" );
+    AngleToy.EmitterParameters.addDataKey( 0, %angle );
+    AngleToy.EmitterParameters.deselectField();
+    
+    // Show Sin, Cos, Tan
+    %sin = mSin( %angle );
+    %cos = mCos( %angle );
+    %tan = mTan( %angle );
+
+    // Find the vector that's 20/21 units from the center in the direction of
+    // %worldPosition.  Here are a couple of ways to do that:
+    %worldPositionAtRadius20 = Vector2Direction( %angle, 20 );
+    %worldPositionAtRadius21 = Vector2Scale( Vector2Normalize( %worldPosition ), 21 );
+
+    // Draw the Sine    
+    %onYAxis = setWord( %worldPositionAtRadius20, 0, 0 ); // Set the X-component to 0
+    AngleToy.SinLineSegment.draw( %worldPositionAtRadius20, %onYAxis );
+    AngleToy.SinLabel.setPosition( Vector2Add( %onYAxis, "0 -1" ) );
+    AngleToy.SinLabel.setText( mFloatLength( %sin, 4 ) );
+    
+    // Draw the Cosine
+    %onXAxis = setWord( %worldPositionAtRadius20, 1, 0 ); // Set the Y-component to 0
+    AngleToy.CosLineSegment.draw( %worldPositionAtRadius20, %onXAxis );
+    AngleToy.CosLabel.setPosition( Vector2Add( %onXAxis, "-1 0" ) );
+    AngleToy.CosLabel.setAngle( 90 );
+    AngleToy.CosLabel.setText( mFloatLength( %cos, 4 ) );
+    
+    // Draw the Tangent
+    AngleToy.TanLineSegment.drawTangent( %worldPositionAtRadius20, %tan, %angle );
+    AngleToy.TanLabel.setPosition( %worldPositionAtRadius21 );
+    AngleToy.TanLabel.setAngle( %angle - 90 );
+    AngleToy.TanLabel.setText( mFloatLength( %tan, 4 ) );
+}
+
+//-----------------------------------------------------------------------------
+
+function MagicTarget::repoint( %this )
+{
+    %myPosition = %this.getPosition();
+    %angle = Vector2AngleToPoint( %myPosition, AngleToy.repointTarget );
+    %this.rotateTo( %angle - 90, 360 ); // Image points at 90 degrees, so we need to subtract that off.
+    %this.setLinearVelocityPolar( %angle,
+        Vector2Length( Vector2Sub( AngleToy.repointTarget, %myPosition  ) ) );
+}
+
+//-----------------------------------------------------------------------------
+
+function LineSegment::draw( %this, %from, %to )
+{
+    %length = Vector2Distance( %from, %to );
+    %width = 0.25;
+    %mid = Vector2Scale( Vector2Add( %from, %to ), 0.5 ); // Mid-Point
+    %angle = Vector2AngleToPoint( %from, %to );
+    
+    %this.setPosition( %mid );
+    %this.setSize( %length, %width );
+    %this.setAngle( %angle );
+}
+
+function LineSegment::drawTangent( %this, %from, %tan, %angleOnCircle )
+{
+    // One of the many, many definitions of tangent is that the line that
+    // is tangent to the circle will intersect the X-axis with a length of
+    // %tangent.  It's fun, so we'll use it for this example.
+
+    // The tangent to a circle at a given angle is equal to +/- 90 degrees.
+    %tangentAngle = %angleOnCircle - 90;
+    
+    // Sine, cosine, and tangent assume a unit circle.  Let's scale to our 20 units.
+    %length = %tan * 20; 
+    
+    %tangentEnd = Vector2Add( %from, Vector2Direction( %tangentAngle, %length ) );
+    
+    %this.draw( %from, %tangentEnd );
+}

+ 10 - 0
modules/AngleToy/1/module.taml

@@ -0,0 +1,10 @@
+<ModuleDefinition
+	ModuleId="AngleToy"
+	VersionId="1"
+	Description="Demonstrates how to use most angle functions."
+	Dependencies="ToyAssets=1"
+	Type="toy"
+	ToyCategoryIndex="3"
+	ScriptFile="main.cs"
+	CreateFunction="create"
+	DestroyFunction="destroy"/>

+ 1 - 1
modules/CompositeSpriteToy/1/scripts/customLayout.cs

@@ -82,7 +82,7 @@ function CompositeSprite::onCustomLayout( %this, %args )
     %inputX = %args._0;
     
     // Calculate an angle from the first argument.
-    %angle = mDegToRad( %inputX * 10 );
+    %angle = %inputX * 10;
     
     // Calculate an interesting output position.
     %outputX = %inputX - (CompositeSpriteToy.SpriteCount * 0.5);

+ 3 - 4
modules/CompoundObjectsToy/1/main.cs

@@ -140,14 +140,13 @@ function CompoundObjectsToy::createCompoundObject( %this, %worldPosition )
     // Create compound ring.    
     for( %angle = 0; %angle < 360; %angle += %angleStride )
     {
-        %radianAngle = mDegToRad( %angle );
-        %spriteX = mSin( %radianAngle ) * %radius;
-        %spriteY = mCos( %radianAngle ) * %radius;
+        %spriteX = mCos( %angle ) * %radius;
+        %spriteY = mSin( %angle ) * %radius;
         
         %composite.addSprite();
         %composite.setSpriteLocalPosition( %spriteX, %spriteY );
         %composite.setSpriteSize( %blockSize );
-        %composite.setSpriteAngle( -%angle );
+        %composite.setSpriteAngle( %angle );
         %composite.setSpriteImage( "ToyAssets:Blocks" );
         %composite.setSpriteImageFrame( getRandom(0,55) );
     }

+ 3 - 3
modules/DeathBallToy/1/main.cs

@@ -450,7 +450,7 @@ function DeathBallToy::cancelPendingEvents()
 function DeathBallToy::onTouchDown(%this, %touchID, %worldPosition)
 {
     %origin = Deathball.getPosition();
-    %angle = -mRadToDeg( mAtan( getWord(%worldPosition,0)-getWord(%origin,0), getWord(%worldPosition,1)-getWord(%origin,1) ) );
+    %angle = mAtan( Vector2Sub( %worldPosition, %origin ) ) - 90;
 
     Deathball.RotateTo( %angle, DeathBallToy.rotateSpeed );
 
@@ -468,7 +468,7 @@ function DeathBallToy::onTouchDown(%this, %touchID, %worldPosition)
 function DeathBallToy::onTouchUp(%this, %touchID, %worldPosition)
 {
     %origin = Deathball.getPosition();
-    %angle = -mRadToDeg( mAtan( getWord(%worldPosition,0)-getWord(%origin,0), getWord(%worldPosition,1)-getWord(%origin,1) ) );
+    %angle = mAtan( Vector2Sub( %worldPosition, %origin ) );
     
     // Since the speed is used instead of time, we can use the current velocity to set it's speed.
     %adjustedSpeed = VectorLen(DeathBall.getLinearVelocity());// (DeathBallToy.ballSpeed / DeathBallToy.maxBallSpeed) * 3000;
@@ -481,7 +481,7 @@ function DeathBallToy::onTouchUp(%this, %touchID, %worldPosition)
 function DeathBallToy::onTouchDragged(%this, %touchID, %worldPosition)
 {    
     %origin = Deathball.getPosition();
-    %angle = -mRadToDeg( mAtan( getWord(%worldPosition,0)-getWord(%origin,0), getWord(%worldPosition,1)-getWord(%origin,1) ) );
+    %angle = mAtan( Vector2Sub( %worldPosition, %origin ) ) - 90;
 
     Deathball.RotateTo( %angle, DeathBallToy.rotateSpeed );
 

+ 1 - 1
modules/DeathBallToy/1/scripts/faceObjectBehavior.cs

@@ -42,7 +42,7 @@ function FaceObjectBehavior::updateFace(%this)
         return;
    
     %origin = %this.owner.getPosition();
-    %angle = -mRadToDeg( mAtan( getWord(%this.target.getPosition(),0)-getWord(%origin,0), getWord(%this.target.getPosition(),1)-getWord(%origin,1) ) );
+    %angle = mAtan( Vector2Sub( %this.target.getPosition(), %origin ) );
     
     if ( %this.turnSpeed > 0.0 )
     {

+ 1 - 1
modules/PointForceControllerToy/1/main.cs

@@ -165,7 +165,7 @@ function Planetoid::onCollision( %this, %object, %collisionDetails )
     {
         // Yes, so calculate position angle.
         %positionDelta = Vector2Sub( %object.Position, %this.Position );
-        %angle = -mRadToDeg( mAtan( %positionDelta._0, %positionDelta._1 ) );
+        %angle = mAtan( %positionDelta ) - 90;
         
         // Fetch contact position.
         %contactPosition = %collisionDetails._4 SPC %collisionDetails._5;

+ 18 - 7
modules/RotateToToy/1/main.cs

@@ -125,17 +125,23 @@ function RotateToToy::setTrackMouse( %this, %value )
 
 function RotateToToy::onTouchDown(%this, %touchID, %worldPosition)
 {
-    // Calculate the angle to the mouse.
-    %origin = RotateToToy.TargetObject.getPosition();
-    %angle = -mRadToDeg( mAtan( %worldPosition.x-%origin.x, %worldPosition.y-%origin.y ) );
-    
-    //Rotate to the touched angle.
-    RotateToToy.TargetObject.RotateTo( %angle, RotateToToy.rotateSpeed );
+    %this.rotateTargetObject( %worldPosition );
 }
 
 //-----------------------------------------------------------------------------
 
 function RotateToToy::onTouchMoved(%this, %touchID, %worldPosition)
+{
+    // Finish if not tracking the mouse.
+    if ( !RotateToToy.trackMouse )
+        return;
+        
+    %this.rotateTargetObject( %worldPosition );
+}
+
+//-----------------------------------------------------------------------------
+
+function RotateToToy::rotateTargetObject(%this, %worldPosition)
 {
     // Finish if not tracking the mouse.
     if ( !RotateToToy.trackMouse )
@@ -143,7 +149,12 @@ function RotateToToy::onTouchMoved(%this, %touchID, %worldPosition)
         
     // Calculate the angle to the mouse.
     %origin = RotateToToy.TargetObject.getPosition();
-    %angle = -mRadToDeg( mAtan( %worldPosition.x-%origin.x, %worldPosition.y-%origin.y ) );
+    %angle = mAtan( Vector2Sub( %worldPosition, %origin ) );
+    
+    // The target object points up (the 90-degree point in polar coordinates).
+    // We can simply subtract 90 from the calculate angle to make the
+    // object point to the mouse.
+    %angle -= 90;
     
     //Rotate to the touched angle.
     RotateToToy.TargetObject.RotateTo( %angle, RotateToToy.rotateSpeed );