问题描述
Pyephem以[0.0,1.0]中的数字为我提供亮度,> 0刚好在新月之后,
我正在创建月球的图形表示,因此,我试图呈现天文学上正确的月牙(或月球?)。
我的系统使用Pygame进行音频和图形处理,但是看起来填充区域在matplotlib中更容易使用,并且我为这两种技术都提供了连接器,因此解决方案可以使用这两种技术。
到目前为止,我的方法是渲染一个白色圆圈和一个黑色圆圈,将其涂在临时曲面上,在该曲面上调整Alpha。稍后,我将计算当前月球的名称,并根据月球名称(例如,狼月,血月等)来选择背景。
我当前的代码有点像月相,但是看起来不太正确。我不确定从哪里开始寻找正确的参数...我认为主要的问题是找出食偏圆的比例,然后找出其中心的正确偏移量。
def arc_patch (ax,lunacity): # https://stackoverflow.com/questions/58263608/fill-between-arc-patches-matplotlib
ax.grid (False)
xmin = -85 # Todo don't use magic numbers
xmax = +85
xrng = xmax - xmin
ymin = -85
ymax = +85
yrng = ymax - ymin
ax.set_xlim (xmin,xmax)
ax.set_ylim (ymin,ymax)
# Use a predefined colormap
colormap = []
# Draw multiple ellipses with different colors and style. All are perfectly superposed
ellipse = mpl.patches.Ellipse ( # Base one,with big black line for reference
ORIGIN,xrng,yrng,color='k',fill=False,zorder=100) # Todo what is zorder ?
# Define some clipping paths
# One for each area
clips = [
mpl.patches.Arc ( # the moon,both light and dark
ORIGIN,theta1=0,theta2=360,visible=False # We do not need to display it,just to use it for clipping
),]
colormap.append ('purple') # invisible
if lunacity < .25: # 0,.25 => new moon,first quarter moon
print ("q0-q1")
lun = lunacity * 4 # 0,1.
lun = 1 - lun # 1,0.
lun = 1 / lun # 1,inf
rx,ry = xrng,yrng * lun
X,Y = ORIGIN # center of light circle
X = X - (rx / 2) * ((lunacity - 0) * 4)
x,y = X,Y # center of dark circle
Arc1_xy = x,y
# draw light circle,then dark circle
light_patch = mpl.patches.Ellipse (
ORIGIN,visible=False)
dark_patch = mpl.patches.Ellipse (
Arc1_xy,rx,ry,visible=False)
colormap.append ('white')
colormap.append ('black')
clips.append (light_patch)
clips.append ( dark_patch)
elif lunacity < .5: # .25,.5 => first quarter moon,full moon
print ("q1-q2")
assert .25 <= lunacity
lun = lunacity - .25 # 0.,.25
assert lun >= 0
assert lun < .25
lun = lun * 4 # 0.,1.
assert lun >= 0
assert lun < 1
lun = 1 / lun # inf,1.
assert lun >= 1
print ("lun: %s" % (lun,))
rx,Y = ORIGIN # center of dark circle
X = X + (rx / 2) * (1 - ((lunacity - .25) * 4))
x,Y # center of light circle
Arc1_xy = x,y
print ("(x: %s,y: %s),(w: %s,h: %s)" % (x,y,ry))
# draw dark circle,then light circle
dark_patch = mpl.patches.Ellipse (
ORIGIN,visible=False)
light_patch = mpl.patches.Ellipse (
Arc1_xy,visible=False)
colormap.append ('black')
colormap.append ('white')
clips.append ( dark_patch)
clips.append (light_patch)
elif lunacity < .75: # .5,.75 => full moon,third quarter moon
print ("q2-q3")
assert .5 <= lunacity
lun = lunacity - .5 # 0.,1.
assert lun >= 0
assert lun < 1
lun = 1 - lun # 1.,0.
assert lun > 0
assert lun <= 1
lun = 1 / lun # 1.,inf
assert lun >= 1
print ("lun: %s" % (lun,Y = ORIGIN # center of light circle
X = X - (rx / 2) * ((lunacity - .5) * 4)
x,visible=False)
colormap.append ('black')
colormap.append ('white')
clips.append ( dark_patch)
clips.append (light_patch)
elif lunacity < 1.0: # .75,1. => third quarter moon,full moon
print ("q3-q4")
assert .75 <= lunacity
lun = lunacity - .75 # 0.,1.
assert lun > 1
print ("lun: %s" % (lun,Y = ORIGIN # center of light circle
X = X + (rx / 2) * (1 - ((lunacity - .75) * 4))
x,ry))
# draw light circle,visible=False)
colormap.append ('white')
colormap.append ('black')
clips.append (light_patch)
clips.append ( dark_patch)
n = len (clips)
# Ellipses for your sub-areas.
# Add more if you want more areas
# Apply the style of your areas here (colors,alpha,hatch,etc.)
areas = [
mpl.patches.Ellipse (
ORIGIN,# Perfectly fit your base ellipse
color=colormap [i],fill=True,alpha=1.0,# Add some style,fill,color,alpha
zorder=i)
for i in range (n) # Here,we have 4 areas
]
# Add all your components to your axe
ax.add_patch (ellipse)
for area,clip in zip (areas,clips):
ax.add_patch (area)
ax.add_patch (clip)
area.set_clip_path (clip) # Use clipping paths to clip you areas
更多地研究了问题之后,我发现我正在向后看椭圆的轴。修改后,我有了这个,但是圆弧的起始/结束角度出了点问题(看来matplotlib遵守了theta1和theta2)或剪辑顺序:
if lunacity < .25: # 0,0.
rx,ry = xrng * lun,yrng
# dark left,dark middle,light right
light_patch = mpl.patches.Ellipse ( # right half
ORIGIN,visible=False) # theta1=-90,theta2=+90
dark_patch = mpl.patches.Ellipse ( # center
ORIGIN,visible=False)
dark_patch2 = mpl.patches.Arc ( # left half
ORIGIN,theta1=+90,theta2=+270,visible=False)
colormap.append ('black')
colormap.append ('white')
colormap.append ('black')
clips.append ( dark_patch2)
clips.append (light_patch)
clips.append ( dark_patch)
elif lunacity < .5: # .25,1.
assert lun >= 0
assert lun < 1
rx,light middle,light right
light_patch2 = mpl.patches.Ellipse ( # right
ORIGIN,theta2=+90
dark_patch = mpl.patches.Arc ( # left
ORIGIN,visible=False)
light_patch = mpl.patches.Ellipse ( # middle
ORIGIN,visible=False)
colormap.append ('white')
colormap.append ('black')
colormap.append ('white')
clips.append (light_patch2)
clips.append ( dark_patch)
clips.append (light_patch)
elif lunacity < .75: # .5,0.
assert lun > 0
assert lun <= 1
rx,yrng
# light left,dark right
light_patch2 = mpl.patches.Ellipse ( # left
ORIGIN,visible=False) # theta1=+90,dark_patch = mpl.patches.Arc ( # right
ORIGIN,theta1=-90,theta2=+90,visible=False)
colormap.append ('white')
colormap.append ('black')
colormap.append ('white')
clips.append (light_patch2)
clips.append ( dark_patch)
clips.append (light_patch)
elif lunacity < 1.0: # .75,yrng
# light left,dark right
dark_patch2 = mpl.patches.Ellipse ( # right
ORIGIN,theta2=+90
light_patch = mpl.patches.Arc ( # left
ORIGIN,visible=False)
dark_patch = mpl.patches.Ellipse ( # middle
ORIGIN,visible=False)
colormap.append ('black')
colormap.append ('white')
colormap.append ('black')
clips.append ( dark_patch2)
clips.append (light_patch)
clips.append ( dark_patch)
解决方法
几何:
“观察者所看到的球形物体(最显着的是月亮)的发光面的形状似乎少于被太阳照亮的一半,而形状不同于通常称为平面的月牙形几何:假设终结器位于一个大圆上,那么新月形月亮实际上将以半椭圆和半圆为界,椭圆的长轴与半圆的直径重合。” >
(https://en.wikipedia.org/wiki/Crescent#Shape)
我不知道为什么要打补丁.Arc没有使用theta1和theta2,所以我切换到了patch.Rectangle:
light_patch2 = mpl.patches.Rectangle ( # right
*rrect,visible=False)
dark_patch = mpl.patches.Rectangle ( # left
*lrect,visible=False)
light_patch = mpl.patches.Ellipse ( # middle
ORIGIN,rx,ry,visible=False)
colormap.append ('white')
colormap.append ('black')
colormap.append ('white')
clips.append (light_patch2)
clips.append ( dark_patch)
clips.append (light_patch)