# C++ QuestionNeed help returning local direction's angle to sun

#### Mr Martian

Donator
Hi All,

I would appreciate help with something rather complicated which I just can't seem to be able to approach on my own.

I want to return the 'angle' to the sun of a direction vector in local-vessel frame. To better explain I have posted below code which achieves something simillar.

C++:
    VECTOR3 toSun, solpos, gpos;
oapiGetGlobalPos(oapiGetGbodyByIndex(0), &solpos);
oapiGetGlobalPos(vessel->GetHandle(), &gpos);

MATRIX3 R;
oapiGetRotationMatrix(vessel->GetHandle(), &R);
toSun = tmul(R, solpos - gpos);

double ang_s = fabs(atan2(toSun.x, toSun.z)) / PI;
double ang_a = fabs(atan2(toSun.y, toSun.z)) / PI;
//double ang_r = fabs(atan2(toSun.x, toSun.y)) / PI;
return (ang_s + ang_a) / 2;

The above is tailored for another purpose; to take the vessel's AOA and slip angle to the sun, and return a number between 0-1, with 0 being pointed directly at the sun and 1 being pointed directly away. I keep trying to work with this as a starting-point but have found myself going round in circles. I don't think this is the right approach but I have reached an impass!

What I would like, is to be able to have a direction vector in local frame (for example 0,1,0: pointed straight up) and return the same 0-1 value based on this vector's angle to the sun. I need for the vector to be able to be dynamic, say for if I wanted it to rotate around the vessel, say starting as (0,1,0) and ending as (0,0,-1). Essentially this is for solar panel simulation, but I would like for the solar panel's direction to be able to be any direction (in case of solar tracking). I know this is probabloy a very roundabout way of tackling this, but I am developing this as part of an SDK, which is why I have need for such a universal-approach.

Thank you anyone who can help me with this, any help is greatly appreciated!

MrMartian

#### Gondos

##### Active member
Hi All,

I would appreciate help with something rather complicated which I just can't seem to be able to approach on my own.

I want to return the 'angle' to the sun of a direction vector in local-vessel frame. To better explain I have posted below code which achieves something simillar.

C++:
    VECTOR3 toSun, solpos, gpos;
oapiGetGlobalPos(oapiGetGbodyByIndex(0), &solpos);
oapiGetGlobalPos(vessel->GetHandle(), &gpos);

MATRIX3 R;
oapiGetRotationMatrix(vessel->GetHandle(), &R);
toSun = tmul(R, solpos - gpos);

double ang_s = fabs(atan2(toSun.x, toSun.z)) / PI;
double ang_a = fabs(atan2(toSun.y, toSun.z)) / PI;
//double ang_r = fabs(atan2(toSun.x, toSun.y)) / PI;
return (ang_s + ang_a) / 2;

The above is tailored for another purpose; to take the vessel's AOA and slip angle to the sun, and return a number between 0-1, with 0 being pointed directly at the sun and 1 being pointed directly away. I keep trying to work with this as a starting-point but have found myself going round in circles. I don't think this is the right approach but I have reached an impass!

What I would like, is to be able to have a direction vector in local frame (for example 0,1,0: pointed straight up) and return the same 0-1 value based on this vector's angle to the sun. I need for the vector to be able to be dynamic, say for if I wanted it to rotate around the vessel, say starting as (0,1,0) and ending as (0,0,-1). Essentially this is for solar panel simulation, but I would like for the solar panel's direction to be able to be any direction (in case of solar tracking). I know this is probabloy a very roundabout way of tackling this, but I am developing this as part of an SDK, which is why I have need for such a universal-approach.

Thank you anyone who can help me with this, any help is greatly appreciated!

MrMartian
A dot product should give you something in the range [1;-1] where 1 is pointed directly to the sun and -1 away from it I think.
The two vectors need to be normalized and in the same reference frame.
Maybe you can take a look at NASSP's high gain antenna code, I guess they must be doing something similar

#### Mr Martian

Donator
A dot product should give you something in the range [1;-1] where 1 is pointed directly to the sun and -1 away from it I think.
The two vectors need to be normalized and in the same reference frame.
Maybe you can take a look at NASSP's high gain antenna code, I guess they must be doing something similar
Thanks for the reply! From what I can see in NASSP's code it doesn't really work out for what I am trying. As for your suggestion, I think that is straight-forward enough, but one thing I am really having diofficulty with is creating a rotation matrix for my defined direction vecotr in the vessel's frame. For instance I can call GetRotationMatrix() to get the rotation matrix for my vessel, but how would I go about doing this for a defined vectore? I am having a hard time wrapping my head around matracies...

#### Gondos

##### Active member
Thanks for the reply! From what I can see in NASSP's code it doesn't really work out for what I am trying. As for your suggestion, I think that is straight-forward enough, but one thing I am really having diofficulty with is creating a rotation matrix for my defined direction vecotr in the vessel's frame. For instance I can call GetRotationMatrix() to get the rotation matrix for my vessel, but how would I go about doing this for a defined vectore? I am having a hard time wrapping my head around matracies...
I'm no math wiz but usually when you have a matrix and a vector, you end up multiplying them
The art is in finding the right order when doing so
Regarding you solar panel feature, you may want to take a look at vVessel::ModLighting (LPD3DLIGHT7 light), looks like it computes the fraction of light available after taking into account the closest planetary shadow

#### martins

##### Orbiter Founder
Orbiter Founder
The code snippet in your first post is already a good start. The "toSun" vector you are calculating is the position of the sun in local vessel coordinates. The only things remaining are:
- normalisation, to get the sun's direction vector:
Code:
  VECTOR3 toSunDir = unit(toSun);
- dot product, to get the direction cosine:
Code:
  double cosdir = dotp(MyLocalDir, toSunDir);
- inverting the cosine, to get the angle:
Code:
  double dir = acos(cosdir)

#### Mr Martian

Donator
The code snippet in your first post is already a good start. The "toSun" vector you are calculating is the position of the sun in local vessel coordinates. The only things remaining are:
- normalisation, to get the sun's direction vector:
Code:
  VECTOR3 toSunDir = unit(toSun);
- dot product, to get the direction cosine:
Code:
  double cosdir = dotp(MyLocalDir, toSunDir);
- inverting the cosine, to get the angle:
Code:
  double dir = acos(cosdir)
Thank you so much Martins! That is perfect, works exactly how I need it to now. I think I need to familiarize myself with the math functions more... I often find myself neglecting to use them...

Thanks again!

Replies
10
Views
1K
Replies
1
Views
438
Replies
32
Views
2K
Replies
19
Views
1K
Replies
2
Views
643