Zdrojový kód procedury generující fraktál pro PostgreSQL

Z PostgreSQL
Přejít na: navigace, hledání
DROP SCHEMA fractal CASCADE;

CREATE SCHEMA fractal;

CREATE TABLE fractal.disp (
  id INT PRIMARY KEY,
  content VARCHAR(1000)
);

CREATE TABLE fractal.shade (
  id INT PRIMARY KEY,
  value INT
);

CREATE FUNCTION ord(text) RETURNS int AS $$SELECT ascii($1); $$ LANGUAGE SQL IMMUTABLE; -- <nove>                                                                                                                                
CREATE FUNCTION concat(text, text) RETURNS text AS $$ SELECT $1 || $2; $$ LANGUAGE SQL IMMUTABLE; -- <nove>                                                                                                                      

INSERT INTO fractal.shade (id,value) VALUES (0,ORD(' ')),(1,ORD('.')),(2,ORD(',')),(3,ORD('-')),(4,ORD('~')),
(5,ORD('*')),(6,ORD(':')),(7,ORD(';')),(8,ORD('+')),
(9,ORD('o')),(10,ORD('O')),(11,ORD('&')),(12,ORD('%')),(13,ORD('@'));

CREATE OR REPLACE FUNCTION fractal.mandelbrot (IN x_max INT, IN y_max INT, OUT _content VARCHAR(1000)) -- <zm>                                                                                                                   
RETURNS SETOF VARCHAR(1000) AS $$ -- <nove>                                                                                                                                                                                      
BEGIN
  DECLARE x INT DEFAULT 0;
  DECLARE y INT DEFAULT 0;
  DECLARE xf0 FLOAT;
  DECLARE yf0 FLOAT;
  DECLARE xf1 FLOAT;
  DECLARE yf1 FLOAT;
  DECLARE tf FLOAT;
  DECLARE l INT;
  DECLARE l_max INT;
  DECLARE buffer VARCHAR(1000);
  DECLARE tint INT;
  TRUNCATE fractal.disp; -- <zm>                                                                                                                                                                                                 
  SET l_max = (SELECT MAX(id) FROM fractal.shade LIMIT 1); -- <zm>                                                                                                                                                               
  WHILE y<y_max DO
    SET buffer='';
    SET x=0;
    WHILE x<x_max DO
      SET xf0=x*4.0/x_max-2.0;
      SET yf0=y*4.0/y_max-2.0;
      SET xf1=xf0;
      SET yf1=yf0;
      SET l=0;
      WHILE l<l_max AND xf1*xf1+yf1*yf1<4.0 DO
        SET tf=xf1*xf1-yf1*yf1+xf0;
        SET yf1=2.0*xf1*yf1+yf0;
        SET xf1=tf;
        SET l=l+1;
      END WHILE;
      SET tint = (SELECT value FROM fractal.shade WHERE id=l); -- <zm>                                                                                                                                                           
      SET buffer=CONCAT(chr(tint),buffer); --<zm>                                                                                                                                                                                
      SET x=x+1;
    END WHILE;
    INSERT INTO fractal.disp (id,content) VALUES (y,buffer); -- <zm>                                                                                                                                                             
    SET y=y+1;
  END WHILE;
  RETURN (SELECT content FROM fractal.disp ORDER BY id ASC); -- <zm>                                                                                                                                                             
END;
$$ LANGUAGE plpgpsm;

SELECT * FROM fractal.mandelbrot (50,30); -- <zm>