arrows.js
//var cv = document.getElementById('canvas');
//var ctx = cv.getContext('2d');
/**
 * Tworzy obiekt typu Arrow
 * 
 * @param endX
 *            float - współrzędna x tylnego końca strzałki
 * @param endY
 *            float - współrzędna y tylnego końca strzałki
 * @param arrowLength
 *            float - długość strzałki
 * @param arrowWidth
 *            float - grubość strzałki
 * @param arrowAngle
 *            float - kat pod ktorym jest skierowana strzalka katy podawane sa w
 *            stopniach, kat zerowy to polozenie godziny 3.00, katy wzrastaja w
 *            kierunku przeciwnym do wskazowek zegara
 * @param brudLength
 *            float - długość grota mierzona wzdłuż osi strzałki
 * @param brudAngle
 *            float - kąt między osią strzałki a brzegiem grota
 * @param close
 *            boolean -  true - grot bez wcięcia, false - grot z wcięciem             
 */
function drawArrow(endX, endY, arrowLength, arrowWidth, arrowAngle, brudLength,
        brudAngle, close) {
    this.endX = endX;
    this.endY = endY;
    this.arrowLength = arrowLength;
    this.arrowAngle = arrowAngle;
    this.brudLength = brudLength;
    this.brudAngle = brudAngle;
    this.close = close;
    var cosa = Math.cos(degToRad(arrowAngle));
    var sina = Math.sin(degToRad(arrowAngle));
    var half = arrowWidth / 2.0;
    var cosah = cosa * half;
    var sinah = sina * half;
    var startX = endX + arrowLength * Math.cos(degToRad(-arrowAngle));
    var startY = endY + arrowLength * Math.sin(degToRad(-arrowAngle));
    var middleX = endX + (arrowLength - brudLength)
            * Math.cos(degToRad(-arrowAngle));// x7
    var middleY = endY + (arrowLength - brudLength)
            * Math.sin(degToRad(-arrowAngle));// y7
    var cosb = Math.cos(degToRad(brudAngle));
    var sinb = Math.sin(degToRad(brudAngle));
    var w2 = half * cosb / sinb;
    var mmiddleX = endX + (arrowLength - w2) * Math.cos(degToRad(-arrowAngle));//
    var mmiddleY = endY + (arrowLength - w2) * Math.sin(degToRad(-arrowAngle));//
    var w3 = brudLength - w2;
    var w4 = w3 * sinb / cosb;
    var w5 = w4 + half;
    // -
    var x1 = endX - sinah;
    var y1 = endY - cosah;
    var x2 = endX + sinah;
    var y2 = endY + cosah;
    var x5 = middleX + sinah;
    var y5 = middleY + cosah;
    var x6 = middleX - sinah;
    var y6 = middleY - cosah;
    var x8 = mmiddleX + sinah;
    var y8 = mmiddleY + cosah;
    var x9 = mmiddleX - sinah;
    var y9 = mmiddleY - cosah;
    var x10 = middleX + sina * w5;
    var y10 = middleY + cosa * w5;
    var x11 = middleX - sina * w5;
    var y11 = middleY - cosa * w5;
    ctx.save();
    ctx.beginPath();
    if (this.close) {
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        ctx.lineTo(x5, y5);
        ctx.lineTo(x10, y10);
        ctx.lineTo(x8, y8);
        ctx.lineTo(startX, startY);
        ctx.lineTo(x9, y9);
        ctx.lineTo(x11, y11);
        ctx.lineTo(x6, y6);
        ctx.closePath();
    } else {
        ctx.moveTo(x11, y11);
        ctx.lineTo(x9, y9);
        ctx.moveTo(x10, y10);
        ctx.lineTo(x8, y8);
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        ctx.lineTo(x8, y8);
        ctx.lineTo(startX, startY);
        ctx.lineTo(x9, y9);
        ctx.closePath();

    }
    ctx.restore();
}
;
/*
 * funkcja zamienia stopnie na radiany
 */
// k¹t deg podajemy w stopniach
var degToRad = function (deg) {
    return Math.PI * deg / 180.0;
};

/*
 * funkcja zamienia radiany na stopnie k¹t rad podajemy w radianach
 */
var radToDeg = function (rad) {
    return rad * 180.0 / Math.PI;
};
var arrowLength = function (x1, y1, x2, y2) {
    var distance = 0.0;
    var x3 = x1 - x2;
    var y3 = y1 - y2;
    distance = Math.sqrt(x3 * x3 + y3 * y3);
    return distance;
};
var atan2Deg = function (yy, xx) {
    return Math.atan2(yy, xx) * 180.0 / Math.PI;
};
var arrowAngle = function (x1, y1, x2, y2) {
    var x3 = x1 - x2;
    var y3 = y1 - y2;
    return atan2Deg(x3, y3);
};
figures.js
var Figure = function () {
    this.globalAlpha = 1.0;
    this.globalCompositeOperation = "source-over";
    this.strokeStyle = "black";
    this.fillStyle = "black";
    this.shadowOffsetX = 0.0;
    this.shadowOffsetY = 0.0;
    this.shadowBlur = 0.0;
    this.shadowColor = "black";
    this.lineWidth = 1.0;
    this.lineCap = "butt";
    this.lineJoin = "miter";
    this.miterLimit = 10.0;
    this.lineDashOffset = 5.0;
    this.lineDashSegments = [];
    this.fill = false;
    this.stroke = false;
};
Figure.prototype.setProps = function (context) {
    context.globalAlpha = this.globalAlpha;
    context.globalCompositeOperation = this.globalCompositeOperation;
    context.strokeStyle = this.strokeStyle;
    context.fillStyle = this.fillStyle;
    context.shadowOffsetX = this.shadowOffsetX;
    context.shadowOffsetY = this.shadowOffsetY;
    context.shadowBlur = this.shadowBlur;
    context.shadowColor = this.shadowColor;
    context.lineWidth = this.lineWidth;
    context.lineCap = this.lineCap;
    context.lineJoin = this.lineJoin;
    context.miterLimit = this.miterLimit;
    context.lineDashOffset = this.lineDashOffset;
    context.lineDashSegments = this.lineDashSegments;
};
// Point
// 0 - tworzy punkt P(0,0)
// 2 - dwie współrzędne x i y
var Point = function () {
    var len = arguments.length;
    if (len === 0) {
        this.x = 0.0;
        this.y = 0.0;
    } else if (len === 2) {
        this.x = arguments[0];
        this.y = arguments[1];
    }
    this.diam = 5.0;// promień
    this.shape = "circle";
};
Point.prototype = new Figure();
Point.prototype.distance = function (point) {
    var a = point.x - this.x;
    var b = point.y - this.y;
    return Math.sqrt(a * a + b * b);
};
Point.prototype.deepclone = function () {
    var figure = new Point();
    figure.globalAlpha = this.globalAplpha;
    figure.globalCompositeOperation = this.globalCompositeOperation;
    figure.strokeStyle = this.strokeStyle;
    figure.fillStyle = this.fillStyle;
    figure.shadowOffsetX = this.shadowOffsetX;
    figure.shadowOffsetY = this.shadowOffsetY;
    figure.shadowBlur = this.shadowBlur;
    figure.shadowColor = this.shadowColor;
    figure.lineWidth = this.lineWidth;
    figure.lineCap = this.lineCap;
    figure.lineJoin = this.lineJoin;
    figure.miterLimit = this.miterLimit;
    figure.lineDashOffset = this.lineDashOffset;
    figure.lineDashSegments = [];
    for (var i = 0; i < this.lineDashSegments.length; i++) {
        figure.lineDashSegments[i] = this.lineDashSegments[i];
    }
    figure.fill = this.fill;
    figure.stroke = this.stroke;
    figure.x = this.x;
    figure.y = this.y;
    figure.diam = this.diam;
    figure.shape = this.shape;
    return figure;
};
Point.prototype.draw = function (context) {
    context.save();
    context.beginPath();
    this.setProps(context);
    switch (this.shape) {
        case "circle":
            context.arc(this.x, this.y, this.diam / 2.0, 0.0, 2 * Math.PI, 
              false);
            break;
        case "square":
            context.rect(this.x - this.diam / 2.0, this.y - this.diam / 2.0,
                    this.diam, this.diam);
            break;
        case "cross":
            context.moveTo(this.x - this.diam / 2.0, this.y);
            context.lineTo(this.x + this.diam / 2.0, this.y);
            context.moveTo(this.x, this.y - this.diam / 2.0);
            context.lineTo(this.x, this.y + this.diam / 2.0);
            break;
    }
    if (this.stroke === true) {
        context.stroke();
    }
    if (this.fill === true) {
        context.fill();
    }
    context.restore();
};
// Segment = Odcinek
// Liczba argumentów
// 0 - automatyczne wstawienie tego samego punktu (0,0)
// 1 - tablica punktów
// 2 - dwa punkty
// 4 - cztery wspolrzedne dwoch punktow (x,y)
var Segment = function () {
    this.points = [];
    var len = arguments.length;
    if (len === 0) {
        this.points[0] = new Point(0.0, 0.0);
        this.points[1] = new Point(0.0, 0.0);
    } else if (len === 1) {
        for (var i = 0; i < 2; i++) {
            this.points[i] = new Point(arguments[0][i].x, arguments[0][i].y);
        }
    } else if (len === 2) {
        this.points[0] = new Point(arguments[0].x, arguments[0].y);
        this.points[1] = new Point(arguments[1].x, arguments[1].y);
    } else if (len === 4) {
        this.points[0] = new Point(arguments[0], arguments[1]);
        this.points[1] = new Point(arguments[2], arguments[3]);
    }
};
Segment.prototype = new Figure();
Segment.prototype.length = function () {
    return distance(this.points[0], this.points[1]);
};
Segment.prototype.deepclone = function () {
    var figure = new Segment();
    figure.globalAlpha = this.globalAplpha;
    figure.globalCompositeOperation = this.globalCompositeOperation;
    figure.strokeStyle = this.strokeStyle;
    figure.fillStyle = this.fillStyle;
    figure.shadowOffsetX = this.shadowOffsetX;
    figure.shadowOffsetY = this.shadowOffsetY;
    figure.shadowBlur = this.shadowBlur;
    figure.shadowColor = this.shadowColor;
    figure.lineWidth = this.lineWidth;
    figure.lineCap = this.lineCap;
    figure.lineJoin = this.lineJoin;
    figure.miterLimit = this.miterLimit;
    figure.lineDashOffset = this.lineDashOffset;
    figure.lineDashSegments = [];
    for (var i = 0; i < this.lineDashSegments.length; i++) {
        figure.lineDashSegments[i] = this.lineDashSegments[i];
    }
    figure.fill = this.fill;
    figure.stroke = this.stroke;
    figure.points = [];
    for (var i = 0; i < this.points.length; i++) {
        figure.points[i] = new Point(this.points[i].x, this.points[i].y);
    }
    return figure;
};
Segment.prototype.barycenter = function () {
    var x = (this.points[0].x + this.points[1].x) / 2.0;
    var y = (this.points[0].y + this.points[1].y) / 2.0;
    return new Point(x, y);
};
Segment.prototype.draw = function (context) {
    context.save();
    context.beginPath();
    this.setProps(context);
    context.moveTo(this.points[0].x, this.points[0].y);
    context.lineTo(this.points[1].x, this.points[1].y);
    if (this.stroke === true) {
        context.stroke();
    }
    context.restore();
};
function distance(pointA, pointB) {
    var a = pointB.x - pointA.x;
    var b = pointB.y - pointA.y;
    return Math.sqrt(a * a + b * b);
}
// Triangle (trójkąt)
// Liczba argumentów
// 0 - automatyczne wstawienie tego samego punktu (0,0)
// 1 - tablica punktów
// 3 - trzy punkty
// 6 - sześć wspolrzednych trzech punktow (x,y)
var Triangle = function () {
    this.points = [];
    var len = arguments.length;
    if (len === 0) {
        this.points[0] = new Point(0.0, 0.0);
        this.points[1] = new Point(0.0, 0.0);
        this.points[2] = new Point(0.0, 0.0);
    } else if (len === 1) {
        for (var i = 0; i < 3; i++) {
            this.points[i] = new Point(arguments[0][i].x, arguments[0][i].y);
        }
    } else if (len === 3) {
        this.points[0] = new Point(arguments[0].x, arguments[0].y);
        this.points[1] = new Point(arguments[1].x, arguments[1].y);
        this.points[2] = new Point(arguments[2].x, arguments[2].y);
    } else if (len === 6) {
        this.points[0] = new Point(arguments[0], arguments[1]);
        this.points[1] = new Point(arguments[2], arguments[3]);
        this.points[2] = new Point(arguments[4], arguments[5]);
    }
};
Triangle.prototype = new Figure();
Triangle.prototype.isTriangle = function () {
    var d1 = distance(this.points[0], this.points[1]);
    var d2 = distance(this.points[0], this.points[2]);
    var d3 = distance(this.points[1], this.points[2]);
    var tab = new Array(d1, d2, d3);
    tab.sort(comparison);
    if (tab[0] < tab[1] + tab[2]) {
        return true;
    }
    return false;
};
Triangle.prototype.area = function () {
    var a = distance(this.points[0], this.points[1]);
    var b = distance(this.points[0], this.points[2]);
    var c = distance(this.points[1], this.points[2]);
    var p = (a + b + c) / 2.0;
    return Math.sqrt(p * (p - a) * (p - b) * (p - c));
};
Triangle.prototype.perimeter = function () {
    var a = distance(this.points[0], this.points[1]);
    var b = distance(this.points[0], this.points[2]);
    var c = distance(this.points[1], this.points[2]);
    return a + b + c;
};
Triangle.prototype.deepclone = function () {
    var figure = new Triangle();
    figure.globalAlpha = this.globalAplpha;
    figure.globalCompositeOperation = this.globalCompositeOperation;
    figure.strokeStyle = this.strokeStyle;
    figure.fillStyle = this.fillStyle;
    figure.shadowOffsetX = this.shadowOffsetX;
    figure.shadowOffsetY = this.shadowOffsetY;
    figure.shadowBlur = this.shadowBlur;
    figure.shadowColor = this.shadowColor;
    figure.lineWidth = this.lineWidth;
    figure.lineCap = this.lineCap;
    figure.lineJoin = this.lineJoin;
    figure.miterLimit = this.miterLimit;
    figure.lineDashOffset = this.lineDashOffset;
    figure.lineDashSegments = [];
    for (var i = 0; i < this.lineDashSegments.length; i++) {
        figure.lineDashSegments[i] = this.lineDashSegments[i];
    }
    figure.fill = this.fill;
    figure.stroke = this.stroke;
    figure.points = [];
    for (var i = 0; i < this.points.length; i++) {
        figure.points[i] = new Point(this.points[i].x, this.points[i].y);
    }
    return figure;
};
Triangle.prototype.barycenter = function () {
    var x = (this.points[0].x + this.points[1].x + this.points[2].x) / 3.0;
    var y = (this.points[0].y + this.points[1].y + this.points[2].y) / 3.0;
    return new Point(x, y);
};
Triangle.prototype.draw = function (context) {
    context.save();
    context.beginPath();
    this.lineCap = "square";
    this.setProps(context);
    context.moveTo(this.points[0].x, this.points[0].y);
    context.lineTo(this.points[1].x, this.points[1].y);
    context.lineTo(this.points[2].x, this.points[2].y);
    context.closePath();
    if (this.stroke === true) {
        context.stroke();
    }
    if (this.fill === true) {
        context.fill();
    }
    context.restore();
};
// Rectangle (Prostokąt)
// Liczba argumentów
// 0 - automatyczne wstawienie tego samego punktu (0,0)
// 1 - tablica punktów
// 3 - Point(x, y), w, h
// 4 - x, y, w, h
var Rectangle = function () {
    this.points = [];
    var len = arguments.length;
    if (len === 0) {
        this.points[0] = new Point(0.0, 0.0);
        this.points[1] = new Point(0.0, 0.0);
        this.points[2] = new Point(0.0, 0.0);
        this.points[3] = new Point(0.0, 0.0);
    } else if (len === 1) {
        for (var i = 0; i < 4; i++) {
            this.points[i] = new Point(arguments[0][i].x, arguments[0][i].y);
        }
    } else if (len === 3) {
        this.points[0] = new Point(arguments[0].x, arguments[0].y);
        this.points[1] = new Point(arguments[0].x + arguments[1],
                arguments[0].y);
        this.points[2] = new Point(arguments[0].x + arguments[1],
                arguments[0].y + arguments[2]);
        this.points[3] = new Point(arguments[0].x, arguments[0].y
                + arguments[2]);

    } else if (len === 4) {
        this.points[0] = new Point(arguments[0], arguments[1]);
        this.points[1] = new Point(arguments[0] + arguments[2], arguments[1]);
        this.points[2] = new Point(arguments[0] + arguments[2], arguments[1]
                + arguments[3]);
        this.points[3] = new Point(arguments[0], arguments[1] + arguments[3]);
    }
};
Rectangle.prototype = new Figure();
Rectangle.prototype.isRectangle = function () {
    var d1 = roundToDecimal(distance(this.point[0], this.points[1]), 4);
    var d2 = roundToDecimal(distance(this.points[1], this.points[2]), 4);
    var d3 = roundToDecimal(distance(this.points[2], this.points[3]), 4);
    var d4 = roundToDecimal(distance(this.points[3], this.points[0]), 4);
    if (d1 === d3 && d2 === d4) {
        return true;
    }
    return false;
};
Rectangle.prototype.area = function () {
    var a = distance(this.points[0], this.points[1]);
    var b = distance(this.points[1], this.points[2]);
    return a * b;
};
Rectangle.prototype.deepclone = function () {
    var figure = new Rectangle();
    figure.globalAlpha = this.globalAplpha;
    figure.globalCompositeOperation = this.globalCompositeOperation;
    figure.strokeStyle = this.strokeStyle;
    figure.fillStyle = this.fillStyle;
    figure.shadowOffsetX = this.shadowOffsetX;
    figure.shadowOffsetY = this.shadowOffsetY;
    figure.shadowBlur = this.shadowBlur;
    figure.shadowColor = this.shadowColor;
    figure.lineWidth = this.lineWidth;
    figure.lineCap = this.lineCap;
    figure.lineJoin = this.lineJoin;
    figure.miterLimit = this.miterLimit;
    figure.lineDashOffset = this.lineDashOffset;
    figure.lineDashSegments = [];
    for (var i = 0; i < this.lineDashSegments.length; i++) {
        figure.lineDashSegments[i] = this.lineDashSegments[i];
    }
    figure.fill = this.fill;
    figure.stroke = this.stroke;
    figure.points = [];
    for (var i = 0; i < this.points.length; i++) {
        figure.points[i] = new Point(this.points[i].x, this.points[i].y);
    }
    return figure;
};
Rectangle.prototype.barycenter = function () {
    var x = (this.points[0].x + this.points[1].x) / 2.0;
    var y = (this.points[0].y + this.points[3].y) / 2.0;
    return new Point(x, y);
};
Rectangle.prototype.perimeter = function () {
    var a = distance(this.points[0], this.points[1]);
    var b = distance(this.points[1], this.points[2]);
    return 2 * (a + b);
};
Rectangle.prototype.diagonal = function () {
    var a = distance(this.points[0], this.points[1]);
    var b = distance(this.points[1], this.points[2]);
    return Math.sqrt(a * a + b * b);
};
Rectangle.prototype.draw = function (context) {
    context.save();
    context.beginPath();
    this.setProps(context);
    context.moveTo(this.points[0].x, this.points[0].y);
    context.lineTo(this.points[1].x, this.points[1].y);
    context.lineTo(this.points[2].x, this.points[2].y);
    context.lineTo(this.points[3].x, this.points[3].y);
    context.closePath();
    if (this.stroke === true) {
        context.stroke();
    }
    if (this.fill === true) {
        context.fill();
    }
    context.restore();
};
// IrregPolygon
// Liczba argumentów
// 0 Tworzy wielokąt zerowy
// 1 - tablica punktów
// więcej niż 1 - pojedyncze punkty Point(x,y)
var IrregPolygon = function () {
    this.points = [];
    var len = arguments.length;
    if (len === 0) {
        this.points[0] = new Point(0.0, 0.0);
    } else if (len === 1) {
        for (var i = 0; i < arguments[0].length; i++) {
            this.points[i] = new Point(arguments[0][i].x, arguments[0][i].y);
        }
    } else {
        for (var i = 0; i < len; i++) {
            this.points[i] = new Point(arguments[i].x, arguments[i].y);
        }
    }
};
IrregPolygon.prototype = new Figure();
IrregPolygon.prototype.deepclone = function () {
    var figure = new IrregPolygon();
    figure.globalAlpha = this.globalAplpha;
    figure.globalCompositeOperation = this.globalCompositeOperation;
    figure.strokeStyle = this.strokeStyle;
    figure.fillStyle = this.fillStyle;
    figure.shadowOffsetX = this.shadowOffsetX;
    figure.shadowOffsetY = this.shadowOffsetY;
    figure.shadowBlur = this.shadowBlur;
    figure.shadowColor = this.shadowColor;
    figure.lineWidth = this.lineWidth;
    figure.lineCap = this.lineCap;
    figure.lineJoin = this.lineJoin;
    figure.miterLimit = this.miterLimit;
    figure.lineDashOffset = this.lineDashOffset;
    figure.lineDashSegments = [];
    for (var i = 0; i < this.lineDashSegments.length; i++) {
        figure.lineDashSegments[i] = this.lineDashSegments[i];
    }
    figure.fill = this.fill;
    figure.stroke = this.stroke;
    figure.points = [];
    for (var i = 0; i < this.points.length; i++) {
        figure.points[i] = new Point(this.points[i].x, this.points[i].y);
    }
    return figure;
};
IrregPolygon.prototype.barycenter = function () {
    var cv1 = document.getElementById("testcanvas");
    var ctx1 = cv1.getContext("2d");
    var w = cv1.width;
    var h = cv1.height;
    var barray = this.deepclone();
    var len = barray.points.length;
    barray.draw(ctx1);
    var last;
    var triangle;
    var segment;
    var centrum;
    var area = 0.0;
    var areax = 0.0;
    var areay = 0.0;
    while (len > 2) {
        last = len - 1;
        triangle = new Triangle(barray.points[0], barray.points[1],
                barray.points[last]);
        segment = new Segment(barray.points[1], barray.points[last]);
        centrum = segment.barycenter();
        if (ctx1.isPointInPath(centrum.x, centrum.y)) {
            var arear = triangle.area();
            area += arear;
            var bary = triangle.barycenter();
            areax += (bary.x * arear);
            areay += (bary.y * arear);
            barray.points.shift();
            len = barray.points.length;

        } else {
            triangle = new Triangle(barray.points[last], barray.points[0],
                    barray.points[last - 1]);
            segment = new Segment(barray.points[0], barray.points[last - 1]);
            centrum = segment.barycenter();
            var arear = triangle.area();
            area += arear;
            var bary = triangle.barycenter();
            areax += (bary.x * arear);
            areay += (bary.y * arear);
            barray.points.pop();
            len = barray.points.length;
        }
    }
    return new Point(areax / area, areay / area);
};
IrregPolygon.prototype.area = function () {
    var cv1 = document.getElementById("testcanvas");
    var ctx1 = cv1.getContext("2d");
    var w = cv1.width;
    var h = cv1.height;
    var barray = this.deepclone();
    var len = barray.points.length;
    barray.draw(ctx1);
    var last;
    var triangle;
    var segment;
    var centrum;
    var area = 0.0;
    while (len > 2) {
        last = len - 1;
        triangle = new Triangle(barray.points[0], barray.points[1],
                barray.points[last]);
        segment = new Segment(barray.points[1], barray.points[last]);
        centrum = segment.barycenter();
        if (ctx1.isPointInPath(centrum.x, centrum.y)) {
            var arear = triangle.area();
            area += arear;
            barray.points.shift();
            len = barray.points.length;
        } else {
            triangle = new Triangle(barray.points[last], barray.points[0],
                    barray.points[last - 1]);
            segment = new Segment(barray.points[0], barray.points[last - 1]);
            var arear = triangle.area();
            area += arear;
            barray.points.pop();
            len = barray.points.length;
        }
    }
    return area;
};
IrregPolygon.prototype.perimeter = function () {
    var len = this.points.length;
    var perimeter = distance(this.points[len - 1], this.points[0]);
    for (var i = 0; i < len - 1; i++) {
        perimeter += distance(this.points[i], this.points[i + 1]);
    }
    return perimeter;
};
IrregPolygon.prototype.draw = function (context) {
    context.save();
    context.beginPath();
    this.setProps(context);
    context.moveTo(this.points[0].x, this.points[0].y);
    for (var i = 1; i < this.points.length; i++) {
        context.lineTo(this.points[i].x, this.points[i].y);
    }
    context.closePath();
    if (this.stroke === true) {
        context.stroke();
    }
    if (this.fill === true) {
        context.fill();
    }
    context.restore();
};
// RegPolygon (Wielobok)
// Liczba argumentów
// 0 Tworzy wielokąt z jednym punktem P(0,0) i
// promieniu (0,0)
// 3 środek P(x,y), liczba boków, promień;
var RegPolygon = function () {
    this.points = [];
    var len = arguments.length;
    if (len === 0) {
        this.center = new Point(0, 0);
        this.sides = 0;
        this.r = 0;
        this.points[0] = new Point(0.0, 0.0);
    } else if (len === 3) {
        this.center = new Point(arguments[0].x, arguments[0].y);
        this.sides = arguments[1];// liczba boków
        this.r = arguments[2];// promień
        this.points[0] = new Point(arguments[0].x + this.r, arguments[0].y);
        for (var i = 1; i < this.sides; i++) {
            this.points[i] = new Point(arguments[0].x + this.r
                    * Math.cos(i * 2 * Math.PI / this.sides), arguments[0].y
                    + this.r * Math.sin(i * 2 * Math.PI / this.sides));
        }
    }
};
RegPolygon.prototype = new Figure();
RegPolygon.prototype.area = function () {
    var area = 0.0;
    var a = distance(this.points[0], this.points[1]);
    var ka = a * a;
    switch (this.sides) {
        case 3:
            area = Math.sqrt(3) / 4.0 * ka;
            break;
        case 4:
            area = ka;
            break;
        case 5:
            area = Math.sqrt(25 + 10 * Math.sqrt(5)) / 4 * ka;
            break;
        case 6:
            area = 3 * Math.sqrt(3) / 2 * ka;
            break;
        case 7:
            area = 3.6339 * ka;
            break;
        case 8:
            area = 2(1 + Math.sqrt(2)) * ka;
            break;
        case 9:
            area = 6.1818 * ka;
            break;
        case 10:
            area = 5 * Math.sqrt(25 + 10 * Math.sqrt(5)) / 2 * ka;
            break;
        case 12:
            area = 3 * (2 + Math.sqrt(3)) * ka;
            break;
        default:
            area = this.sides / 4
                    * (Math.cos(Math.PI / sides) / Math.sin(Math.PI / 
                        sides)) * ka;
            break;
    }
    return area;
};
RegPolygon.prototype.deepclone = function () {
    var figure = new RegPolygon();
    figure.globalAlpha = this.globalAplpha;
    figure.globalCompositeOperation = this.globalCompositeOperation;
    figure.strokeStyle = this.strokeStyle;
    figure.fillStyle = this.fillStyle;
    figure.shadowOffsetX = this.shadowOffsetX;
    figure.shadowOffsetY = this.shadowOffsetY;
    figure.shadowBlur = this.shadowBlur;
    figure.shadowColor = this.shadowColor;
    figure.lineWidth = this.lineWidth;
    figure.lineCap = this.lineCap;
    figure.lineJoin = this.lineJoin;
    figure.miterLimit = this.miterLimit;
    figure.lineDashOffset = this.lineDashOffset;
    figure.lineDashSegments = [];
    for (var i = 0; i < this.lineDashSegments.length; i++) {
        figure.lineDashSegments[i] = this.lineDashSegments[i];
    }
    figure.fill = this.fill;
    figure.stroke = this.stroke;
    figure.points = [];
    for (var i = 0; i < this.points.length; i++) {
        figure.points[i] = new Point(this.points[i].x, this.points[i].y);
    }
    figure.center = new Point(this.center.x, this.center.y);
    figure.sides = this.sides;
    figure.r = this.r;
    return figure;
};
RegPolygon.prototype.barycenter = function () {
    return new Point(this.center.x, this.center.y);
};
RegPolygon.prototype.perimeter = function () {
    var dist = distance(this.points[0], this.points[1]);
    return dist * this.sides;
};
RegPolygon.prototype.draw = function (context) {
    context.save();
    context.beginPath();
    this.setProps(context);
    context.moveTo(this.points[0].x, this.points[0].y);
    for (var i = 1; i < this.sides; i++) {
        context.lineTo(this.points[i].x, this.points[i].y);
    }
    context.closePath();
    if (this.stroke === true) {
        context.stroke();
    }
    if (this.fill === true) {
        context.fill();
    }
    context.restore();
};
// StarPolygon - wielokąt gwiaździsty
// Liczba argumentów
// 0 Tworzy wielokąt zerowy z jednym punktem P(0,0) i //promieniu (0,0)
// 4 środek P(x,y), liczba boków, co ile, promień;
var StarPolygon = function () {
    this.points = [];
    var len = arguments.length;
    if (len === 0) {
        this.center = new Point(0, 0);// środek wielokąta
        this.sides = 0;// liczba boków
        this.k = 0; // co ile wierzchołków
        this.r = 0; // promień okręgu opisanego
        this.points[0] = new Point(0.0, 0.0);
    } else if (len === 4) {
        this.center = new Point(arguments[0].x, arguments[0].y);
        this.sides = arguments[1];// liczba boków
        this.k = arguments[2];
        this.r = arguments[3];// promień okręgu opisanego
        this.points[0] = new Point(arguments[0].x + this.r, arguments[0].y);
        for (var i = 1; i < this.sides; i++) {
            this.points[i] = new Point(arguments[0].x + this.r
                    * Math.cos(i * 2 * Math.PI / this.sides), arguments[0].y
                    + this.r * Math.sin(i * 2 * Math.PI / this.sides));
        }
    }
};
StarPolygon.prototype = new Figure();
StarPolygon.prototype.deepclone = function () {
    var figure = new StarPolygon();
    figure.globalAlpha = this.globalAplpha;
    figure.globalCompositeOperation = this.globalCompositeOperation;
    figure.strokeStyle = this.strokeStyle;
    figure.fillStyle = this.fillStyle;
    figure.shadowOffsetX = this.shadowOffsetX;
    figure.shadowOffsetY = this.shadowOffsetY;
    figure.shadowBlur = this.shadowBlur;
    figure.shadowColor = this.shadowColor;
    figure.lineWidth = this.lineWidth;
    figure.lineCap = this.lineCap;
    figure.lineJoin = this.lineJoin;
    figure.miterLimit = this.miterLimit;
    figure.lineDashOffset = this.lineDashOffset;
    figure.lineDashSegments = [];
    for (var i = 0; i < this.lineDashSegments.length; i++) {
        figure.lineDashSegments[i] = this.lineDashSegments[i];
    }
    figure.fill = this.fill;
    figure.stroke = this.stroke;
    figure.points = [];
    for (var i = 0; i < this.points.length; i++) {
        figure.points[i] = new Point(this.points[i].x, this.points[i].y);
    }
    figure.center = new Point(this.center.x, this.center.y);
    figure.sides = this.sides;
    figure.r = this.r;
    figure.k = this.k;
    return figure;
};
StarPolygon.prototype.barycenter = function () {
    return new Point(this.center.x, this.center.y);
};
StarPolygon.prototype.draw = function (context) {
    context.save();
    context.beginPath();
    this.setProps(context);
    var n = this.points.length;
    var k = this.k;
    var ilefigur = nwd2(n, k);
    var ileelem = n / ilefigur;
    var points1 = sortCyclic(this.points, k);
    if (ilefigur === 1) {
        context.moveTo(points1[0].x, points1[0].y);
        for (var i = 1; i < n; i++) {
            context.lineTo(points1[i].x, points1[i].y);
        }
        context.closePath();
    } else {
        for (var j = 0; j < n; j += ileelem) {
            context.moveTo(points1[j].x, points1[j].y);
            for (var m = j; m < j + ileelem - 1; m++) {
                context.lineTo(points1[m + 1].x, points1[m + 1].y);
            }
            context.closePath();
        }
    }
    if (this.stroke === true) {
        context.stroke();
    }
    if (this.fill === true) {
        context.fill();
    }
    context.restore();
};
// Star - gwiazda
// Liczba argumentów
// Gwiazda zerowa
// 4 środek P(x,y), outerR, innerR, apices;
var Star = function () {
    this.points = [];
    this.points1 = [];
    var len = arguments.length;
    if (len === 0) {
        this.center = new Point(0, 0);// środek wielokąta
        this.outerR = 0.0;// średnica zewnętrzna
        this.innerR = 0.0; // średnica wewnętrzna
        this.apices = 0; // liczba promieni (wierzchołków)
        this.points[0] = new Point(0.0, 0.0);
        this.alfa = 0.0;
    } else if (len === 4) {
        this.center = new Point(arguments[0].x, arguments[0].y);
        this.outerR = arguments[1];// promień okręgu opisanego
        this.innerR = arguments[2];// promień okręgu wpisanego
        this.apices = arguments[3];// liczba promieni (wierzchołków)
        this.alfa = 360.0 / this.apices;
        var r = 0.5 * this.outerR;
        for (var i = 0; i < this.apices; i++) {
            this.points[i] = new Point(this.center.x + r
                    * Math.cos(degToRad(this.alfa * i)), this.center.y + r
                    * Math.sin(degToRad(this.alfa * i)));
            this.points1[i] = new Point(this.center.x + this.innerR / 2.0
                    * Math.cos(degToRad((this.alfa * i) + 0.5 * this.alfa)),
                    this.center.y
                    + this.innerR
                    / 2.0
                    * Math.sin(degToRad((this.alfa * i) + 0.5
                            * this.alfa)));
        }
    }
};
Star.prototype = new Figure();
Star.prototype.deepclone = function () {
    var figure = new StarPolygon();
    figure.globalAlpha = this.globalAplpha;
    figure.globalCompositeOperation = this.globalCompositeOperation;
    figure.strokeStyle = this.strokeStyle;
    figure.fillStyle = this.fillStyle;
    figure.shadowOffsetX = this.shadowOffsetX;
    figure.shadowOffsetY = this.shadowOffsetY;
    figure.shadowBlur = this.shadowBlur;
    figure.shadowColor = this.shadowColor;
    figure.lineWidth = this.lineWidth;
    figure.lineCap = this.lineCap;
    figure.lineJoin = this.lineJoin;
    figure.miterLimit = this.miterLimit;
    figure.lineDashOffset = this.lineDashOffset;
    figure.lineDashSegments = [];
    for (var i = 0; i < this.lineDashSegments.length; i++) {
        figure.lineDashSegments[i] = this.lineDashSegments[i];
    }
    figure.fill = this.fill;
    figure.stroke = this.stroke;
    figure.points = [];
    for (var i = 0; i < this.points.length; i++) {
        figure.points[i] = new Point(this.points[i].x, this.points[i].y);
    }
    figure.points1 = [];
    for (var i = 0; i < this.points1.length; i++) {
        figure.points1[i] = new Point(this.points1[i].x, this.points1[i].y);
    }
    figure.center = new Point(this.center.x, this.center.y);
    figure.outerR = this.outerR;
    figure.innerR = this.innerR;
    figure.apices = this.apices;
    figure.alfa = this.alfa;
    return figure;
};
Star.prototype.barycenter = function () {
    return new Point(this.center.x, this.center.y);
};

Star.prototype.draw = function (context) {
    context.save();
    context.beginPath();
    this.setProps(context);
    context.moveTo(this.points1[this.apices - 1].x,
            this.points1[this.apices - 1].y);
    for (var i = this.apices - 1; i > 0; i--) {
        context.lineTo(this.points[i].x, this.points[i].y);
        context.lineTo(this.points1[i - 1].x, this.points1[i - 1].y);
    }
    context.lineTo(this.points[0].x, this.points[0].y);
    context.closePath();
    if (this.stroke === true) {
        context.stroke();
    }
    if (this.fill === true) {
        context.fill();
    }
    context.restore();
};
// Oval

// Liczba argumentów
// 0 - owal zerowy
// 4 punkt centralny Point(x,y), promień, startAngle, endAngle
// 5 punkt centralny Point(x,y), promień, startAngle, endAngle, 
// połowa wysokości elipsy
// jeśli to koło to parametr jest równy promieniowi
// 6 punkt centralny Point(x,y), promień, startAngle, endAngle, 
// połowa wysokości elipsy,
// jeśli to koło to parametr jest równy promieniowi
// czy to jest odcinek czy wycinek (true - odcinek koła lub elipsy,
// false (domyślny) - wycinek koła lub elipsy)
var Oval = function () {
    var len = arguments.length;
    this.counterClockwise = true;
    if (len === 0) {
        this.center = new Point(0, 0);
        this.r = 0.0;
        this.startAngle = 0.0;
        this.endAngle = 0.0;
        this.b = this.r;
        this.segment = false;
    } else if (len === 4) {
        this.center = new Point(arguments[0].x, arguments[0].y);
        this.r = arguments[1];
        this.startAngle = arguments[2];
        this.endAngle = arguments[3];
        this.b = this.r;
        this.segment = false;
    } else if (len === 5) {
        this.center = new Point(arguments[0].x, arguments[0].y);
        this.r = arguments[1];
        this.startAngle = arguments[2];
        this.endAngle = arguments[3];
        this.b = arguments[4];
        this.segment = false;
    } else if (len === 6) {
        this.center = new Point(arguments[0].x, arguments[0].y);
        this.r = arguments[1];
        this.startAngle = arguments[2];
        this.endAngle = arguments[3];
        this.b = arguments[4];
        this.segment = arguments[5];
    }
};
Oval.prototype = new Figure();
Oval.prototype.deepclone = function () {
    var figure = new StarPolygon();
    figure.globalAlpha = this.globalAplpha;
    figure.globalCompositeOperation = this.globalCompositeOperation;
    figure.strokeStyle = this.strokeStyle;
    figure.fillStyle = this.fillStyle;
    figure.shadowOffsetX = this.shadowOffsetX;
    figure.shadowOffsetY = this.shadowOffsetY;
    figure.shadowBlur = this.shadowBlur;
    figure.shadowColor = this.shadowColor;
    figure.lineWidth = this.lineWidth;
    figure.lineCap = this.lineCap;
    figure.lineJoin = this.lineJoin;
    figure.miterLimit = this.miterLimit;
    figure.lineDashOffset = this.lineDashOffset;
    figure.lineDashSegments = [];
    for (var i = 0; i < this.lineDashSegments.length; i++) {
        figure.lineDashSegments[i] = this.lineDashSegments[i];
    }
    figure.fill = this.fill;
    figure.stroke = this.stroke;
    figure.center = new Point(this.center.x, this.center.y);
    figure.r = this.r;
    figure.startAngle = this.startAngle;
    figure.endAngle = this.endAngle;
    figure.counterClockwise = this.counterClockwise;
    figure.b = this.b;
    figure.segment = this.segment;
    return figure;
};
Oval.prototype.barycenter = function () {
    return new Point(this.center.x, this.center.y);
};
Oval.prototype.draw = function (context) {
    var angle = 2 * Math.PI;
    context.save();
    context.beginPath();
    this.setProps(context);
    var s = this.b / this.r;
    context.translate(0, this.center.y - this.center.y * s);
    context.scale(1, s);
    if (this.stroke === true) {
        context
                .arc(this.center.x, this.center.y, this.r, angle
                        - this.startAngle, angle - this.endAngle,
                        this.counterClockwise);
        context.stroke();
    }
    if (this.fill === true) {
        if (this.segment) {
            context
                    .arc(this.center.x, this.center.y, this.r, angle
                            - this.startAngle, angle - this.endAngle,
                            this.counterClockwise);
        } else {

            context
                    .arc(this.center.x, this.center.y, this.r, angle
                            - this.startAngle, angle - this.endAngle,
                            this.counterClockwise);
            context.lineTo(this.center.x, this.center.y);

        }
        context.fill();
    }
    context.restore();
};
// ---------------------- różne funkcje pomocnicze ---------------------------

function comparison(x, y) {
    return y - x;
}
;
function roundToDecimal(num, dec) {
    var multi = Math.round(Math.pow(10, dec));
    var temp = Math.round(num * multi);
    var temp1 = temp * 1.0 / multi;
    return temp1;
}
;
function deepclone(parray) {
    var arraynew = [];
    for (var i = 0; i < parray.length; i++) {
        arraynew[i] = new Point(parray[i].x, parray[i].y);
    }
    return arraynew;
}
;
function nwd2(x, y) {
    if (y === 0) {
        return x;
    }
    while (x !== y) {
        if (x > y)
            x -= y;
        else
            y -= x;
    }
    return x;
}
;
function cutDecimal(nr) {
    var temp = nr.toString();
    var temp1 = temp.indexOf(".");
    var temp2 = "";
    if (temp1 > -1) {
        temp2 = temp.substr(0, temp1);
    } else {
        temp2 = temp;
    }
    return parseInt(temp2);
}
;
// k = krok )(co ile);
// zwraca nową tablicę liczb posortowanych cyklicznie
function sortCyclic(array, k) {
    var n = array.length;
    var tabl = [];
    var nwd = nwd2(n, k);
    var m = 0;
    switch (nwd) {
        case 1:
            var h = n * k;
            for (var i = 0; i < h; i += k) {
                tabl[m] = array[i - cutDecimal(i / n) * n];
                m++;
            }
            break;
        default:
            var h1 = n * k / nwd;
            for (var j = 0; j < nwd; j++) {
                for (var i = j; i < h1; i += k) {
                    tabl[m] = array[i - cutDecimal(i / n) * n];
                    m++;
                }
            }
            break;
    }
    return tabl;
}
;
var degToRad = function (deg) {
    return Math.PI * deg / 180.0;
};
autos.js
var cv = document.getElementById('canvas');
var ctx = cv.getContext('2d');
var width = cv.width;
var height = cv.height;
var liczbaPol = 100;
var szer = 8;// odleglosc miedzy liniami = szerokosc komorki
var len = szer * liczbaPol;
var len1 = len / 2;
var timer = null;
// tworzy automat o danym numerze zaczynajacy sie od wybranej kombinacji
// startowej
function Automaton(autoNumber, kombStart, ksztaltKomorek, kolorKomorek) {
    this.autoNumber = autoNumber;
    this.kombStart = kombStart;
    this.ksztaltKomorek = ksztaltKomorek;
    this.kolorKomorek = kolorKomorek;
    this.autos = new Array(liczbaPol * 2);
    for (var i = 0; i < liczbaPol * 2; i++) {
        this.autos[i] = new Array(liczbaPol * 2);
    }
    for (var k = 0; k < liczbaPol * 2; k++) {
        for (var j = 0; j < liczbaPol * 2; j++)
            this.autos[k][j] = 0;
    }
    var startCell = liczbaPol;
    this.autos[0][startCell - 1] = kombStart[0];
    this.autos[0][startCell] = kombStart[1];
    this.autos[0][startCell + 1] = kombStart[2];
    for (var m = 1; m < liczbaPol * 2 - 1; m++) {
        for (var n = 1; n < liczbaPol * 2 - 1; n++) {
            var arr = new Array(3);
            arr[0] = this.autos[m - 1][n - 1];
            arr[1] = this.autos[m - 1][n];
            arr[2] = this.autos[m - 1][n + 1];
            this.autos[m][n] = nextValue(arr, autoNumber);
        }
    }
}
;

var drawAutomaton = function (automaton) {
    ctx.save();
    ctx.beginPath();
    ctx.strokeStyle = "rgb(220,220,220)";
    var z = 0;// polozenie linii
    for (var i = 0; i <= liczbaPol / 2; i++) {
        ctx.moveTo(0, z);
        ctx.lineTo(len, z);
        z += szer;
    }
    z = 0;
    for (var k = 0; k <= liczbaPol; k++) {
        ctx.moveTo(z, 0);
        ctx.lineTo(z, len1);
        z += szer;
    }
    ctx.stroke();
    ctx.restore();
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = automaton.kolorKomorek;
    for (var m = 0; m < liczbaPol; m++) {
        for (var j = liczbaPol / 2; j < liczbaPol + liczbaPol / 2; j++) {
            if (automaton.autos[m][j] === 1) {
                var y = m * szer;
                var x = (j - liczbaPol / 2) * szer;
                switch (automaton.ksztaltKomorek) {
                    case "KOLO":
                        ctx.beginPath();
                        ctx.arc(x + szer / 2, y + szer / 2, szer / 2, 0,
                                Math.PI * 2, false);
                        ctx.fill();
                        break;
                    case "KWADRAT":
                        ctx.fillRect(x, y, szer, szer);
                }
            }
        }
    }
    ctx.fill();
    ctx.restore();

};

var order = function (array) {
    var val = 0;
    var len = array.length;
    for (var i = 0; i < len; i++) {
        if (array[len - 1 - i] === 1) {
            val += cutDecimal(Math.pow(2, i));
        }
    }
    return val;
};
var nextValue = function (array, automatNumber) {
    var val = order(array);
    var nbin = parseInt(automatNumber).toString(2);
    if (nbin.length < 8) {
        var diff = 8 - nbin.length;
        for (var i = 0; i < diff; i++) {
            nbin = "0".concat(nbin);
        }
    }
    var len = nbin.length;
    var sval = nbin.substring(len - val - 1, len - val);
    return parseInt(sval);
};
var cutDecimal = function (nr) {
    var temp = nr.toString();
    var temp1 = temp.indexOf(".");
    var temp2 = "";
    if (temp1 > -1) {
        temp2 = temp.substr(0, temp1);
    } else {
        temp2 = temp;
    }
    return parseInt(temp2);
};
function Life(ksztaltKomorek, kolorKomorek, probability) {
    this.ksztaltKomorek = ksztaltKomorek;
    this.kolorKomorek = kolorKomorek;
    this.probability = probability;
    this.autos1 = new Array(liczbaPol);
    this.autos2 = new Array(liczbaPol);
    for (var i = 0; i < liczbaPol; i++) {
        this.autos1[i] = new Array(liczbaPol);
        this.autos2[i] = new Array(liczbaPol);
    }
    for (var j = 0; j < liczbaPol; j++) {
        for (var k = 0; k < liczbaPol; k++) {
            this.autos1[j][k] = Math.random() < this.probability;
            this.autos2[j][k] = false;
        }
    }
}
Life.prototype.actualize = function () {
    var cells = this.autos1;
    for (var i = 0; i < liczbaPol; i++) {
        for (var j = 0; j < liczbaPol; j++) {
            this.autos2[i][j] = cells[i][j];
            var nb = this.liczbaSasiadow(cells, i, j);
            if (nb === 3)
                this.autos2[i][j] = true;
            if (nb < 2 || nb > 3)
                this.autos2[i][j] = false;
        }
    }
    this.autos1 = this.autos2;
    this.autos2 = cells;
};
// oblicza liczbe sasiadow komorki
// p i q sa indeksami okreslajacymi polozenie komorki
// autos[][] jest tablicą komórek
Life.prototype.liczbaSasiadow = function (autos, p, q) {
    var x1 = p;
    var x2 = p;
    var y1 = q;
    var y2 = q;
    var licznik = 0;
    if (p > 0) {
        x1--;
    }
    if (p < liczbaPol - 1) {
        x2++;
    }
    if (q > 0) {
        y1--;
    }
    if (q < liczbaPol - 1) {
        y2++;
    }
    for (var i = x1; i <= x2; i++) {
        for (var j = y1; j <= y2; j++) {
            licznik += (autos[i][j]) ? 1 : 0;
        }
    }
    if (autos[p][q]) {
        licznik--;
    }
    return licznik;
};
Life.prototype.drawLife = function () {
    this.actualize();
    ctx.save();
    ctx.clearRect(0, 0, 800, 800);
    ctx.beginPath();
    ctx.strokeStyle = "rgb(220,220,220)";
    var z = 0;// polozenie linii
    for (var i = 0; i <= liczbaPol; i++) {
        ctx.moveTo(0, z);
        ctx.lineTo(len, z);
        ctx.moveTo(z, 0);
        ctx.lineTo(z, len);
        z += szer;
    }
    ctx.stroke();
    ctx.beginPath();
    ctx.fillStyle = this.kolorKomorek;
    for (var m = 0; m < liczbaPol; m++) {
        for (var j = 0; j < liczbaPol; j++) {
            if (this.autos1[m][j]) {
                var y = m * szer;
                var x = j * szer;
                switch (this.ksztaltKomorek) {
                    case "KOLO":
                        ctx.beginPath();
                        ctx.arc(x + szer / 2, y + szer / 2, (szer / 2) - 1, 0,
                                Math.PI * 2, false);
                        ctx.fill();
                        break;
                    case "KWADRAT":
                        ctx.fillRect(x, y, szer, szer);
                        break;
                }
            }
        }

    }
    ctx.fill();
    ctx.restore();
};
Life.prototype.clear = function () {
    for (var j = 0; j < liczbaPol; j++) {
        for (var k = 0; k < liczbaPol; k++) {
            this.autos1[j][k] = false;
            this.autos2[j][k] = false;
        }
    }
};
Life.prototype.putStructure = function (array, cols) {
    this.clear();
    var arr = oneToTwo(array, cols);
    for (var m1 = 0; m1 < arr.length; m1++) {
        for (var j1 = 0; j1 < arr[0].length; j1++) {
            this.autos1[m1 + 25][j1 + 25] = arr[m1][j1];
        }
    }
};

var oneToTwo = function (tab, cols) {
    var rows = tab.length / cols;
    var temparr = new Array(rows);
    for (var k = 0; k < rows; k++) {
        temparr[k] = new Array(cols);
    }
    for (var i = 0; i < tab.length; i++) {
        var x = cutDecimal(i / cols);
        var y = i % cols;
        temparr[x][y] = tab[i];
    }
    return temparr;
};
ant.js
var cv = document.getElementById('canvas');
var ctx = cv.getContext('2d');
var width = cv.width;
var height = cv.height;
var w = 800;
var h = 800;
var liczbaPol = 100;
var ap = liczbaPol / 2;
var szer = 8;
var s = szer / 2;
var len = szer * liczbaPol;
var CW = "white";
var CB = "black";
var CR = "red";
var antx = ap;
var anty = ap;
var antDir = 1;
var timer;
var Ant = function () {
    this.autos1 = [];
    this.autos2 = [];
    for (var i = 0; i < liczbaPol; i++) {
        this.autos1[i] = [];
        this.autos2[i] = [];
    }
    this.clear();
};

Ant.prototype.clear = function () {
    for (var j = 0; j < liczbaPol; j++) {
        for (var k = 0; k < liczbaPol; k++) {
            this.autos1[j][k] = 0;
            this.autos2[j][k] = 0;
        }
    }
};

Ant.prototype.putStructure = function (x, y, array) {
    this.clear();
    for (var i = 0; i < array.length; i++) {
        for (var j = 0; j < array[0].length; j++) {
            this.autos1[i + y][j + x] = array[i][j];
        }
    }
};
Ant.prototype.run = function () {
    this.autos2 = clone(this.autos1);
    antDir = changeDir(antDir, this.autos2[antx][anty]);
    if (this.autos2[antx][anty] === 0) {
        this.autos2[antx][anty]++;
    } else if (this.autos2[antx][anty] === 1) {
        this.autos2[antx][anty]--;
    }

    if (antDir === 1) {
        anty--;
        if (anty === -1) {
            anty = liczbaPol - 1;
        }
    } else if (antDir === 2) {
        antx--;
        if (antx === -1) {
            antx = liczbaPol - 1;
        }
    } else if (antDir === 3) {
        anty++;
        if (anty === liczbaPol) {
            anty = 0;
        }
    } else if (antDir === 4) {
        antx++;
        if (antx === liczbaPol) {
            antx = 0;
        }
    }
    this.autos1 = clone(this.autos2);
    this.drawAnt();
};
Ant.prototype.drawAnt = function () {
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = CW;
    ctx.rect(0, 0, w, h);
    ctx.fill();
    ctx.strokeStyle = "lightgrey";
    var z = 0;// polozenie linii
    for (var k = 0; k <= liczbaPol + 1; k++) {
        ctx.moveTo(0, z);
        ctx.lineTo(len, z);
        ctx.moveTo(z, 0);
        ctx.lineTo(z, len);
        z += szer;
    }
    ctx.lineWidth = 0.5;
    ctx.stroke();
    ctx.beginPath();
    ctx.fillStyle = CB;
    for (var i = 0; i < liczbaPol; i++) {
        for (var j = 0; j < liczbaPol; j++) {
            var x = i * szer;
            var y = j * szer;
            if (this.autos1[i][j] === 1) {
                ctx.beginPath();
                ctx.rect(x, y, szer, szer);
                ctx.fill();
            }
            ctx.fillStyle = CR;
            ctx.beginPath();
            ctx.arc(antx * szer + s, anty * szer + s, s, 0, 2 * Math.PI, false);
            ctx.fill();
            ctx.fillStyle = CB;
        }
    }
    ctx.restore();
};

function changeDir(dir, col) {
    var newDir = 0;
    switch (dir) {
        case 1:
            if (col === 0) {
                newDir = 2;
            } else if (col === 1) {
                newDir = 4;
            }
            break;
        case 2:
            if (col === 0) {
                newDir = 3;
            } else if (col === 1) {
                newDir = 1;
            }
            break;
        case 3:
            if (col === 0) {
                newDir = 4;
            } else if (col === 1) {
                newDir = 2;
            }
            break;
        case 4:
            if (col === 0) {
                newDir = 1;
            } else if (col === 1) {
                newDir = 3;
            }
            break;
    }
    return newDir;
};

function clone(array) {
    var r = array.length;
    var c = array[0].length;
    var array1 = [];
    for (var k = 0; k < r; k++) {
        array1[k] = [];
    }
    for (var i = 0; i < r; i++) {
        for (var j = 0; j < c; j++) {
            array1[i][j] = array[i][j];
        }
    }
    return array1;
};
nagel.js
var cv = document.getElementById('canvas');
var ctx = cv.getContext('2d');
var width = cv.width;
var height = cv.height;
var w = 800;
var h = 80;
var liczbaPol = 100;
var szer = 8;
var len = szer * liczbaPol;
var params = 2;// predkosc, kolor
var timer;
var kolory = ["#000000", "#0000FF", "#00FFFF", "#C0C0C0", "#008000",
    "#808080", "#800000", "#FF0000", "#FF00FF", "#008080"];
function Nagel() {
    this.autos1 = [];
    this.autos2 = [];
    for (var i = 0; i < liczbaPol; i++) {
        this.autos1[i] = [];
        this.autos2[i] = [];
    }
    this.clear();
};
Nagel.prototype.runs = function () {
    this.autos2 = this.clone(this.autos1);
    //przegladamy wszystkie komorki zaczynajac od ostatniej
    for (var i = liczbaPol - 1; i >= 0; i--) {
        var speed = 0;
        var dist = 0;
        //sprawdzamy czy komorka jest zajeta czy nie
        if (this.autos2[i][0] !== -1) {
            //jesli tak zapisujemy predkosc
            speed = this.autos2[i][0];
            //sprawdzamy liczbe pustych kratek przed samochodem
            //czyli odleglosc od poprzedzającego samochodu
            for (var j = i + 1; j < liczbaPol; j++) {
                //jesli kratka jest wolna
                if (this.autos2[j][0] === -1) {
                    //zwiekszamy dystans
                    dist++;
                }
                //jesli jest zajeta - przerywamy zliczanie 
                //dystansu
                else {
                    break;
                }
            }
            //jesli samochod ma zbyt duza szybkosc w stosunku
            //do odleglosci - zmniejszamy szybkosc
            if (dist < speed) {
                speed = dist;
            }
            //albo jesli samochod ma wolna odleglosc, a nie
            //ma maksynmalnej szybkosc - podnosimy szybkosc 0 1
            else if ((dist > speed) && (speed < 5)) {
                speed++;
            }
            //wprowadzamy czynnik rozpraszający kierowcę
            //co powoduje hamowanie

            var rand1 = Math.random();
            if (rand1 < 0.3) {
                if (speed > 0) {
                    speed--;
                }
            }
            //jesli szybkosc jest wieksza od zero
            //przestawiamy samochod do przodu 
            if ((speed > 0) && (i + speed < 99)) {
                this.autos2[i + speed][0] = speed;
                this.autos2[i + speed][1] = this.autos2[i][1];
                this.autos2[i][0] = -1;
                this.autos2[i][1] = -1;
            } else {
                this.autos2[i][0] = -1;
                this.autos2[i][1] = -1;
            }
        }
    }
    //indeks komórki tablicy zawierającej ostatni samochód;
    //jeśli w tablicy nie ma zadnego samochodu indeks bedzie
    //mial wartosc 100;
    var index = 100;
    for (var m = 0; m < liczbaPol; m++) {
        if (this.autos2[m][0] !== -1) {
            index = m;
            break;
        }
    }
    //jesli w pierwszej komorce od lewej nie ma samochodu
    var x;
    if (index > 0) {
        x = Math.random();
        if (x < 0.7) {
            //
            //int s = Math.min(index, 5);
            var s = 1;
            var c = this.randomInRange(0, 9);
            this.autos2[0][0] = s;
            this.autos2[0][1] = c;
            //System.out.println(index + " " + s + " " + c);
        }
    }
    //-
    this.autos1 = this.clone(this.autos2);
    this.drawNagel();
};
Nagel.prototype.drawNagel = function () {
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = "#FFFFFF";
    ctx.rect(0, 0, w, h);
    ctx.fill();
    ctx.beginPath();
    ctx.lineWidth = 0.5;
    ctx.strokeStyle = "#a3a3a3";
    var z = 0;
    ctx.moveTo(0, h / 2);
    ctx.lineTo(len, h / 2);
    ctx.moveTo(0, szer + h / 2);
    ctx.lineTo(len, szer + h / 2);
    for (var i = 0; i < liczbaPol; i++) {
        ctx.moveTo(z, h / 2);
        ctx.lineTo(z, szer + h / 2);
        z += szer;
    }
    ctx.stroke();
    for (var i = 0; i < liczbaPol; i++) {
        if (this.autos1[i][1] > -1) {
            ctx.beginPath();
            ctx.fillStyle = kolory[this.autos1[i][1]];
            ctx.rect(1 + i * szer, 2 + h / 2, szer - 2, szer / 2);
            ctx.fill();
        }
    }
    ctx.fillStyle = "#000000";
    for (var i = 0; i < liczbaPol; i++) {
        if (this.autos1[i][0] > -1) {
            ctx.beginPath();
            ctx.fillText("" + this.autos1[i][0], 1 + i * szer, -5 + h / 2);
            ctx.fill();
        }
    }
    ctx.restore();
};
Nagel.prototype.clear = function () {
    for (var j = 0; j < liczbaPol; j++) {
        for (var k = 0; k < params; k++) {
            this.autos1[j][k] = -1;
            this.autos2[j][k] = -1;
        }
    }
};
Nagel.prototype.clone = function (array) {
    var r = array.length;
    var c = array[0].length;
    var array1 = [];
    for (var k = 0; k < r; k++) {
        array1[k] = [];
    }
    for (var i = 0; i < r; i++) {
        for (var j = 0; j < c; j++) {
            array1[i][j] = array[i][j];
        }
    }
    return array1;
};
Nagel.prototype.randomInRange = function (min, max) {
    var random = -1;
    if (min > max) {
        return new Error('Pierwsza liczba musi być mniejsza od drugiej');
    } else {
        random = this.cutDecimal(Math.floor(Math.random() * (max - min + 1)) 
              + min);
    }
    return random;
};
Nagel.prototype.cutDecimal = function (nr) {
    var temp = nr.toString();
    var temp1 = temp.indexOf(".");
    var temp2 = "";
    if (temp1 > -1) {
        temp2 = temp.substr(0, temp1);
    } else {
        temp2 = temp;
    }
    return parseInt(temp2);
};
fractals.js
var cv = document.getElementById('canvas');
var ctx = cv.getContext('2d');
var width = cv.width;
var height = cv.height;

// logarytm o dowolnej podstawie także o podstawie 10 lub e
var log = function (b, a) {
    return Math.log(b) / Math.log(a);
};
// scale = liczba oczek siatki w poziomie
// 2 oznacza siatke 2 x 2, 3 = 3 x 3, etc
var drawGrid = function (scale, show) {
    ctx.save();
    ctx.beginPath();
    ctx.lineWidth = 2;
    ctx.moveTo(0, 0);
    ctx.lineTo(width, 0);
    ctx.lineTo(width, height);
    ctx.lineTo(0, height);
    ctx.lineTo(0, 0);
    ctx.stroke();
    ctx.restore();
    if (!show) {
        drawPart(scale, 0.2);
    } else {
        for (var i = 0, j = log(scale, 2) - 1; i < log(scale, 2); i++, j--) {
            drawPart(scale / Math.pow(2, i), 2 / Math.pow(2, j));
        }
    }
};
// metoda pomocnicza do metody drawGrid
var drawPart = function (scale, lineWidth) {
    var szer = width / scale;
    var len = szer * scale;
    ctx.save();
    ctx.beginPath();
    ctx.lineWidth = lineWidth;
    var z = 0;// polozenie linii
    for (var i = 0; i <= scale; i++) {
        ctx.moveTo(0, z);
        ctx.lineTo(len, z);
        z += szer;
    }
    z = 0;
    for (var k = 0; k <= scale; k++) {
        ctx.moveTo(z, 0);
        ctx.lineTo(z, len);
        z += szer;
    }
    ctx.stroke();
    ctx.restore();
};
var drawCantorSet = function (steps) {

    var x = 5;// punkt startu
    var y = 4;// punkt startu
    var wt = width - 2 * x;// szerokosc rysunku
    ctx.save();
    ctx.beginPath();
    ctx.lineWidth = 1;
    for (var i = 0; i < steps; i++) {
        y += 20;
        var w = wt / Math.pow(3, i);// dlugosc odcinka
        var coeffs = coeffTable(i + 1);// tablica wspolczynnikow
        for (var j = 0; j < coeffs.length; j++) {
            ctx.moveTo(x + coeffs[j] * w, y);
            ctx.lineTo(x + coeffs[j] * w + w, y);
        }
    }
    ctx.stroke();
    ctx.restore();
};
// funkcja pomocnicza dla drawCantorSet
var coeffTable = function (steps) {
    var arr = null;
    if (steps === 1) {
        arr = new Array(1);
        arr[0] = 0;
    } else {
        arr = new Array(2);
        arr[0] = 0;
        arr[1] = 2;
        var x = 2;
        for (var i = 2; i < steps; i++) {
            var arr2 = copyArray(arr);
            for (var j = 0; j < arr2.length; j++) {
                arr2[j] += x * 3;
            }
            arr = arr.concat(arr2);
            x *= 3;
        }
    }
    return arr;
};
var copyArray = function (ar) {
    var arr2 = new Array(ar.length);
    for (var i = 0; i < arr2.length; i++) {
        arr2[i] = ar[i];
    }
    return arr2;
};
var drawKochCurve = function (steps) {
    var x = 5;// punkt startu
    var y = height / 2;// punkt startu
    var wt = width - 2 * x;// szerokosc rysunku
    ctx.save();
    ctx.translate(x, y);
    ctx.moveTo(0, 0);
    subflake(--steps, wt);
    ctx.restore();
    ctx.stroke();
};
var subflake = function (steps, wt) {
    ctx.save();
    if (steps === 0) {
        ctx.lineTo(wt, 0);
    } else {
        ctx.scale(1 / 3, 1 / 3);
        subflake(steps - 1, wt);
        ctx.rotate(-1 / 3 * Math.PI);
        subflake(steps - 1, wt);
        ctx.rotate(2 / 3 * Math.PI);
        subflake(steps - 1, wt);
        ctx.rotate(-1 / 3 * Math.PI);
        subflake(steps - 1, wt);
    }
    ctx.restore();
    ctx.stroke();
    ctx.translate(wt, 0);
};
var Vector2f = function (x, y) {
    switch (arguments.length) {
        case 0:
            this.x = 0.0;
            this.y = 0.0;
            break;
        case 2:
            this.x = arguments[0];
            this.y = arguments[1];
            break;
    }
};
Vector2f.prototype.toString = function () {
    return "V=[" + this.x + ", " + this.y + "]";
};
var v1, v2, v3, v4, v5, v6, v7, v8, v9;
var vs = new Array(new Vector2f(0, height), new Vector2f(width, height),
        new Vector2f(width / 2, height - Math.sqrt(3) / 2 * height));
var fillb = "blue";
var fillw = "white";
var drawSierpinskiGasket = function (steps) {
    ctx.save();
    ctx.fillStyle = fillb;
    fillSierpinskiGasket(vs);
    ctx.fillStyle = fillw;
    calcSierpinskiGasket(new Vector2f(vs[0].x, vs[0].y), 
           new Vector2f(vs[1].x,vs[1].y), 
           new Vector2f(vs[2].x, vs[2].y), steps);
    ctx.restore();
};

var fillSierpinskiGasket = function (vs) {
    ctx.beginPath();
    ctx.moveTo(vs[0].x, vs[0].y);
    ctx.lineTo(vs[1].x, vs[1].y);
    ctx.lineTo(vs[2].x, vs[2].y);
    ctx.closePath();
    ctx.fill();
};
var calcSierpinskiGasket = function (va, vb, vc, steps) {
    if (steps === 0) {
        return;
    }
    steps -= 1;
    var coords = new Array(new Vector2f(vc.x, vb.y), new Vector2f(
            (vc.x + vb.x) / 2, (vc.y + va.y) / 2), new Vector2f(
            (va.x + vc.x) / 2, (vc.y + va.y) / 2));
    fillSierpinskiGasket(coords);
    v1 = va;
    v4 = new Vector2f(vc.x, vb.y);
    v7 = new Vector2f((va.x + vc.x) / 2, (vc.y + va.y) / 2);
    calcSierpinskiGasket(v1, v4, v7, steps);
    v2 = new Vector2f(vc.x, vb.y);
    v5 = vb;
    v8 = new Vector2f((vc.x + vb.x) / 2, (vc.y + va.y) / 2);
    calcSierpinskiGasket(v2, v5, v8, steps);
    v3 = new Vector2f((va.x + vc.x) / 2, (vc.y + va.y) / 2);
    v6 = new Vector2f((vc.x + vb.x) / 2, (vc.y + va.y) / 2);
    v9 = vc;
    calcSierpinskiGasket(v3, v6, v9, steps);
};

var drawDragon = function (start, end, steps, strokeStyle) {
    ctx.save();
    if (steps === 0) {
        ctx.beginPath();
        ctx.strokeStyle = strokeStyle;
        ctx.moveTo(start.x, start.y);
        ctx.lineTo(end.x, end.y);
        ctx.stroke();

    } else {
        var v1 = new Vector2f((start.x + end.x) / 2, 
               (start.y + end.y) / 2);
        var v2 = new Vector2f(v1.x + end.y - v1.y, 
                v1.y + start.x - v1.x);
        ctx.strokeStyle = strokeStyle;
        drawDragon(end, v2, steps - 1);
        drawDragon(start, v2, steps - 1);

    }
    ctx.stroke();
    ctx.restore();
};
function JuliaFractal(iters, re, im, cre, cim) {
    this.min = -1.7;
    this.max = 1.7;
    this.scale = (this.max - this.min) / width;
    this.s = 2.0;
    this.iters = iters;
    this.re = re;
    this.im = im;
    this.cre = cre;
    this.cim = cim;
};

JuliaFractal.prototype.liczIter = function (zre1, zim1) {
    var zim = zim1;
    var zre = zre1;
    var kwad = 0.0;
    var licznik = 0;
    while ((kwad < this.s * this.s) && (licznik < this.iters)) {
        var tempr = zre * zre - zim * zim + this.cre;
        var tempz = this.s * zre * zim + this.cim;
        zre = tempr;
        zim = tempz;
        kwad = zim * zim + zre * zre;
        licznik++;
    }
    return this.iters - licznik;
};
JuliaFractal.prototype.index = function (row, col, cols) {
    return row * cols + col;
};
JuliaFractal.prototype.rowCol = function (indeks, cols) {
    var row = cutDecimal(indeks / cols);
    var col = indeks % cols;
    var arr = new Array(row, col);
    return arr;
};
var cutDecimal = function (nr) {
    var temp = nr.toString();
    var temp1 = temp.indexOf(".");
    var temp2 = "";
    if (temp1 > -1) {
        temp2 = temp.substr(0, temp1);
    } else {
        temp2 = temp;
    }
    return parseInt(temp2);
};
JuliaFractal.prototype.drawJulia = function () {
    var img1 = ctx.getImageData(0, 0, width, height);
    var idata = img1.data;
    for (var i = 0; i < idata.length; i += 4) {
        var ar = this.rowCol(i / 4, width);
        var zr = this.min + ar[1] * this.scale;
        var zi = this.min + ar[0] * this.scale;
        var licz = this.liczIter(zr, zi);
        idata[i] = ((licz >> 1) & 0x07) << 5;
        idata[i + 1] = ((licz >> 3) & 0x07) << 5;
        idata[i + 2] = ((licz >> 6) & 0x07) << 5;
        idata[i + 3] = 255;
    }
    ctx.putImageData(img1, 0, 0);
};
// -
function Mandelbrot(iters, re, im, cre, cim) {
    this.min = -2.5;
    this.max = 2.5;
    this.scale = (this.max - this.min) / width;
    this.s = 2.0;
    this.iters = iters;
    this.re = re;
    this.im = im;
    this.cre = cre;
    this.cim = cim;
};

Mandelbrot.prototype.liczIter = function (cre, cim) {
    var zim = 0;
    var zre = 0;
    var kwad = 0.0;
    var licznik = 0;
    while ((kwad < this.s * this.s) && (licznik < this.iters)) {
        var tempr = zre * zre - zim * zim + cre;
        var tempz = this.s * zre * zim + cim;
        zre = tempr;
        zim = tempz;
        kwad = zim * zim + zre * zre;
        licznik++;
    }
    return this.iters - licznik;
};
Mandelbrot.prototype.index = function (row, col, cols) {
    return row * cols + col;
};
Mandelbrot.prototype.rowCol = function (indeks, cols) {
    var row = cutDecimal(indeks / cols);
    var col = indeks % cols;
    var arr = new Array(row, col);
    return arr;
};
Mandelbrot.prototype.drawMandelbrot = function () {
    var img1 = ctx.getImageData(0, 0, width, height);
    var idata = img1.data;
    for (var i = 0; i < idata.length; i += 4) {
        var ar = this.rowCol(i / 4, width);
        var cre = this.min + ar[1] * this.scale;
        var cim = this.min + ar[0] * this.scale;
        var licz = this.liczIter(cre, cim);
        idata[i] = ((licz >> 1) & 0x07) << 5;
        idata[i + 1] = ((licz >> 3) & 0x07) << 5;
        idata[i + 2] = ((licz >> 6) & 0x07) << 5;
        idata[i + 3] = 255;
    }
    ctx.putImageData(img1, 0, 0);
};
// -
function BurningShip(iters, re, im) {
    this.min = -2.4;
    this.max = 2.4;
    this.scale = (this.max - this.min) / width;
    this.s = 2.0;
    this.iters = iters;
    this.re = re;
    this.im = im;
};
BurningShip.prototype.liczIter = function (cre, cim) {
    var tre = 0;
    var tim = 0;
    var kwad = 0.0;
    var licznik = 0;
    while ((kwad < this.s * this.s) && (licznik < this.iters)) {
        var tempr = tre * tre - tim * tim + cre;
        var tempi = 2 * Math.abs(tre * tim) + cim;
        tre = tempr;
        tim = tempi;
        kwad = tim * tim + tre * tre;
        licznik++;
    }
    return this.iters - licznik;
};
BurningShip.prototype.index = function (row, col, cols) {
    return row * cols + col;
};
BurningShip.prototype.rowCol = function (indeks, cols) {
    var row = cutDecimal(indeks / cols);
    var col = indeks % cols;
    var arr = new Array(row, col);
    return arr;
};
BurningShip.prototype.drawBurningShip = function () {
    var img1 = ctx.getImageData(0, 0, width, height);
    var idata = img1.data;
    for (var i = 0; i < idata.length; i += 4) {
        var ar = this.rowCol(i / 4, width);
        var cre = this.min + ar[1] * this.scale;
        var cim = this.min + ar[0] * this.scale;
        var licz = this.liczIter(cre, cim);
        idata[i] = ((licz >> 3) & 0x07) << 5;
        idata[i + 1] = ((licz >> 3) & 0x07) << 5;
        idata[i + 2] = ((licz >> 5) & 0x07) << 5;
        idata[i + 3] = 255;
    }
    ctx.putImageData(img1, 0, 0);
};
var calculateBarnsley = function (steps) {
    var arr = new Array(steps);
    arr[0] = new Vector2f(0.0, 0.0);
    for (var i = 0; i < steps - 1; i++) {
        var rand1 = Math.random();
        var rand2 = Math.random();
        if (rand1 <= 0.01) {
            arr[i + 1] = new Vector2f(0.0, 0.16 * arr[i].y);
        } else if (rand1 <= 0.15) {
            if (rand2 <= 0.5) {
                arr[i + 1] = new Vector2f(-0.15 * arr[i].x + 
                  0.28 * arr[i].y, 0.26 * arr[i].x + 0.24 * 
                  arr[i].y + 0.44);
            } else {
                arr[i + 1] = new Vector2f(0.2 * arr[i].x - 
                   0.26 * arr[i].y, 0.23 * arr[i].x + 0.22 * 
                   arr[i].y + 1.6);
            }
        } else {
            arr[i + 1] = new Vector2f(0.85 * arr[i].x + 0.04 * 
                 arr[i].y, -0.04 * arr[i].x + 0.85 * arr[i].y + 1.6);
        }
    }
    return arr;
};
var index = function (row, col, cols) {
    return row * cols + col;
};
var drawBarnsley = function (steps) {
    var img1 = ctx.getImageData(0, 0, width, height);
    var idata = img1.data;
    var arr = calculateBarnsley(steps);
    for (var i = 0; i < arr.length; i++) {
        var x = cutDecimal(arr[i].x * 50) + 3 * 50;
        var y = cutDecimal(arr[i].y * 50) + 3 * 50;
        var j = 4 * index(x, y, width);
        idata[j] = 0;
        idata[j + 1] = 255;
        idata[j + 2] = 0;
        idata[j + 3] = 255;
    }
    ctx.putImageData(img1, 0, 0);
};
var srodek = function (v1, v2) {
    return new Vector2f((v1.x + v2.x) / 2, (v1.y + v2.y) / 2);
};
var randomInRange = function (min, max) {
    var random = -1;
    if (min > max) {
        return new Error('Pierwsza licba musi być mniejsza 
              od drugiej');
    } else {
        random = cutDecimal(Math.floor(Math.random() * 
               (max - min + 1)) + min);
    }
    return random;
};
var drawSierpinskiRandom = function (steps) {
    var A = new Vector2f(0.0, width);
    var B = new Vector2f(width, width);
    var C = new Vector2f(width / 2, width - width * Math.sqrt(3) / 2);
    var D = new Vector2f(width / 4, width - width / 16.0);
    var centrum = null;
    var img1 = ctx.getImageData(0, 0, width, height);
    var idata = img1.data;
    for (var i = 0; i < steps; i++) {
        var r = randomInRange(0, 2);
        switch (r) {
            case 0:
                centrum = srodek(D, A);
                break;
            case 1:
                centrum = srodek(D, B);
                break;
            case 2:
                centrum = srodek(D, C);
                break;
        }
        var j = 4 * index(cutDecimal(centrum.y), cutDecimal(centrum.x), 
              width);
        idata[j] = 0;
        idata[j + 1] = 255;
        idata[j + 2] = 0;
        idata[j + 3] = 255;
        D = centrum;
    }
    ctx.putImageData(img1, 0, 0);
};
// -
function Tuple(x, y, headDir) {
    this.x = x;
    this.y = y;
    this.headDir = headDir;
}
;
function Turtle(x, y, headDir, ww, vars, start, rules, scale, steps, 
           angle) {
    this.x = x;
    this.y = y;
    this.headDir = headDir;
    this.ww = ww;
    this.vars = vars;
    this.start = start;
    this.rules = rules;
    this.scale = scale;
    this.steps = steps;
    this.distance = this.getDistance(steps, scale);
    this.frules = this.process(steps, start, rules, vars);
    this.angle = angle;
    this.memo = new Array();
}
;
Turtle.prototype.tailDown = function (x, y) {
    ctx.beginPath();
    ctx.strokeStyle = "black";
    ctx.lineWidth = 1;
    ctx.moveTo(Math.floor(this.x), Math.floor(this.y));
    ctx.lineTo(Math.floor(this.x + x), Math.floor(this.y + y));
    ctx.stroke();

};
Turtle.prototype.move = function (distance, tailDown) {
    var x = Math.cos(this.headDir) * distance;
    var y = Math.sin(this.headDir) * distance;
    if (tailDown) {
        this.tailDown(x, y);
    }
    this.x += x;
    this.y += y;
};
Turtle.prototype.process = function (steps, start, rules, vars) {
    var result = start;
    var result1 = "";
    for (var i = 0; i < steps; i++) {
        for (var j = 0; j < result.length; j++) {
            var temp = result.substring(j, j + 1);
            for (var k = 0; k < vars.length; k++) {
                if (temp === vars[k]) {
                    result1 = result1.concat(rules[k]);
                }
            }
        }
        result = result1;
        result1 = "";
    }
    return result;
};
Turtle.prototype.getDistance = function (steps, scale) {
    var wt1 = this.ww;
    for (var i = 0; i < steps; i++) {
        wt1 *= scale;
    }
    return wt1;
};
Turtle.prototype.draw = function () {
    var a = "";
    for (var i = 0; i < this.frules.length; i++) {
        a = this.frules.substring(i, i + 1);
        switch (a) {
            case "F":
            case "G":
                this.move(this.distance, true);
                break;
            case "X":
            case "Y":
            case "Z":
                break;
            case "f":
                this.move(this.distance, false);
                break;
            case "+":
                this.headDir += this.angle;
                break;
            case "-":
                this.headDir -= this.angle;
                break;
            case "[":
                var t = new Tuple(this.x, this.y, this.headDir);
                this.memo.push(t);
                break;
            case "]":
                var t = this.memo.pop();
                this.x = t.x;
                this.y = t.y;
                this.headDir = t.headDir;
                break;
        }
    }
};
// gridSize = 2 oznacza siatke, 2 x 2
// gridSize 4 oznacza siatke 4 x 4, etc.
var countCells = function (gridSize) {
    var canvasWidth = width;
    var cellWidth = canvasWidth / gridSize;
    var img1 = ctx.getImageData(0, 0, width, height);
    var idata = img1.data;
    var sum = 0;
    for (var i = 0; i < canvasWidth; i += cellWidth) {
        for (var j = 0; j < canvasWidth; j += cellWidth) {
            br: for (var k = i; k < i + cellWidth; k++) {
                for (var m = j; m < j + cellWidth; m++) {
                    var n = 4 * index(k, m, width);
                    if ((idata[n] < 200) || (idata[n + 1] < 200)
                            || (idata[n + 2] < 200)) {
                        sum++;
                        break br;
                    }
                }
            }
        }
    }
    ctx.fillText(sum, 20, 20);
    return sum;
};
var solve = function (arr1, arr2) {
    var matrix1 = new Matrix(arr1);
    var matrix2 = new Matrix(arr2);
    var matrix3 = matrix1.reverte();
    var matrix4 = matrix3.multiply2(matrix2);
    return [matrix4.getMN(0, 0), matrix4.getMN(1, 0)];
};
var drawAtractorLorenza = function () {
    var x0 = (Math.random() * 48.0 - 24.0) / 2.0;
    var y0 = (Math.random() * 48.0 - 24.0) / 2.0;
    var z0 = Math.random() * 24.0 / 2.0;
    var ro = 10.0;
    var r = 28.0;
    var b = 8.0 / 3.0;
    var h = 0.01;
    ctx.save();
    ctx.strokeStyle = "blue";
    for (var i = 0; i < 8000; i++) {
        var x = x0 * 10 + 410;
        var y = y0 * 10 + 410;
        ctx.moveTo(x, y);
        ctx.arc(x, y, 1, 0, 2 * Math.PI, true);
        var x1 = x0 + h * ro * (y0 - x0);
        var y1 = y0 + h * (x0 * (r - z0) - y0);
        var z1 = z0 + h * (x0 * y0 - b * z0);
        x0 = x1;
        y0 = y1;
        z0 = z1;
    }
    ctx.stroke();
    ctx.restore();
};

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *