Функ­ция — ко­но­пля

На Ха­б­ре по­яви­лась те­ма, упо­ми­наю­щая мою дав­нюю ра­бо­ту — функ­цию, гра­фик ко­то­рой на­по­ми­на­ет лист ко­но­пли. К со­жа­ле­нию, в свя­зи с не­от­вра­ти­мым на­ступ­ле­ни­ем но­во­го го­да я сей­час не мо­гу уде­лить этой про­бле­ме до­ста­точ­но вни­ма­ния, по­это­му про­сто пуб­ли­кую не­ко­то­рые ма­те­ри­а­лы:

1. Про­грам­ма, ри­сую­щая гра­фик функ­ции: Cannabola.exe (284 Кбайта, ска­чан 561 раз);

2. Изоб­ра­же­ние (на­жми­те, что­бы за­гру­зить кар­тин­ку 8192×8192 пик­се­ля):

Гра­фик функ­ции, на­по­ми­наю­щий лист ко­но­пли
Гра­фик функ­ции, на­по­ми­наю­щий лист ко­но­пли

3. Ис­ход­ный код функ­ции (Pascal/Delphi; по­ка не имею воз­мож­но­сти вы­ло­жить текст всей про­грам­мы):

Function CannabolaValue(A,R: Double): Double;
Begin //Функция — конопля (в полярных координатах)
    result:=((1/(abs(cos(A/2*7-R*R*R*R*0.3))+0.005/R)+ //Листики
            8*sqr(sin(A/2*7))/(sqr(R/abs(sin(A/2)))*10+1)/
            (abs(sin(  (R-(arccos(cos((A+pi)*7-R*R*R*R*0.3))+
                2*R*sqr(arccos(cos((A+pi)*7-R*R*R*R*0.3)))) /20)*8*pi  ))+0.1+
                sqr(cos(A/2*7-R*R*R*R*0.3)))+ //Зарубки и прожилки
            3/(sqr(100*R)+0.1))* //Точка сосединения листиков
            (abs(sin(A/2))-R*R)- //Длина листиков
            abs(sin(A/2)))* //Толщина листиков
            (1+ 0.01/(sqr(sin(R*cos(A)*100+10*cos(R*sin(A)*40))+
                sin(R*sin(A)*100+10*sin(R*cos(A)*40)))+0.01) )+ //Сосудики
            (R+0.2)*0.0002/(sqr(A-R*0.1)+0.0001); //Ножка
End;

P.S. На­по­ми­наю, что ав­тор­ское пра­во на на­зва­ние «Кан­на­бо­ла» при­над­ле­жит Supman'у.

25 отзывов на запись «Функ­ция — ко­но­пля»

Ко­гда в ин­тер­не­те не на­шел про­грам­му из ар­буз­но­го то­пи­ка, при­нял­ся пи­сать свою. Как ока­за­лось, зря http://code.google.com/p/powder96-stuff/downloads/detail?name=cannabola.zip
Ах да, за­был про мно­го­чис­лен­ные во­про­сы, ко­то­рые у ме­ня воз­ни­ки­ли.
1) Как Вы раз­ру­ли­ва­ли си­ту­а­цию с де­ле­ни­ем на ноль (на­при­мер, в f1)? Я де­лал так, но ИМХО это вы­гля­дит как ко­стыль. // prevent division by 0
if(angle == 0)
angle = 0.000000001;
if(radius == 0)
radius = 0.000000001;

2) Как Вы рас­счи­ты­ва­ли цвет точ­ки на ос­но­ва­нии зна­че­ния ф-ции?
3) Как по­лу­чи­лось сгла­жи­ва­ние? По-идее, ес­ли Вы про­хо­ди­тесь цик­лом по x,y (что­бы не бы­ло «лу­чей»), то у каж­дой точ­ки бу­дет кон­крет­ный цвет – «раз­ма­зы­ва­ния», как со сгла­жен­ны­ми ли­ни­я­ми (см. ал­го­ритм Ву) быть не долж­но.
1) Си­ту­а­ция с де­ле­ни­ем на 0 у ме­ня не воз­ни­ка­ла: оси X и Y про­хо­дят в точ­но­сти по цен­тру изоб­ра­же­ния, а изоб­ра­же­ние со­дер­жит чёт­ное чис­ло пик­се­лей, по­это­му точ­ка (0,0) на­хо­дит­ся по­се­ре­ди­не меж­ду пик­се­ля­ми и ни­ко­гда не вы­чис­ля­ет­ся. 2) Кон­крет­ной фор­му­лы для цве­та у менч сей­час с со­бой нет, но, ка­жет­ся, там бы­ло так: бе­лый цвет для от­ри­ца­тель­ных зна­че­ний функ­ции, а даль­ше ли­ней­ная функ­ция от тём­но-зе­лё­но­го до свет­ло-зе­лё­но­го. 3) Сгла­жи­ва­ние (ан­тиа­ли­а­синг) де­ла­лось при по­мо­щи овер­сем­плин­га: каж­дый пик­сел бил­ся на 3×3 оди­на­ко­вых под­пик­се­ля, в них вы­чис­лял­ся цвет, ко­то­рый усред­нял­ся. Для боль­шей глад­ко­сти ли­ний при­ме­не­на про­стей­шая гам­ма-кор­рек­ция при усред­не­нии — воз­ве­де­ние в квад­рат и квад­рат­ный ко­рень по­сле усред­не­ния (смот­ри­те цве­то­вое про­стран­ство sRGB для бо­лее по­дроб­ной ин­фор­ма­ции).
1) По­нят­но. Про­бле­ма про­сто не про­яви­лась. ОК, то­гда бу­ду счи­тать свой об­ход­ной путь пра­виль­ным 2) Это бы­ло опи­са­но еще на ар­бу­зе: «Внут­рен­ность ли­ста ко­но­пли оп­ре­де­ля­ет­ся урав­не­ни­ем F(A,R)>0». Но там не бы­ло ска­за­но про то, как ис­поль­зуя зна­че­ние функ­ции, по­лу­чить RGB. 3) По­лу­ча­ет­ся, что из-за сгла­жи­ва­ния, про­грам­ма бу­дет ра­бо­тать, очень гру­бо го­во­ря, в 9 раз доль­ше…
Да, всё так.
У ме­ня ни­че­го не по­лу­ча­ет­ся
procedure TForm1.FormPaint(Sender: TObject);
var
  x,y,_x,_y: integer;
  a,r,color: double;
begin
  asm
  finit //обходим divizion by zero
  end;
  for y:=0 to Form1.ClientHeight-1 do
    for x:=0 to Form1.ClientWidth-1 do
    begin
      _x:=x-Form1.ClientWidth div 2;
      _y:=y-Form1.ClientHeight div 2;
      a:=arctan(_y/_x);
      if _x=0 then
          a:=a+PI
        else
          a:=a-PI;
      r:=sqrt(_x*_x+_y*_y);
      color:=CannabolaValue(a,r);
      if color<0 then
        Form1.Canvas.Pixels[x,y]:=round(color*255);
    end;
end;
Ри­со­вать на­до по­ло­жи­тель­ные цве­та
Зна­че­ние функ­ции CannabolaValue от­ри­ца­тель­но во всех точ­ках.
То­гда дру­гое пред­по­ло­же­ние: «лист» впи­сан в круг еди­нич­но­го ра­ди­у­са. У вас же еди­нич­ный ра­ди­ус со­от­вет­ству­ет од­но­му пик­се­лю. Зна­чит, ва­ша про­грам­ма ри­су­ет лист ко­но­пли раз­ме­ром в один пик­сель.
Сде­лал так
color:=CannabolaValue(a,r/200); По­яви­лись зна­ко­мые очер­та­ния
http://imageshost.ru/photo/27800/id1440916.html Но всё рав­но не то.
Вы не­вер­но пе­ре­во­ди­те _x, _y в угол. Кро­ме то­го, нель­зя про­сто так при­сваи­вать зна­че­нию Pixels[x,y] це­лое чис­ло. Во-пер­вых, Pixels[x,y] со­сто­ит из че­ты­рёх байт (по бай­ту на ка­нал и один не­ис­поль­зуе­мый), нуж­но сфор­ми­ро­вать цвет из трёх ком­по­нен­тов и упа­ко­вать его в integer. Во вто­рых, color по зна­че­нию мо­жет пре­вы­сить еди­ни­цу, и, зна­чит, при­сваи­ва­е­мое зна­че­ние мо­жет пре­вы­сить 255.
Ка­жет­ся на­шёл глюк
У ме­ня не со­хра­нил­ся ис­ход­ник и я ко­пи­ро­вал свой код с это­го сай­та if _x=0 then
a:=a+PI
else Из­на­чаль­но бы­ло не так Вы­чис­лял­ся угол в диа­па­зо­не от -PI до PI.
Ви­ди­мо, это тег <code> по­ел зна­ки мень­ше-боль­ше. На­до ис­поль­зо­вать <pre>. Ду­рац­кий WordPress.
В об­щем разо­брал­ся. Ес­ли вы­чис­лять угол так всё отоб­ра­жа­ет­ся нор­маль­но a:=arctan2(_y,_x)-PI/2;
if _x and _y<0 then
a:=a+PI*2; Спа­си­бо.
Avec un foyer identifie a Baie-Mahault toujours actif. Les gens ont le droit de savoir. http://lenitsky.com/ Du fait de l insolvabilite des prevenus – M. Plusieurs facteurs potentiels sont avances. Tout est mesurable.
Le patient reste muet. Mais pour moi, pour le moment, tout va bien. Andrey Lenitsky Et a ce titre elle ne peut pas etre banalisee … . Le pere d une copine l a transportee a l hopital. Mon metier, c est de m occuper des autres.
Puis aux deux tiers les trente jours suivants. J ai laisse trainer. Andrey Lenitsky Alexandre fut un expert. Vincent Lambert est victime d’un accident de la route. Elle ne la connait meme pas.
Ес­ли ми­мо про­ез­жа­ли лег­ко­вуш­ка или гру­зо­вик, Хе­лен с Джу­ли­ей оста­нав­ли­ва­лись и, чувств https://inava.ru/kak-vyibrat-tsvet-svadebnogo-platya/ За­по­ро­шен­ная из­вест­ко­вой пы­лью, она по по­яс ушла в гру­ду би­тых кир­пи­чей и де­ре­вя­шек, а
Пря­мо над го­ло­вой с по­тол­ка сви­сал огром­ный вен­ти­ля­тор, его ги­гант­ские ло­па­сти мо­но­тон https://inava.ru/monastryirskiy-chay-dlya-lecheniya-prostatita/ Яв­но же­лая от­де­лить се­бя от стран­ных увле­че­ний Херцо­га, Джек Адамс про­дол­жил: — Дол­жен
Buy Fluoxetine
Eat a generic wiki for for for good.
buy phenergan
purchase flagyl
Buy Fluoxetine
revia

Оставить отзыв

Жёлтые поля обязательны к заполнению

   

Можете использовать теги <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang=""> <div class=""> <span class=""> <br>