Hi tomnagel, and welcome to the forum!

During some of my earliest attempts at getting a heliostat to work, I thought that calculating the heliostat's position could be done the way you described. After some experimenting with some CAD drawings in Sketchup though, I realized that it doesn't work. The calculated angle is sort of in the ballpark, but can still be several degrees off from where it should be. The method is perfectly sound in 2D, but once you move to 3D it gets a fair bit more complicated.

I have pasted most of the "FindHeliostatAngle" function below. I just realized that I never got around to writing comments to explain what everything does. I would need a good picture to explain it in depth, but if you know your trig and a little bit of vector math, you should still be able to get the gist of it.

First, the code takes the altitude and azimuth of the sun and turns it into a vector,

**v1**=<x1,y1,z1>.

z1 = sin(to_rad(altitude));

hyp = cos(to_rad(altitude));

x1 = hyp*cos(to_rad(azimuth));

y1 = hyp*sin(to_rad(azimuth));

It also turns the target altitude and azimuth into a vector,

**v2**=<x2,y2,z2>.

z2 = sin(to_rad(targetalt));

hyp = cos(to_rad(targetalt));

x2 = hyp*cos(to_rad(targetaz));

y2 = hyp*sin(to_rad(targetaz));

The "half way vector" is then calculated with the below code. This represents the direction that the normal vector of the mirror's surface needs to point.

Note: The below code can be written more succinctly in vector notation as

**v3**=(

**v1**-

**v2**)/2+

**v2** where

**v3**=<x,y,z>

x=(x1-x2)/2+x2;

y=(y1-y2)/2+y2;

z=(z1-z2)/2+z2;

The below code has a very low likelihood of ever running, but is present to avoid getting z/0 (which is undefined) if the variable "dist" turns out to be 0. This would only happen if the target vector

**v2** is pointing in the exact opposite direction as

**v1**, so essentially if the target is exactly 180 degrees from the sun in relation to the heliostat.

dist=sqrt(x*x+y*y+z*z);

if ((dist>-0.000001) && (dist <0.000001)){

dist=0.000001;

}

Finally, the vector

**v3** is turned into an angle measurement which gives the altitude and azimuth of the mirror's normal vector of the heliostat.

machinealt=to_deg(asin(z/dist));

if (x==0){x=0.000001;} (looking at this line of code again, I'm doubtful that it is needed)

machineaz=to_deg(atan2(y,x));

I'm sure there are other ways of doing these calculations, but this is what I came up with. I've done a lot of testing with some simulations I wrote in Matlab, and the code worked perfect in them, so I'm pretty happy with it.

An earlier version of this program used the calculations on this pdf.

http://www.tapthesun.com/PDF/PSTC%20-%20Heliostat%20Reflection%20Equations.pdfI eventually realized that they would break when certain inputs were used, so I had to upgrade to the current calculations. It could be that I over looked something on the pdf, but I figured that it would be easier to just come up with something from scratch instead of trying to figure out what was wrong.

Hope that helps,

Gabriel