Хаос Шаоса

Использование и разработка софта (преимущественно на ПЦ)

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 23918
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote:
Shaos wrote:По просьбе Axora вспомнил и запрограммировал алгоритм генерации скал
А потом портировал его на ZX-Spectrum ;)
Image

Вот собственно оно - исходник на языке RW1 от 1 января 2006 года (исходнику уже больше года):

Code: Select all

robot "Gory"
author "Shaos"
+inc/rw1p2.rwi
+inc/rw1_std.rwi
@DX=256
@DY=192
@MAXT=512 // 16*16*2
@MAXP=867 // 17*17*3
@MAXS=51  // 17*3
@MAXG=256
@TRAN=128
@TRAM=16
@PIDX(2)=g_step*(((@1)*3)+((@2)*@MAXS))
main()
{
 text "\ === Начало главной функции ==="
 def ztile[9]
 text "\ Массив COS[16] для вычисления косинусов сдвинутых на 6 бит"
 def cos[16] = {64,60,45,23,0,-23,-45,-60,-64,-60,-45,-23,0,23,45,60}
 text "\ Массив SIN[16] для вычисления синусов сдвинутых на 6 бит"
 def sin[16] = {0,23,45,60,64,60,45,23,0,-23,-45,-60,-64,-60,-45,-23}
 text "\ Массивы для треугольников и их вершин"
 def p1[@MAXT]
 def p2[@MAXT]
 def p3[@MAXT]
 def po[@MAXP]
 text "\ Установить в качестве текущего цвета зеленый (с черным фоном)"
 color #07
 text "\ Начальные установки"
 d_line = 0 // for DD()
 g_step = 16
 g_num = 1
 g_m = @TRAM
 g_a = 6
 g_tmax = 1
 p1[0] = @PIDX(0,0)
 p2[0] = @PIDX(0,1)
 p3[0] = @PIDX(1,1)
 p1[1] = @PIDX(0,0)
 p2[1] = @PIDX(1,0)
 p3[1] = @PIDX(1,1)
 g_buf = 0
 text "\ Главный цикл"
 while(1)
 {
   clr()
   points()
   drawtri()
   say "PRESS SP,O,P or Q to quit"
   text "\ Ожидание нажатия клавиши"
   while(g_buf==0)
   {
     recv g_buf
   }         
   if(N==@keyboard)
   {
     text "\ Клавиша нажата - анализ"
     if(g_buf=='Q') break
     if(g_buf==#20 && g_step > 1) 
     {
        g_step = g_step>>1
	g_num = 16/g_step
	newtri()
     }
     if(g_buf=='O') 
     {
        g_a = g_a + 1
	if(g_a==16) g_a=0
     }	
     if(g_buf=='P') 
     {
        g_a = g_a - 1
	if(g_a==-1) g_a=15
     }	
     g_buf = 0
   }
 }
 say "--- OK ---"
 text "\ === Конец главной функции ==="
 ret
}

clr()
{
 text "\ --- CLR - Очистка экрана"
 A = #D000 // Address of ztile ???
 command @P2_TERMCLR
 say "(c) 2005, A.A.SHABARSHIN    "
 text "\ --- CLR - Конец подпрограммы"
}

moveto() // A-x B-y
{
 text "\ --- MOVETO - Запомнить начальные координаты"
 last_x = A
 last_y = B
 text "\ --- MOVETO - Конец подпрограммы"
}

lineto() // A-x B-y
{
 text "\ --- LINETO - Нарисовать линию из запомненных координат в заданные"
 l_x = A
 l_y = B
 l_dx = 0
 l_xlen = 0
 if(l_x > last_x)
 {
   l_dx = 1
   l_xlen = l_x - last_x
 }
 if(l_x < last_x)
 {
   l_dx = -1
   l_xlen = last_x - l_x
 }      
 l_dy = 0
 l_ylen = 0
 if(l_y > last_y)
 {
   l_dy = 1
   l_ylen = l_y - last_y
 }
 if(l_y < last_y)
 {
   l_dy = -1
   l_ylen = last_y - l_y
 }
 if(l_dy==0) 
 {
   l_step = 0
   l_mode = 1
 }      
 if(l_dx==0)
 {
   l_step = 0
   l_mode = 2
 }
 if(l_dx!=0 && l_dy!=0)
 {
   if(l_xlen > l_ylen)
   { 
     l_step = (l_xlen<<7)/l_ylen
     l_mode = 3
   }  
   else
   { 
     l_step = (l_ylen<<7)/l_xlen
     l_mode = 4
   }  
 }
 l_curs = l_step
 while(1)
 {
   if(last_x < 0 || last_x >= @DX || last_y <0 || last_y >= @DY) break
   pixel last_x last_y
   C = 0
   if(l_dx >= 0 && l_x-last_x < 2) C=C+1
   if(l_dx < 0 && last_x-l_x < 2) C=C+1
   if(l_dy >= 0 && l_y-last_y < 2) C=C+1
   if(l_dy < 0 && last_y-l_y < 2) C=C+1
   if(C==2)
   {
     if(l_x!=last_x || l_y!=last_y)
     {
       pixel l_x l_y
       last_x = l_x
       last_y = l_y
     }
     break
   }
   if(l_mode==1)
   {
     last_x = last_x + l_dx
     continue
   }
   if(l_mode==2)
   {
     last_y = last_y + l_dy
     continue
   }
   if(l_mode==3)
   {
     last_x = last_x + l_dx
     l_curs = l_curs - #80
     if(l_curs < #80)
     {
       l_curs = l_curs + l_step
       last_y = last_y + l_dy
     }
     continue
   }
   if(l_mode==4)
   {
     last_y = last_y + l_dy
     l_curs = l_curs - #80
     if(l_curs < #80)
     {
       l_curs = l_curs + l_step
       last_x = last_x + l_dx
     }
     continue
   }
   say "LINE ERROR"
   break
 }
 text "\ --- LINETO - Конец подпрограммы"
}

points() 
{
 text "\ --- POINTS - Пересчитать координаты точек для экрана"
 for(B=0;B<=g_num;B++)
 {
   for(A=0;A<=g_num;A++)
   {
      p_idx=@PIDX(A,B)
      p_x=A*g_step*g_m-@TRAN
      p_y=B*g_step*g_m-@TRAN
      p_z=(po[p_idx+2]>>8)&255
      p_x1=p_x*cos[g_a]-p_y*sin[g_a]
      p_y1=p_x*sin[g_a]+p_y*cos[g_a]
      p_xe=128+p_x1/100
      p_ye=14+20736/((p_y1>>6)+309)
      p_ze=(p_z<<7)/309
      po[p_idx]=p_xe
      po[p_idx+1]=p_ye
      po[p_idx+2]=(p_z<<8)|(p_ze&255)
   }
 }
 text "\ --- POINTS - Конец подпрограммы"
}

newtri() // A - number of points
{
 text "\ --- NEWTRI - Добавить следующую степень точности"
 t_k = 0
 t_m = g_step*g_m
 t_d = t_m>>2
 for(t_j=1;t_j<=g_num;t_j=t_j+2)
 {
   for(t_i=1;t_i<=g_num;t_i=t_i+2)
   {
      t_0_0 = @PIDX(t_i-1,t_j-1)
      t_1_0 = @PIDX(t_i,t_j-1)
      t_2_0 = @PIDX(t_i+1,t_j-1)
      t_0_1 = @PIDX(t_i-1,t_j)
      t_1_1 = @PIDX(t_i,t_j)
      t_2_1 = @PIDX(t_i+1,t_j)
      t_0_2 = @PIDX(t_i-1,t_j+1)
      t_1_2 = @PIDX(t_i,t_j+1)
      t_2_2 = @PIDX(t_i+1,t_j+1)
      t_z00 = (po[t_0_0+2]>>8)&255
      t_z01 = (po[t_0_2+2]>>8)&255
      t_z10 = (po[t_2_0+2]>>8)&255
      t_z11 = (po[t_2_2+2]>>8)&255
      t_rand = R
      t_z = ((t_z00+t_z10)>>1)-t_d+(t_rand%t_m)
      if(t_z<0) t_z=0
      if(t_z>255) t_z=255
      po[t_1_0+2] = t_z<<8
      t_rand = R
      t_z = ((t_z00+t_z01)>>1)-t_d+(t_rand%t_m)
      if(t_z<0) t_z=0
      if(t_z>255) t_z=255
      po[t_0_1+2] = t_z<<8
      t_rand = R
      t_z = ((t_z00+t_z11)>>1)-t_d+(t_rand%t_m)
      if(t_z<0) t_z=0
      if(t_z>255) t_z=255
      po[t_1_1+2] = t_z<<8
      t_rand = R
      t_z = ((t_z10+t_z11)>>1)-t_d+(t_rand%t_m)
      if(t_z<0) t_z=0
      if(t_z>255) t_z=255
      po[t_2_1+2] = t_z<<8
      t_rand = R
      t_z = ((t_z01+t_z11)>>1)-t_d+(t_rand%t_m)
      if(t_z<0) t_z=0
      if(t_z>255) t_z=255
      po[t_1_2+2] = t_z<<8
      p1[t_k] = t_0_0
      p2[t_k] = t_0_1
      p3[t_k] = t_1_1
      t_k = t_k+1
      p1[t_k] = t_0_0
      p2[t_k] = t_1_0
      p3[t_k] = t_1_1
      t_k = t_k+1
      p1[t_k] = t_1_0
      p2[t_k] = t_1_1
      p3[t_k] = t_2_1
      t_k = t_k+1
      p1[t_k] = t_1_0
      p2[t_k] = t_2_0
      p3[t_k] = t_2_1
      t_k = t_k+1
      p1[t_k] = t_0_1
      p2[t_k] = t_0_2
      p3[t_k] = t_1_2
      t_k = t_k+1
      p1[t_k] = t_0_1
      p2[t_k] = t_1_1
      p3[t_k] = t_1_2
      t_k = t_k+1
      p1[t_k] = t_1_1
      p2[t_k] = t_1_2
      p3[t_k] = t_2_2
      t_k = t_k+1
      p1[t_k] = t_1_1
      p2[t_k] = t_2_1
      p3[t_k] = t_2_2
      t_k = t_k+1
   }
 }
 g_tmax = t_k-1
 text "\ --- NEWTRI - Конец подпрограммы"
}

drawtri()
{
 text "\ --- DRAWTRI - Нарисовать треугольники"
 for(t_i=0;t_i<=g_tmax;t_i++)
 {
   t_z1 = po[p1[t_i]+2]&255
   t_y1 = po[p1[t_i]+1]-t_z1
   t_x1 = po[p1[t_i]]
   t_z2 = po[p2[t_i]+2]&255
   t_y2 = po[p2[t_i]+1]-t_z2
   t_x2 = po[p2[t_i]]
   t_z3 = po[p3[t_i]+2]&255
   t_y3 = po[p3[t_i]+1]-t_z3
   t_x3 = po[p3[t_i]]
   moveto(t_x1,t_y1)
   lineto(t_x2,t_y2)
   lineto(t_x3,t_y3)
   lineto(t_x1,t_y1)
 }
 text "\ --- DRAWTRI - Конец подпрограммы"
}

dd()
{
 A=0
 B=d_line
 C=1
 command @P2_SETSAY 
 d_line=d_line+1
}
А вот архив с исходником RW1, а также собранными TAP и TRD: gory_01_2006.zip (16K)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23918
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Хаос Шаоса

Post by Shaos »

Восстановил картинки в первых сообщениях топика
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23918
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Хаос Шаоса

Post by Shaos »

Вот ещё из старины глубокой - картинки высокого разрешения 1024x768 из множества Мандельброта, полученные мною в июле 1997 года (26 с лишним лет назад) - они были в моём собственном 8-битном формате без сжатия и вот сегодня я преобразовал их в PNG без потерь:
view1024_000.png
view1024_001.png
view1024_002.png
view1024_003.png
Координаты картинок (сделать что ли современную мандельбротоходилку?):

Code: Select all

mndlbrt0.gra  x0=-0.280000 y0= 1.500000 dx=4.000000
mndlbrt1.gra  x0=-0.219759 y0=-0.813599 dx=0.000977
mndlbrt2.gra  x0= 0.300260 y0= 0.025391 dx=0.007812
mndlbrt3.gra  x0=-0.175000 y0=-1.023438 dx=0.031250
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Pinokio240
Fanat
Posts: 57
Joined: 23 May 2023 23:14

Re: Хаос Шаоса

Post by Pinokio240 »

Фракталы, это всегда красиво))
User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re:

Post by Alikberov »

Shaos wrote:По просьбе Axora вспомнил и запрограммировал алгоритм генерации скал для газеты Абзац:

Image
Image
Image
Image
Я эти картинки все 90-е в Бейсике РАДИО-86РК пытался воспроизвести безуспешно. :-?
Пока не понял принцип лишь многим позже:
User avatar
Shaos
Admin
Posts: 23918
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Хаос Шаоса

Post by Shaos »

Надо на РК портировать мою прогу генерации гор :)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Хаос Шаоса

Post by Alikberov »

Shaos wrote:Надо на РК портировать мою прогу генерации гор :)
Она и в SVG жутко тормозит. :roll:
Даёшь анимацию гор на РК с 50 fps!? :lol:
User avatar
Shaos
Admin
Posts: 23918
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Хаос Шаоса

Post by Shaos »

Не - 50FPS конечно же не выйдет :)

Хотя у меня когда-то были мысли сделать "сопроцессор" для ретрокомпьютеров на PIC16 (он тоже 8-битный, но с частотами до 20 МГц и 4-мя тактами на команду), который бы "помогал" в некоторых матрасчётах слабенькому ретропроцу...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Хаос Шаоса

Post by Alikberov »

Shaos wrote:Не - 50FPS конечно же не выйдет :)

Хотя у меня когда-то были мысли сделать "сопроцессор" для ретрокомпьютеров на PIC16 (он тоже 8-битный, но с частотами до 20 МГц и 4-мя тактами на команду), который бы "помогал" в некоторых матрасчётах слабенькому ретропроцу...
Как-то занимался темой быстрого построения линии в РК по Брезенхэму. Однако, не справился с символами псевдографики.
Помните (мышь работает)?
User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Скрипт генерации имитации плоской проекции "гор"

Post by Alikberov »

Нашёл исходный код свой. :roll:
(Сколько своих аккаунтов шерстить надо!)
You do not have the required permissions to view the files attached to this post.
User avatar
Shaos
Admin
Posts: 23918
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Хаос Шаоса

Post by Shaos »

Сдаётся мне чувак из книжки спёр мои картинки зеркально отразив :lol:
Shaos wrote:По просьбе Axora вспомнил и запрограммировал алгоритм генерации скал для газеты Абзац:

Image
Image
Image
Image
P.S. Хотя там же написано 1986? :roll:

P.P.S. Не - просто похоже очень :lol:
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23918
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re:

Post by Shaos »

Shaos wrote:По просьбе Axora вспомнил и запрограммировал алгоритм генерации скал для газеты Абзац:




Нашёл свой сишный исходник от декабря 2005 года :)

 gory1.c

Code: Select all

/* 
   gory1.c - Mountain Image Generator (15 Dec 2005 - 17 Dec 2005)
   Author: Alexander Shabarshin (alexander@shabarshin.com)
   http://chaos.shabarshin.com
   
   Compilation:
     gcc gory1.c -o gory1 -lSDL -ljpeg -lm
   Usage: 
     ./gory1
*/

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>
#include <SDL/SDL.h>
#include <jpeglib.h>

#define MAXPIX 400000

int DDX = 1024;
int DDY = 768;
int quality = 90;

int black = 0x000000;
int grey  = 0x808080;
int white = 0xFFFFFF;
int red   = 0xFF0000;
int green = 0x00FF00;
int blue  = 0x0000FF;

SDL_Surface* screen;

struct my_error_mgr {
  struct jpeg_error_mgr pub;	/* "public" fields */
  jmp_buf setjmp_buffer;	/* for return to caller */
};

typedef struct my_error_mgr * my_error_ptr;

/*
 * Here's the routine that will replace the standard error_exit method:
 */

METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  my_error_ptr myerr = (my_error_ptr) cinfo->err;

  /* Always display the message. */
  /* We could postpone this until after returning, if we chose. */
  (*cinfo->err->output_message) (cinfo);

  /* Return control to the setjmp point */
  longjmp(myerr->setjmp_buffer, 1);
}

int putpixel(int x, int y, int c)
{
 int *bits;
 SDL_Surface* s; 
 if(x<0 || x>=DDX || y<0 || y>=DDY) return 0;
 s = screen;
 if(SDL_MUSTLOCK(s) && SDL_LockSurface(s)<0) return 0;
 bits = (int*)(&((unsigned char*)s->pixels)[y*s->pitch+x*4]);
 *bits = c;
 if(SDL_MUSTLOCK(s)) SDL_UnlockSurface(s);
 return 1;
}

int getpixel(int x, int y)
{
 int *bits,c;
 SDL_Surface* s; 
 if(x<0 || x>=DDX || y<0 || y>=DDY) return 0;
 s = screen;
 if(SDL_MUSTLOCK(s) && SDL_LockSurface(s)<0) return 0;
 bits = (int*)(&((unsigned char*)s->pixels)[y*s->pitch+x*4]);
 c = *bits;
 if(SDL_MUSTLOCK(s)) SDL_UnlockSurface(s);
 return c;
}

void drawbar(int x, int y, int w, int h, int c)
{
 int i,j;
 for(j=y;j<y+h;j++)
 {
  if(j<0) continue;
  if(j>=DDY) break;
  for(i=x;i<x+w;i++)
  {
   if(i<0) continue;
   if(i>=DDX) break;
   putpixel(i,j,c);
  }
 }  
}

void drawhline(int x, int y, int l, int c)
{
 int i;
/* printf("drawhline(%i,%i,%i,%i)\n",x,y,l,c); */
 for(i=0;i<l;i++) putpixel(x+i,y,c);
}

void drawvline(int x, int y, int l, int c)
{
 int j;
/* printf("drawvline(%i,%i,%i,%i)\n",x,y,l,c); */
 for(j=0;j<l;j++) putpixel(x,y+j,c);
}

void drawrect(int x, int y, int w, int h, int c)
{
 drawhline(x,y,w,c);
 drawhline(x,y+h-1,w,c);
 drawvline(x,y,h,c);
 drawvline(x+w-1,y,h,c);
}

void drawline(int x, int y, int vx, int vy, int c)
{
 int ax,ay,n=0;
 long xlong,ylong,xxlong,yylong,hstep,vstep,l;
 if(vy==0)
 {
   if(vx>0) drawhline(x,y,vx,c);
   else drawhline(x+vx,y,-vx,c);
   return;
 }  
 if(vx==0)
 {
   if(vy>0) drawvline(x,y,vy,c);
   else drawvline(x,y+vy,-vy,c);
   return;
 }  
 if(vx>0) ax=vx;
 else ax=-vx;
 if(vy>0) ay=vy;
 else ay=-vy;
 if(ax<=1 && ay<=1) 
 {
   putpixel(x,y,c);
   return;
 }
 if(ax>ay) 
      l=ax<<1;
 else l=ay<<1;
 xlong = ((long)x)<<16;
 ylong = ((long)y)<<16;
 xxlong = ((long)(x+vx))<<16;
 yylong = ((long)(y+vy))<<16;
 hstep = (vx<<16)/l;
 vstep = (vy<<16)/l;
/*
 printf("\ndrawline(%i,%i,%i,%i,0x%8.8X)\n",x,y,vx,vy,c);
 printf("xlong=0x%8.8X\n",xlong);
 printf("ylong=0x%8.8X\n",ylong);
 printf("xxlong=0x%8.8X (%i)\n",xxlong,xxlong>>16);
 printf("yylong=0x%8.8X (%i)\n",yylong,yylong>>16);
 printf("hstep=0x%8.8X\n",hstep);
 printf("vstep=0x%8.8X\n",vstep);
*/ 
 while(1)
 { if(n++>=1000) break;
   putpixel(xlong>>16,ylong>>16,c);
   xlong += hstep;
   ylong += vstep;
/*   
   printf("%i) xlong=0x%8.8X (%i)\n",n,xlong,xlong>>16);
   printf("%i) ylong=0x%8.8X (%i)\n",n,ylong,ylong>>16);
*/   
   if(abs((xlong&0xFFFF0000)-xxlong)<=0x10000 &&
      abs((ylong&0xFFFF0000)-yylong)<=0x10000
     ) break;
 }
}

void line(int x1, int y1, int x2, int y2, int c)
{
 drawline(x1,y1,x2-x1,y2-y1,c);
}

typedef struct _pixel
{
  short x,y,z;
} pixel;

typedef struct _triangle
{
  short l,t,r;
} triangle;

triangle *tri;
pixel *pix;
int mtri,ntri,npix;

void drawtri(int t, int x, int y, int c)
{
  int x1,x2,x3,y1,y2,y3,z1,z2,z3;
  int i,k1,k2,ax[3],ay[3],xmin,ymin,xmax,ymax,yy,i1,i2,num;
  float fx1,fx2,tmp,dx1,dx2;
  long a1,a2,a3,a4,a5,a6,vx,vy,vz,cc;
  pixel *pl,*pt,*pr;
  triangle *tr;
  tr = &tri[t];
  pl = &pix[tr->l];
  pt = &pix[tr->t];
  pr = &pix[tr->r];
  z1 = pl->z;
  y1 = pl->y + y - z1;
  x1 = pl->x + x;
  z2 = pt->z;
  y2 = pt->y + y - z2;
  x2 = pt->x + x;
  z3 = pr->z;
  y3 = pr->y + y - z3;
  x3 = pr->x + x;
  if(c>=0)
  {
    line(x1,y1,x2,y2,c);
    line(x2,y2,x3,y3,c);
    line(x3,y3,x1,y1,c);
  }
  else
  {
    num = 3;
    if(pt->y < pl->y)
    {
     a1 = pl->x - pt->x;
     a2 = pl->y - pt->y;
     a3 = pl->z - pt->z;
     a4 = pr->x - pt->x;
     a5 = pr->y - pt->y;
     a6 = pr->z - pt->z;
     ax[0] = x1;
     ax[1] = x3;
     ax[2] = x2;
     ay[0] = y1;
     ay[1] = y3;
     ay[2] = y2;
    }
    else
    {
     a1 = pr->x - pt->x;
     a2 = pr->y - pt->y;
     a3 = pr->z - pt->z;
     a4 = pl->x - pt->x;
     a5 = pl->y - pt->y;
     a6 = pl->z - pt->z;
     ax[0] = x1;
     ax[1] = x2;
     ax[2] = x3;
     ay[0] = y1;
     ay[1] = y2;
     ay[2] = y3;
    } 
    vx = a2*a6 - a3*a5;
    vy = a3*a4 - a1*a6;
    vz = a1*a5 - a2*a4;  
    cc = acos(vx/sqrt(vx*vx+vy*vy+vz*vz))*128/3.14159;
    cc = cc|(cc<<8)|(cc<<16);
    xmin = 10000;
    ymin = 10000;
    xmax = -10000;
    ymax = -10000;
    for(i=0;i<num;i++)
    {
      if(ax[i]<xmin){xmin=ax[i];}
      if(ay[i]<ymin){ymin=ay[i];k1=i;}
      if(ax[i]>xmax){xmax=ax[i];}
      if(ay[i]>ymax){ymax=ay[i];k2=i;}
    }
    yy = ay[k1];
    i1 = i2 = k1;
//    putpixel(ax[k1],yy,cc);
    while(1)
    {
       if(yy==ay[k2]) break;
       if(ay[i1]==yy)
       {
          fx1 = ax[i1];
          y1 = ay[i1];
          if(++i1>=num) i1=0;
          tmp = ay[i1]-y1;
          if(tmp==0) continue;
          dx1 = (ax[i1]-fx1)/tmp;
       }
       if(ay[i2]==yy)
       {
          fx2 = ax[i2];
          y2 = ay[i2];
          if(--i2<0) i2=num-1;
          tmp = ay[i2]-y2;
          if(tmp==0) continue;
          dx2 = (ax[i2]-fx2)/tmp;
       }
       yy++;
       drawhline((int)fx1,yy,(int)(fx2-fx1+1),cc);
       fx1+=dx1;
       fx2+=dx2;
    }
  }    
}

void gentri(int m,int n)
{
  int i,j,hh,h2;
  for(i=m;i<n;i++)
  {
    hh = (pix[tri[i].r].x - pix[tri[i].l].x)/3;
    h2 = hh/3;
    pix[npix].x = (pix[tri[i].t].x + pix[tri[i].l].x) >> 1;
    pix[npix].y = (pix[tri[i].t].y + pix[tri[i].l].y) >> 1;
    for(j=0;j<npix;j++)
    {
      if(pix[j].x==pix[npix].x && pix[j].y==pix[npix].y)
      {
          pix[npix].z = pix[j].z;
	  break;
      }
    }
    if(j==npix) 
       pix[npix].z = ((pix[tri[i].t].z + pix[tri[i].l].z) >> 1) - h2 + (rand()%hh);
    npix++;
    pix[npix].x = (pix[tri[i].r].x + pix[tri[i].t].x) >> 1;
    pix[npix].y = (pix[tri[i].r].y + pix[tri[i].t].y) >> 1;
    for(j=0;j<npix;j++)
    {
      if(pix[j].x==pix[npix].x && pix[j].y==pix[npix].y)
      {
          pix[npix].z = pix[j].z;
	  break;
      }
    }
    if(j==npix) 
       pix[npix].z = ((pix[tri[i].r].z + pix[tri[i].t].z) >> 1) - h2 + (rand()%hh);
    npix++;
    pix[npix].x = (pix[tri[i].r].x + pix[tri[i].l].x) >> 1;
    pix[npix].y = (pix[tri[i].r].y + pix[tri[i].l].y) >> 1;
    for(j=0;j<npix;j++)
    {
      if(pix[j].x==pix[npix].x && pix[j].y==pix[npix].y)
      {
          pix[npix].z = pix[j].z;
	  break;
      }
    }
    if(j==npix) 
       pix[npix].z = ((pix[tri[i].r].z + pix[tri[i].l].z) >> 1) - h2 + (rand()%hh);  
    npix++;
    tri[ntri].l = npix - 3;
    tri[ntri].t = tri[i].t;
    tri[ntri].r = npix - 2;
    ntri++;
    tri[ntri].l = tri[i].l;
    tri[ntri].t = npix - 3;
    tri[ntri].r = npix - 1;
    ntri++;
    tri[ntri].l = npix - 3;
    tri[ntri].t = npix - 1;
    tri[ntri].r = npix - 2;
    ntri++;
    tri[ntri].l = npix - 1;
    tri[ntri].t = npix - 2;
    tri[ntri].r = tri[i].r;
    ntri++;
  }
}

void sortri(int m,int n)
{
  int i,y1,y2,l,t,r,k=1;
  while(k)
  {
    k = 0;
    for(i=m;i<n-1;i++)
    {
      if(pix[tri[i].t].y < pix[tri[i].l].y) y1=pix[tri[i].t].y;
      else y1=pix[tri[i].l].y;
      if(pix[tri[i+1].t].y < pix[tri[i+1].l].y) y2=pix[tri[i+1].t].y;
      else y2=pix[tri[i+1].l].y;
      if(y2<y1) 
      {
        k = 1;
	l = tri[i].l;
	t = tri[i].t;
	r = tri[i].r;
	tri[i].l = tri[i+1].l;
	tri[i].t = tri[i+1].t;
	tri[i].r = tri[i+1].r;
	tri[i+1].l = l;
	tri[i+1].t = t;
	tri[i+1].r = r;
      }
    }
  }
}

int main(int argc,char **argv)
{
   char imagefile[32];
   unsigned char *keys,*image_buffer;
   SDL_Color color;
   SDL_Event event;
   struct jpeg_compress_struct cinfo;
   struct jpeg_error_mgr jerr;
   FILE * outfile;		/* target file */
   JSAMPROW row_pointer[1];	/* pointer to JSAMPLE row[s] */
   int row_stride;		/* physical row width in image buffer */
   int image_height;	/* Number of rows in image */
   int image_width;	/* Number of columns in image */
   int number = 0;
   int done = 0;
   int i,j,k;
   int x,y,z;
   int dx,dy,x0,y0,w,w2,h;
   
   srand((unsigned int)time(NULL));
   if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)<0)
   {
    printf("Unable to initialise SDL: %s\n",SDL_GetError());
    exit(1);
   }
   atexit(SDL_Quit);
   screen = SDL_SetVideoMode(DDX,DDY,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
   if(screen==NULL)
   {
    printf("Unable to set video: %s\n", SDL_GetError());
    exit(1);
   }
   
   dx = DDX>>1;
   dy = DDY>>1;
   x0 = 20;
   w = dx-(x0<<1);
   w2 = w>>1;
   h = ((long)w2*56759)>>16;
   y0 = (dy-h)>>1;
   
   tri = (triangle*)malloc(MAXPIX*sizeof(triangle));
   pix = (pixel*)malloc(MAXPIX*sizeof(pixel));
   if(tri==NULL||pix==NULL) return 0;
   mtri = 0;
   ntri = 1;
   npix = 3;
   pix[0].x = x0;
   pix[0].y = y0+h;
   pix[0].z = 0;
   pix[1].x = x0+w2;
   pix[1].y = y0;
   pix[1].z = 0;
   pix[2].x = x0+w;
   pix[2].y = y0+h;
   pix[2].z = 0;
   tri[0].l = 0;
   tri[0].t = 1;
   tri[0].r = 2;

   while(1)
   {
     if(ntri*16>MAXPIX) break;
     if(done==2) break;

     drawbar(0,0,DDX,DDY,0x000000);
     drawrect(0,0,dx,dy,grey);
     drawrect(dx,0,dx,dy,grey);
     drawrect(0,dy,dx,dy,grey);
     drawrect(dx,dy,dx,dy,grey);

     printf("m=%i n=%i\n",mtri,ntri);
     for(i=mtri;i<ntri;i++) drawtri(i,0,0,white);
     sortri(mtri,ntri);
     for(i=mtri;i<ntri;i++) drawtri(i,dx,0,-1);
     k = ntri;
     gentri(mtri,ntri);
     mtri = k;

     printf("m=%i n=%i\n",mtri,ntri);
     for(i=mtri;i<ntri;i++) drawtri(i,0,dy,white);
     sortri(mtri,ntri);
     for(i=mtri;i<ntri;i++) drawtri(i,dx,dy,-1);
     k = ntri;
     gentri(mtri,ntri);
     mtri = k;

     SDL_Flip(screen);
     done = 0;
     while(!done)
     {while(SDL_PollEvent(&event)) 
      {if(event.type == SDL_QUIT) done=2;
       if(event.type == SDL_KEYDOWN) 
       {if(event.key.keysym.sym == SDLK_ESCAPE) done=2;
        if(event.key.keysym.sym == SDLK_SPACE) done=1;
       }
      }
     } 
//     if(done==2) break;
   
/* <><><><><><><><><><> JPEG <><><><><><><><><><><> */

  sprintf(imagefile,"gory1_%i.jpeg",++number);
  printf("Save '%s'\n",imagefile);
  image_width = DDX;
  image_height = DDY;
  image_buffer = (unsigned char*)malloc(DDX*3);
  if(image_buffer==NULL) return 0;

  /* Step 1: allocate and initialize JPEG compression object */

  /* We have to set up the error handler first, in case the initialization
   * step fails.  (Unlikely, but it could happen if you are out of memory.)
   * This routine fills in the contents of struct jerr, and returns jerr's
   * address which we place into the link field in cinfo.
   */
  cinfo.err = jpeg_std_error(&jerr);
  /* Now we can initialize the JPEG compression object. */
  jpeg_create_compress(&cinfo);

  /* Step 2: specify data destination (eg, a file) */
  /* Note: steps 2 and 3 can be done in either order. */

  /* Here we use the library-supplied code to send compressed data to a
   * stdio stream.  You can also write your own code to do something else.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to write binary files.
   */
  if ((outfile = fopen(imagefile, "wb")) == NULL) {
    fprintf(stderr, "can't open %s\n", imagefile);
    exit(1);
  }
  jpeg_stdio_dest(&cinfo, outfile);

  /* Step 3: set parameters for compression */

  /* First we supply a description of the input image.
   * Four fields of the cinfo struct must be filled in:
   */
  cinfo.image_width = image_width; 	/* image width and height, in pixels */
  cinfo.image_height = image_height;
  cinfo.input_components = 3;		/* # of color components per pixel */
  cinfo.in_color_space = JCS_RGB; 	/* colorspace of input image */
  /* Now use the library's routine to set default compression parameters.
   * (You must set at least cinfo.in_color_space before calling this,
   * since the defaults depend on the source color space.)
   */
  jpeg_set_defaults(&cinfo);
  /* Now you can set any non-default parameters you wish to.
   * Here we just illustrate the use of quality (quantization table) scaling:
   */
  jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */ );

  /* Step 4: Start compressor */

  /* TRUE ensures that we will write a complete interchange-JPEG file.
   * Pass TRUE unless you are very sure of what you're doing.
   */
  jpeg_start_compress(&cinfo, TRUE);

  /* Step 5: while (scan lines remain to be written) */
  /*           jpeg_write_scanlines(...); */

  /* Here we use the library's state variable cinfo.next_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   * To keep things simple, we pass one scanline per call; you can pass
   * more if you wish, though.
   */
  row_stride = image_width * 3;	/* JSAMPLEs per row in image_buffer */

  y = 0;
  while (cinfo.next_scanline < cinfo.image_height) {
    /* jpeg_write_scanlines expects an array of pointers to scanlines.
     * Here the array is only one element long, but you could pass
     * more than one scanline at a time if that's more convenient.
     */
     
    i = 0;
    for(x=0;x<DDX;x++){
           k = getpixel(x,y);
           image_buffer[i++] = (k>>16)&255;
           image_buffer[i++] = (k>>8)&255;
           image_buffer[i++] = k&255;
    }
    y++;
     
    row_pointer[0] = (JSAMPLE*)image_buffer;
    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
  }

  /* Step 6: Finish compression */

  jpeg_finish_compress(&cinfo);
  /* After finish_compress, we can close the output file. */
  fclose(outfile);

  /* Step 7: release JPEG compression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_compress(&cinfo);

  /* And we're done! */

  free(image_buffer);
  
  }
  
  free(tri);
  free(pix);
  
  return 1;
}

Он не только генерирует итерации, но и сохраняет картинки в JPEG 1024x768 - до сих пор собирается и работает :mrgreen:
gory1_1.jpeg
gory1_2.jpeg
gory1_3.jpeg
gory1_4.jpeg
P.S. Теперь я могу сам сгенерировать задник для Виртбурга в любом разрешении 8)

P.P.S. Облака по тому же алгоритму генерируются, но там теней нету - только белизна в зависимости от "высоты"...
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net