2008-12-06 118 views
2

我想弄清楚下面的问题。 我正在建设另一个数学函数grapher,该函数绘制在其预定义的x,y范围内,这一切都很好。滴答功能绘图仪

现在我正在处理X,Y轴的背景和滴答声(如果显示任何轴)。

我制定了以下内容。 我的固定宽度为250 p 刻度线间隔应在12.5至50p之间。

蜱应表明单位或半单位范围,我的意思是以下几点。

x量程(-5,5):一个刻度= 1个

x量程(-1,1):一个刻度= 0.5或0.1,具体取决于各该选项将产生的间隙。

X系列(0.1 0.3):0.05

给出一个XRANGE 你将如何得到完全或半单位范围之间的刻度数?

或者也许还有其他方法来解决这类问题。

回答

4

做到这一点的一种方法是“标准化”最小值和最大值之间的差异,并对该值进行区分。在python中:

delta = maximum - minimum 
factor = 10**math.ceil(math.log(delta,10)) # smallest power of 10 greater than delta 
normalised_delta = delta/factor   # 0.1 <= normalised_delta < 1 
if normalised_delta/5 >= 0.1: 
    step_size = 0.1 
elif normalised_delta/5 >= 0.05: 
    step_size = 0.05 
elif normalised_delta/20 <= 0.01: 
    step_size = 0.01 
step_size = step_size * factor 

上面的代码假设你想要尽可能大的差距。对于最小的,你可以使用以下,如果:

if normalised_delta/20 == 0.005: 
    step_size = 0.005 
elif normalised_delta/20 <= 0.01: 
    step_size = 0.01 
elif normalised_delta/5 >= 0.05: 
    step_size = 0.05 

除了可能有不止一个合适的值,也有点令人担忧的可能性,有没有。以范围[0,24]为例,其中12.5p的间隔将给出1.2的步长,而50p的间隙将给出步长4.8。中间没有“单位”或“半个单位”。问题在于12.5p和50p之间的差距是因子4,而0.01和0.05之间的差异是因子5.因此,您必须稍微扩大可允许的间隔范围并相应地调整代码。

澄清一些幻数:20和5的分别对应分别具有最小和最大间隙大小的段数(即250/12.5和250/50)。由于标准化差值在[0.1,1)范围内,因此可以将它除以20和5分别给出[0.005,0.05)和[0.02,0.2)。这些范围导致第一范围可能的(标准化)步长为0.005和0.01,第二范围为0.05和0.1。

+0

谢谢!因子= 10 ** math.ceil(math.log(delta,10))做了tric! – coulix 2008-12-07 09:36:48

0

使用DELTAX

如果DELTAX和 之间2 10个半增量如果要是小于2 20 DELTAX之间10和单位增量 我们乘以10再测试 如果大于20我们把 然后我们得到第一个单位或半个增量的位置在宽度上使用xmin。

我仍然需要测试这个解决方案。

0

你可能想看看Jgraph,它解决了一个互补的问题:它是一个数据绘图器而不是函数绘图器。但是有很多共同点,例如处理主要和次要的刻度线,轴标签等等。我发现输入语言对我来说有点冗长,但Jgraph生成非常好的技术图。网站上有很多例子,可能有些好主意可以偷取。

你知道他们在说什么:人才模仿,但天才偷:-)

0

这似乎做什么我期待。

进口数学

高清的main(): getTickGap(-1,1.5)

高清next_multiple(X,Y): 回报math.ceil(X/Y)* Y

DEF getTickGap(XMIN,XMAX): xdelta = XMAX -xmin 宽度= 250 #最小的10大于δ 因子= 10 ** math.ceil(math.log(xdelta,10)) #0.1更大的功率< =正常化d_delta normalised_delta = xdelta /因子 打印( “normalised_delta”,normalised_delta)

# we want largest gap 
if normalised_delta/4 >= 0.1: 
    step_size = 0.1 
elif normalised_delta/4 >= 0.05: 
    step_size = 0.05 
elif normalised_delta/20 <= 0.01: 
    step_size = 0.01 
step_size = step_size * factor 


## if normalised_delta/20 == 0.005: 
##  step_size = 0.005 
## elif normalised_delta/20 <= 0.01: 
##  step_size = 0.01 
## elif normalised_delta/4 >= 0.05: 
##  step_size = 0.05 
## step_size = step_size * factor 
print("step_size", step_size) 
totalsteps = xdelta/step_size 
print("Total steps", totalsteps) 
print("Range [", xmin, ",", xmax, "]") 

firstInc = next_multiple(xmin, step_size) 
count = (250/xdelta)*(firstInc - xmin) 
print("firstInc ", firstInc, 'tick at ', count) 
print("start at ", firstInc - xmin, (width/totalsteps)*(firstInc - xmin)) 
inc = firstInc 

while (inc <xmax): 
    inc += step_size 
    count += (width/totalsteps) 
    print(" inc", inc, "tick at ", count) 

如果名称 == “”: 主()

0

在范围-1, 0

我得到

normalised_delta 1.0 
step_size 0.1 
Total steps 10.0 
Range [ -1 , 0 ] 
firstInc -1.0 tick at 0.0 
start at 0.0 0.0 
inc -0.9 tick at 25.0 
inc -0.8 tick at 50.0 
inc -0.7 tick at 75.0 
inc -0.6 tick at 100.0 
inc -0.5 tick at 125.0 
inc -0.4 tick at 150.0 
inc -0.3 tick at 175.0 
inc -0.2 tick at 200.0 
inc -0.1 tick at 225.0 
inc -1.38777878078e-16 tick at 250.0 
inc 0.1 tick at 275.0 

底部的第二行怎么会得到这个数字?

+0

这是由于计算机上浮点数和操作的不准确性。具体而言,0.1没有精确的表示,并且+您继续添加错误。如果您使用-1.0 + 9 * 0.1,则误差要小得多。 (见http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems) – mweerden 2008-12-15 17:39:54