Если вы хотите, чтобы он был физически точным, вам нужно учитывать два смещения: вертикальное (в зависимости от текущей даты) и горизонтальное (в зависимости от текущего времени).
Горизонтальное смещение Xможно рассчитать, посмотрев на текущее время в некотором фиксированном географическом местоположении на земле.Смещение тени будет 0 в полночь и будет увеличиваться на 1/86400 каждые секунды после полуночи.Таким образом, формула имеет вид
offsetX = (curHour*3600 + curMinute*60 + curSeconds)/86400
Вертикальное смещение будет изменяться между Солнцестояниями 21 июня и 22 декабря (если это не високосный год, когда Солнцестояния происходят 20 июня и декабря21-е).Максимальные углы составляют 23,44 ° в обоих направлениях.У нас 90 ° на полушарие и 365/2 = 182,5 дня между двумя солнцестояниями, и мы работаем с отображением кругового движения, поэтому необходимо использовать функцию sin ().Длина волны синусоидальной волны равна 2pi, поэтому нам нужно пи для половины вертикального смещения Y одного года.
Обратите внимание, что я не учел високосные секунды, поэтому вычисление может быть немного неправильнымв далеком прошлом / будущем.
// current time
$curHour = date("H");
$curMin = date("i");
$curSec = date("s");
// resulting offset X
$offsetX = ($curHour*3600 + $curMin*60 + $curSec)/86400;
echo "======== OFFSET X ==========\n";
echo "curHour: $curHour\n";
echo "curMin: $curMin\n";
echo "curSec: $curSec\n";
echo "offsetX: $offsetX\n\n";
// spring equinox date as day of year
$equinox = date("z", mktime(0, 0, 0, 3, 20));
// current day of year
// first line is for testing purposes
//$curDay = date("z", mktime(0, 0, 0, 6, 21));
$curDay = date("z");
// Day offset, mapped on the equinox offset
$offsetSin = ((365.25 - $equinox + $curDay)%365.25)/365.25;
// sinus wave offset
$offsetSinFactor = sin($offsetSin * 2 * pi());
// map onto angle
$offsetY = $offsetSinFactor * 23.44;
// optional: Mercator projection
$degreesPerRadian = 180.0 / pi();
$offsetYmercator = atan(sinh($offsetY)) * $degreesPerRadian;
// missing: mapping onto canvas height (it's currently
// mapped on $offsetY = 90 as the total height of the
// canvas.
echo "========= OFFSET Y =========\n";
echo "equinox day: $equinox\n";
echo "curDay: $curDay\n";
echo "offsetSin: $offsetSin\n";
echo "offsetSinFac: $offsetSinFactor\n";
echo "offsetY: $offsetY\n";
echo "offsetYmerc: $offsetYmercator\n";
Вы должны быть в состоянии перенести этот расчет на любой язык.