8

我正在使用 PyEphem 并想计算阴影的长度(假设在地下种植了一根单位长度的棍子)。长度将由 cot(phi) 给出,其中 phi 是太阳仰角(如果我错了,请纠正我)。我不确定在太阳上使用什么场?在下面的示例中,我使用角度 alt:

import ephem, math
o = ephem.Observer()
o.lat, o.long = '37.0625', '-95.677068'
sun = ephem.Sun()
sunrise = o.previous_rising(sun, start=ephem.now())
noon = o.next_transit(sun, start=sunrise)
shadow = 1 / math.tan(sun.alt)

请在下面查看我的解释:

  1. 如果切线是无限的,则表明太阳直接在头顶,没有阴影。
  2. 如果切线为零,则表明太阳在地平线上,阴影无限长。
  3. 我不知道如何解释 cot(phi) 的负面结果。有人能帮我吗?

最后,在给定 ephem.Observer() 的情况下,我对如何使用 PyEphem 从阴影长度向后工作到下一次太阳将投射该长度的阴影感到困惑。

我会很感激这方面的帮助。

4

1 回答 1

10

what field to use on the Sun?

The sun.alt is correct. alt is an altitude above horizon; together with an azimuth east of north they define an apparent position relative to horizon.

Your calculations are almost correct. You've forgot to supply an observer: sun = ephem.Sun(o).

  1. I don't know how to interpret negative results from cot(phi). Can someone help me?

The Sun is below horizon in this case.

Finally, I'm confused about how to use PyEphem to work backwards from a shadow length to the next time when the sun will cast a shadow of that length, given an ephem.Observer().

Here's a script that given a function: g(date) -> altitude computes the next time when the sun will cast a shadow with the same length as right now (an azimuth -- direction of the shadow is not considered):

#!/usr/bin/env python
import math
import ephem    
import matplotlib.pyplot as plt
import numpy as np
import scipy.optimize as opt

def main():
    # find a shadow length for a unit-length stick
    o = ephem.Observer()
    o.lat, o.long = '37.0625', '-95.677068'
    now = o.date
    sun = ephem.Sun(o) #NOTE: use observer; it provides coordinates and time
    A = sun.alt
    shadow_len = 1 / math.tan(A)

    # find the next time when the sun will cast a shadow of the same length
    t = ephem.Date(find_next_time(shadow_len, o, sun))
    print "current time:", now, "next time:", t # UTC time
    ####print ephem.localtime(t) # print "next time" in a local timezone

def update(time, sun, observer):
    """Update Sun and observer using given `time`."""
    observer.date = time
    sun.compute(observer) # computes `sun.alt` implicitly.
    # return nothing to remember that it modifies objects inplace

def find_next_time(shadow_len, observer, sun, dt=1e-3):
    """Solve `sun_altitude(time) = known_altitude` equation w.r.t. time."""
    def f(t):
        """Convert the equation to `f(t) = 0` form for the Brent's method.

        where f(t) = sun_altitude(t) - known_altitude
        """
        A = math.atan(1./shadow_len) # len -> altitude
        update(t, sun, observer)
        return sun.alt - A

    # find a, b such as f(a), f(b) have opposite signs
    now = observer.date # time in days
    x = np.arange(now, now + 1, dt) # consider 1 day
    plt.plot(x, map(f, x))
    plt.grid(True)
    ####plt.show()
    # use a, b from the plot (uncomment previous line to see it)
    a, b = now+0.2, now+0.8

    return opt.brentq(f, a, b) # solve f(t) = 0 equation using Brent's method


if __name__=="__main__":
    main()

Output

current time: 2011/4/19 23:22:52 next time: 2011/4/20 13:20:01
于 2011-04-19T23:09:02.823 回答