我可以在网上找到LUA中只有一个功能,但它提供了错误的值(使用专业的在线工具测量)。
看起来从中午到中午之后数学运算起来,但之后,太阳的角度又回到了日出的位置。应该从106°到253°,目前从106°到180°到106°。
我正在使用的功能:
-- solar altitude, azimuth (degrees)
function sunposition(latitude, longitude, time)
time = time or os.time()
if type(time) == 'table' then time = os.time(time) end
local date = os.date('*t', time)
local timezone = (os.time(date) - os.time(os.date('!*t', time))) / 3600
if date.isdst then timezone = timezone + 1 end
local utcdate = os.date('*t', time - timezone * 3600)
local latrad = math.rad(latitude)
local fd = (utcdate.hour + utcdate.min / 60 + utcdate.sec / 3600) / 24
local g = (2 * math.pi / 365.25) * (utcdate.yday + fd)
local d = math.rad(0.396372 - 22.91327 * math.cos(g) + 4.02543 * math.sin(g) - 0.387205 * math.cos(2 * g)
+ 0.051967 * math.sin(2 * g) - 0.154527 * math.cos(3 * g) + 0.084798 * math.sin(3 * g))
local t = math.rad(0.004297 + 0.107029 * math.cos(g) - 1.837877 * math.sin(g)
- 0.837378 * math.cos(2 * g) - 2.340475 * math.sin(2 * g))
local sha = 2 * math.pi * (fd - 0.5) + t + math.rad(longitude)
local sza = math.acos(math.sin(latrad) * math.sin(d) + math.cos(latrad) * math.cos(d) * math.cos(sha))
local saa = math.acos((math.sin(d) - math.sin(latrad) * math.cos(sza)) / (math.cos(latrad) * math.sin(sza)))
return 90 - math.deg(sza), math.deg(saa)
end
请求示例:
lat, long = 45.327063, 14.442176 -- Rijeka, Croatia
time = {year=2016, month=2, day=17, hour=17, min=30} -- end of the day
altitude, azimuth = sunposition(lat, long, time)
结果是:
结果应为:
我在其他编程语言中找到了多个解决方案,甚至尝试在Lua中重写但没有任何成功。解决方案背后的数学太复杂了。
我将其用于我的 Corona SDK 应用,该应用将显示Sun相对于设备的位置。目前唯一可行的解决方案是PHP或Javascript脚本,我的应用程序可以通过Internet上的API调用询问,但我真的想避免这种情况。
我非常感谢社区的帮助。谢谢你,爱你们! :)
答案 0 :(得分:2)
我找到了解决此问题的方法/黑客。
功能仍然相同:
-- solar altitude, azimuth (degrees)
function sunposition(latitude, longitude, time)
time = time or os.time()
if type(time) == 'table' then time = os.time(time) end
local date = os.date('*t', time)
local timezone = (os.time(date) - os.time(os.date('!*t', time))) / 3600
if date.isdst then timezone = timezone + 1 end
local utcdate = os.date('*t', time - timezone * 3600)
local latrad = math.rad(latitude)
local fd = (utcdate.hour + utcdate.min / 60 + utcdate.sec / 3600) / 24
local g = (2 * math.pi / 365.25) * (utcdate.yday + fd)
local d = math.rad(0.396372 - 22.91327 * math.cos(g) + 4.02543 * math.sin(g) - 0.387205 * math.cos(2 * g)
+ 0.051967 * math.sin(2 * g) - 0.154527 * math.cos(3 * g) + 0.084798 * math.sin(3 * g))
local t = math.rad(0.004297 + 0.107029 * math.cos(g) - 1.837877 * math.sin(g)
- 0.837378 * math.cos(2 * g) - 2.340475 * math.sin(2 * g))
local sha = 2 * math.pi * (fd - 0.5) + t + math.rad(longitude)
local sza = math.acos(math.sin(latrad) * math.sin(d) + math.cos(latrad) * math.cos(d) * math.cos(sha))
local saa = math.acos((math.sin(d) - math.sin(latrad) * math.cos(sza)) / (math.cos(latrad) * math.sin(sza)))
return 90 - math.deg(sza), math.deg(saa)
end
修复此问题的已添加代码:
function getSunPos(lat, long, time)
findTime = {}
findTime.hour, findTime.min = time.hour, time.min
fixedAzimuthLast, fixedAzimuth = 0, 0
for i=0,23 do
for j=0,59 do
time.hour, time.min = i, j
local altitude, azimuth = sunposition(lat, long, time)
-- fix azimuth
if fixedAzimuthLast < azimuth then
fixedAzimuthLast = azimuth
fixedAzimuth = fixedAzimuthLast
else
fixedAzimuth = fixedAzimuthLast + (180 - azimuth)
end
-- find azimuth at target time
if findTime.hour == i and findTime.min == j then
-- final result
return altitude, fixedAzimuth
end
end
end
end
最后得到正确的结果:
lat, long = 45.327063, 14.442176
altitude, azimuth = getSunPos(lat, long, os.date('*t', os.time()))
就是这样。 我会更乐于使用正确完成数学运算的完整函数,但这就足够了。它可以在全球3个地点使用并进行测试。
答案 1 :(得分:1)
角度的Arccos等于360度角,因为它们的余弦值相等。你可以简单地返回360度角。