IonicWind Software

Aurora Compiler => 3D Graphics => Topic started by: kryton9 on August 09, 2006, 10:39:47 PM

Title: Function / Subroutine Take Vector Direction return Degrees (360)
Post by: kryton9 on August 09, 2006, 10:39:47 PM
I got the function finished tonight. You just send it the vector values and it will return the heading between 0 - 360 degrees.
I will write another one that will tell you the bearing between 2 objects soon, that is-- you will know from where you are to what heading you need to move to find the second object.

// Vector to Degrees Routine
// by Kryton9 written 8/9/2006
//
Declare import,timeGetTime(),int;
VECTOR3 camDir;

global sub main()
{
C3DScreen s;
C3DCamera c;
C3DMesh m,m2;
C3DObject scene;
C3DLight light,light2,light3;
CDirectInput di;
float fadjust,fTarget;
//target 60FPS for camera movement
fTarget = 1.0f / /*FPS*/60.0f * 1000.0f;
fAdjust = 1.0f;

s.CreateWindowed(0,0,640,480,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE|AWS_CENTERED,0,"VecToDgrsÂÃ,  -ÂÃ,  Use arrow keys to move aroundÂÃ,  -ÂÃ,  Escape to quit",NULL,false);
di.Init(s);

c.Create(s);
c.Position(0,-300,0);
c.Orient(0,1,0,0,0,1);
c.SetBackPlane(10000);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
s.RenderScene();


m.CreateBox(s,25,10,50,false);
m2.CreateSphere(s,25,1000,true);

light.Create(s,LIGHT_POINT,1);
light.Position(75,75,75);
light.SetDiffuse(255, 0, 0, 255);
light.SetAttenuation(0,1/1000.0,0);
light2.Create(s,LIGHT_POINT,2);
light2.Position(-75,-75,-75);
light2.SetAttenuation(0,1/2000.0,0);
light2.SetDiffuse(0, 0, 255, 255);
light3.Create(s,LIGHT_POINT,3);
light3.Position(-75,0,75);
light3.SetAttenuation(0,1/2000.0,0);
light3.SetDiffuse(0, 255, 0, 255);

scene.CreateScene(s);
scene.AddChild(light);
scene.AddChild(m);
scene.AddChild(m2);

int fps = 0;
int startTime;
do
{
camDir = c.GetDirection();
IF di.KeyDown(DIK_UP) c.Move(0.0f,.75f);

IF di.KeyDown(DIK_DOWN) c.Move(0.0f,-.75f);

IF di.KeyDown(DIK_RIGHT)c.Rotate(.0174533/2,0,0);
IF di.KeyDown(DIK_LEFT) c.Rotate(-.0174533/2,0,0);

m.Rotate(timeGetTime()/1500.0,timeGetTime()/1500.0,0);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
scene.Draw();

s.RenderText(300,10,"Heading:ÂÃ,  "+NumToStr(VecToDgrs(camDir.x,camDir.y))+" ,ÂÃ,  camDir.x "+NumToStr(camDir.x,3)+" ,ÂÃ,  camDir.y "+NumToStr(camDir.y,3),RGBA(0,0,0,255));
s.RenderText(10,10,"FPS: "+NumToStr(fps),RGBA(0,0,0,255));

fps = s.RenderScene();
fAdjust = (timeGetTime() - startTime) / fTarget;
}until di.KeyDown(DIK_ESCAPE);
Scene.Free();
}


sub VecToDgrs(float x, float y),float
{
pi=3.14159265;
if x<0 AND y <0 {Result = 180-(180*atan(abs(x/y))/pi);}
else if x<0 AND y>0 {Result = 180*atan(abs(x/y))/pi;}
else if x>0 AND y<0 {Result = 180+(180*atan(abs(x/y))/pi);}
else if x>0 AND y>0 {Result = 360-(180*atan(abs(x/y))/pi);}
return result;
}
Title: Re: Function / Subroutine Take Vector Direction return Degrees (360)
Post by: kryton9 on August 10, 2006, 01:20:46 PM
This gives your heading (direction) in degrees 0 - 360

sub VecToDgrs(float x, float y),floatÂÃ,  ÂÃ, 


This gives you the heading you need to match to find the target object

sub HdngToTarget(double x, double y, double tx, double ty),doubleÂÃ, 

You might ask why did I use float in one and double in the other? The answer: I am not sure which to use, so was experimenting. I don't know if one is better than the other, it will be easy enough to change once someone can tell me which would be better :)

Till then enjoy, sorry about the psychedlic colors, but just wanted to show how you can do some cool things just by using lights in both examples. The heading to target comes in handy on this one as it is easy to lose the rectangle.

Enjoy :)

// Vector to Degrees Routine
// by Kryton9 written 8/9/2006
//
Declare import,timeGetTime(),int;
VECTOR3 camDir,camPos,mPos;

global sub main()
{
C3DScreen s;
C3DCamera c;
C3DMesh m,m2;
C3DObject scene;
C3DLight light,light2,light3;
CDirectInput di;
float fadjust,fTarget;
//target 60FPS for camera movement
fTarget = 1.0f / /*FPS*/60.0f * 1000.0f;
fAdjust = 1.0f;

s.CreateWindowed(0,0,640,480,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE|AWS_CENTERED,0,"VecToDgrsÂÃ,  -ÂÃ,  Use arrow keys to move aroundÂÃ,  -ÂÃ,  Escape to quit",NULL,false);
di.Init(s);

c.Create(s);
c.Position(0,-300,0);
c.Orient(0,1,0,0,0,1);
c.SetBackPlane(10000);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
s.RenderScene();


m.CreateBox(s,25,10,50,false);
m2.CreateSphere(s,25,1000,true);

light.Create(s,LIGHT_POINT,1);
light.Position(0,0,0);
light.SetDiffuse(255, 0, 0, 255);
light.SetAttenuation(0,1/1000.0,0);
light2.Create(s,LIGHT_POINT,2);
light2.Position(0,0,-300);
light2.SetAttenuation(0,1/2000.0,0);
light2.SetDiffuse(0, 0, 255, 255);
light3.Create(s,LIGHT_POINT,3);
light3.Position(-300,0,0);
light3.SetAttenuation(0,1/2000.0,0);
light3.SetDiffuse(0, 255, 0, 255);

scene.CreateScene(s);
scene.AddChild(light);
scene.AddChild(m);
scene.AddChild(m2);

int fps = 0;
int startTime;
do
{
camDir = c.GetDirection();
camPos = c.GetPosition();
mPos = m.GetPosition(0);
IF di.KeyDown(DIK_UP) c.Move(0.0f,.75f);

IF di.KeyDown(DIK_DOWN) c.Move(0.0f,-.75f);

IF di.KeyDown(DIK_RIGHT)c.Rotate(.0174533/2,0,0);
IF di.KeyDown(DIK_LEFT) c.Rotate(-.0174533/2,0,0);

m.Rotate(timeGetTime()/1500.0,timeGetTime()/1500.0,0);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
scene.Draw();

s.RenderText(300,10,"Heading:ÂÃ,  "+NumToStr(VecToDgrs(camDir.x,camDir.y))+" ,ÂÃ,  camDir.x "+NumToStr(camDir.x,3)+" ,ÂÃ,  camDir.y "+NumToStr(camDir.y,3),RGBA(128,128,128,255));//(camDir.y,3)
s.RenderText(200,30,"HeadingToTarget:ÂÃ,  "+NumToStr(HdngToTarget(camPos.x,camPos.y,mPos.x,mPos.y))+" ,ÂÃ,  camPos.x "+NumToStr(camPos.x,3)+" ,ÂÃ,  camPos.y "+NumToStr(camDir.y,3),RGBA(128,128,128,255));
s.RenderText(300,50,"Object Pos :"+"ÂÃ,  mPos.x "+NumToStr(mPos.x,3)+" ,ÂÃ,  mPos.y "+NumToStr(mPos.y,3),RGBA(128,128,128,255));
s.RenderText(10,10,"FPS: "+NumToStr(fps),RGBA(128,128,128,255));

fps = s.RenderScene();
fAdjust = (timeGetTime() - startTime) / fTarget;
}until di.KeyDown(DIK_ESCAPE);
Scene.Free();
}


sub VecToDgrs(float x, float y),float
{
pi=3.14159265;
if x<0 AND y <0 {Result = 180-(180*atan(abs(x/y))/pi);}
else if x<0 AND y>0 {Result = 180*atan(abs(x/y))/pi;}
else if x>0 AND y<0 {Result = 180+(180*atan(abs(x/y))/pi);}
else if x>0 AND y>0 {Result = 360-(180*atan(abs(x/y))/pi);}
return result;
}

sub HdngToTarget(double x, double y, double tx, double ty),double
{
temp = VecToDgrs(x-tx,y-ty);
if temp>180 {temp=temp-180;}
else if temp <180 {temp=temp+180;}
return abs(temp);
}
Title: Re: Function / Subroutine Take Vector Direction return Degrees (360)
Post by: J B Wood (Zumwalt) on August 11, 2006, 07:06:40 AM
Untested class, this is just the core begining of it, maybe you will find it useful, and I am probably off on my math, so forgive me, I hate math.. This is mainly to help you Kryton9 with your work you are doing.



class V3
{
declare _V3();
declare V3();
float x,y,z;

declare virtual add(C3DMesh obj1, C3DMesh obj2),VECTOR3;
declare virtual subtract(C3DMesh obj1, C3DMesh obj2),VECTOR3;
declare virtual multiply(C3DMesh obj1, C3DMesh obj2),VECTOR3;
declare virtual divide(C3DMesh obj1, C3DMesh obj2),VECTOR3;
declare virtual distance(VECTOR3 obj1, VECTOR3 obj2),VECTOR3;

}

V3 :: V3()
{
}

V3 :: _V3()
{
}

V3 :: add(C3DMesh obj1, C3DMesh obj2),VECTOR3
{
VECTOR3 a,b,c;
a=obj1.GetPosition(0);
b=obj2.GetPosition(0);

c.x=a.x + b.x;
c.y=a.y + b.y;
c.z=a.z + b.z;

return c;
}

V3 :: subtract(C3DMesh obj1, C3DMesh obj2),VECTOR3
{
VECTOR3 a,b,c;
a=obj1.GetPosition(0);
b=obj2.GetPosition(0);

c.x=a.x - b.x;
c.y=a.y - b.y;
c.z=a.z - b.z;

return c;
}

V3 :: multiply(C3DMesh obj1, C3DMesh obj2),VECTOR3
{
VECTOR3 a,b,c;
a=obj1.GetPosition(0);
b=obj2.GetPosition(0);

c.x=a.x * b.x;
c.y=a.y * b.y;
c.z=a.z * b.z;

return c;
}

V3 :: divide(C3DMesh obj1, C3DMesh obj2),VECTOR3
{
VECTOR3 a,b,c;
a=obj1.GetPosition(0);
b=obj2.GetPosition(0);

c.x=a.x / b.x;
c.y=a.y / b.y;
c.z=a.z / b.z;

return c;
}

V3 :: distance(VECTOR3 obj1, VECTOR3 obj2),VECTOR3
{
VECTOR3 diff;
diff.x = obj1.x - obj2.x;
diff.y = obj1.y - obj2.y;
diff.z = obj1.z - obj2.z;
return diff;
}
Title: Degrees to Rads, Rads to Degrees
Post by: kryton9 on August 19, 2006, 04:07:06 PM
Came across this nice simple method of converting between the 2 systems.

Rads to Degrees:  Rad / 0.0174532925 = Degrees

Degrees ro Rads:  Degrees * 0.0174532925 = Rads

pi / 180 = 0.0174532925
Title: Re: Function / Subroutine Take Vector Direction return Degrees (360)
Post by: kryton9 on August 19, 2006, 08:17:28 PM
Here is another useful routine. You send it an angle, in degrees, it returns back the wrapped value within 0 and 360 degrees.

WrapValue(float angleDegrees), float
{
   float angle;
   angleDegrees = angleDegrees / 360.0;
   angle = ( angleDegrees - Floor( angleDegrees ) ) * 360.0;
   return angle;
}
Title: Re: Function / Subroutine Take Vector Direction return Degrees (360)
Post by: kryton9 on September 02, 2006, 01:06:37 AM
Made the previous Sub even more functional. You can send it Degrees or Rads.

If you send it an angle in Rads, just put a positive int after as a second parameter, it will return back in degrees.
If it is in Degrees already, just leave the optional parameter blank.

So to send a Rad Angle:
WrapValue(-0.12345,1);

To send an Angle in Degrees:
WrapValue(752);

sub WrapValue(float angle, opt int Rad), float
{
   float angleDegrees;
   if (Rad)  angle = angle / 0.0174532925;
   angle = angle / 360.0;
   angleDegrees = ( angle - Floor( angle ) ) * 360.0;
   return angleDegrees;
}
Title: Re: Function / Subroutine Take Vector Direction return Degrees (360)
Post by: kryton9 on September 02, 2006, 01:24:39 PM
Is there a way I can make the function in the previous reply, faster. It is something I will be calling a lot in the future I know, and I would like to make sure it is as fast as can be.
Might as well start learning about writing faster routines.
Title: Re: Function / Subroutine Take Vector Direction return Degrees (360)
Post by: Ionic Wind Support Team on September 02, 2006, 01:42:45 PM
Yes.  Make sure your not doing unneccessary conversions from double to float.


sub WrapValue(float angle, opt int Rad), float
{
   float angleDegrees;
   if (Rad)  angle = angle / 0.0174532925f;
   angle = angle / 360.0f;
   angleDegrees = ( angle - Floor( angle ) ) * 360.0f;
   return angleDegrees;
}
Title: Re: Function / Subroutine Take Vector Direction return Degrees (360)
Post by: kryton9 on September 02, 2006, 02:01:06 PM
Thanks Paul and thanks again for the LookAt command, that is going to make life a lot easier and funner with 3D calcs!!