Теория трех ритмов и ее реализация

Когда-то очень давно, когда я баловался с Basic на эмуляторе ZX Spectrum, я написал достаточно убористую программу (которая была архисложной из всех, сделанных мной до этого), которая вычисляла так называемые биоритмы — синусоидальные кривые, которые, по словам сторонников теории «трех ритмов», соответствуют перепадам в физическом, эмоциональном и интеллектуальном состоянии… И вот настала пора реализации этого добра на Icon!

Суть программы проста: вычисляем сколько прошло дней от даты рождения субъекта до текущей даты (при этом считаем дату рождения «нулевой датой», т.е. датой от которой производиться отсчет. Это сделано из позиции уменьшения количества расчетов), подставляем в формулу для вычисления биоритма (Формул — три, по одной на каждый ритм. Отличаются формулы только периодом) — и запускаем в цикле, в котором происходит расчет ритма для точек, соответствующих некоторому интервалу дней (в нашем случае 250 дней в обе стороны от текущей даты, т.е. 250 дней в будущее и 250 дней в прошлое), а также происходит нанесение точек на график (используется видоизмененная func_plot в теле main).

В общем-то, и все — расчет количества прошедших дней — уже чистая математика, которую я в данном случае упущу (не хочется повторять ее снова) и привожу сразу сам код программы:

link graphics
global d,m,y,dd,mm,yy,s1,s2,mon1,mon2
procedure main()
local vv,W,l,i,k
mon1:=[31,28,31,30,31,30,31,31,30,31,30,31]
mon2:=[31,29,31,30,31,30,31,31,30,31,30,31]

write("---------------")
write("Биоритмы v 1.0")
write("---------------")
write("< Дата рождения >")
write("День:")
d:=read()
write("Месяц:")
m:=read()
write("Год:")
y:=read()

write("\n")
write("< Текущая дата >")
write("День:")
dd:=read()
write("Месяц:")
mm:=read()
write("Год:")
yy:=read()

vv:=year(y,yy)+days(m,mm)


W:=WOpen("size=500,500")
grid_coord()
capt_x()
capt_y()
DrawString(270,20,"Percents,%")
DrawString(460,290,"Days,d")
Fg("black")
DrawLine(490,240,500,250)
DrawLine(500,250,490,260)
DrawLine(240,10,250,0)
DrawLine(260,10,250,0)

i:=-250
while i<250 do {
	Fg("green")
        DrawPoint(i+250,250-200*ritm(vv+i/20,23))
        Fg("yellow")
        DrawPoint(i+250,250-200*ritm(vv+i/20,28))
        Fg("red")
        DrawPoint(i+250,250-200*ritm(vv+i/20,33))
        i+:=0.01
}

repeat {
	case Event() of {
	&lpress : {
		Fg("magenta")
	  	DrawString(20,20,"Biorithm:")
                DrawString(20,40,"green line - physical status")
                DrawString(20,60,"yellow line - emotional status")
                DrawString(20,80,"red line - intellectual status")	
	}	
        "q" : exit()
        &rpress : { 
        	Fg("magenta")
        	DrawString(300,420,"Today:")
                DrawString(300,440,"physical "||ritm(vv,23)*100)
                DrawString(300,460,"emotional "||ritm(vv,28)*100)
                DrawString(300,480,"intellectual "||ritm(vv,33)*100)
          }
	}
}

WDone()
end

procedure year(a,b)
local i,s
s:=0
every i:=a+1 to b-1 do {
 if i%4=0 then s+:=366 else s+:=365	
}
return s
end

procedure days(a,b)
s1:=0
s2:=0
if y%4=0 then s1:=mon2[integer(m)]-d else s1:=mon1[integer(m)]-d
if yy%4=0 then s2:=mon2[integer(m)]-dd else s1:=mon1[integer(m)]-dd
if a=1 then s1+:=days_1(2) else s1+:=days_1(a)
if b=1 then s2+:=days_2(2) else s2+:=days_2(b)
return s1+s2
end

procedure days_1(x)
local i
every i:=x to 12 do {
	if y%4=0 then s1+:=mon2[i] else s1+:=mon1[i] 
}
return s1
end

procedure days_2(x)
local i
every i:=x to 12 do {
	if yy%4=0 then s2+:=mon2[i] else s2+:=mon1[i] 
}
return s2
end

procedure ritm(t,p)
return sin(2*&pi*t/p)
end

procedure grid_coord()
local i
Fg("lightgray")      
every i:=0 to 500 by 10 do {
 DrawLine(i,0,i,500)
 DrawLine(0,i,500,i)
}
Fg("black")
DrawLine(0,250,500,250)
DrawLine(250,0,250,500)
end

procedure capt_x()
local q,s
Fg("blue")
s:=["-200","-150","-100","-50","0","50","100","150","200"]
every q:=50 to 250 by 50 do {
	DrawLine(q,250,q,260)
	DrawString(q,270,s[q/50])
}
every q:=300 to 500 by 50 do {
        DrawLine(q,250,q,260)
        DrawString(q,270,s[q/50])
}
end

procedure capt_y()
local q,i,c
q:=[50,150,350,450]
c:=["100","50","-50","-100"]
every i:=1 to *q do {
 DrawLine(250,q[i],260,q[i])
 DrawString(270,q[i],c[i])
}
end

На сладкое, конечно же, скриншот (биоритмы сняты по заказу моего друга):
bio_0_o
P.S: Автор не несет ответственность за результаты, использованные для планирования будущего :) Да и вообще, автор не верит в теорию «трех ритмов» ;)

Добавить комментарий