Уроки, алгоритмы, программы, примеры

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

У меня проблема вот с этим: gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);. Вылезает ошибка: CS1061 "object" не содержит определения "GL_COLOR_BUFFER_BIT", и не удалось найти доступный метод расширения "GL_COLOR_BUFFER_BIT",...
Большое спасибо. Единственный код который прошел без каких либо ошибок. Ура!!!
Скажите пожалуйста, подскажите алгоритм по которому по заданным точкам можно определить тип многогранника, скажем это куб или прямоугольный параллелепипед. Нашел теорию по этим фигурам: https://www.mat... https://www.mat... Акцентировать внимание...
Всем у кого не работает. файл wizard.script Ещё одно упоминание Glut32 в строке "if (!VerifyLibFile(dir_nomacro_lib, _T("glut32"), _T("GLUT's"))) return false;" меняем на "if (!VerifyLibFile(dir_nomacro_lib, _T("freeglut"), _T("GLUT's"))) return...
Не получается, емаё

Счетчики и рейтинг

Рейтинг@Mail.ru Яндекс.Метрика
Демо JavaScript: 

<canvas id = "canvas" width = "500" height = "500"></canvas><br>
 
<div>
    <select id = "select">
        <option value = "0"> Heart 1 </option>
        <option value = "1"> Heart 2 </option>
        <option value = "2"> Star    </option>
        <option value = "3"> Square  </option>
        <option value = "4"> Arrow   </option>
    </select>
    <button onclick = "init()"> Select </button>
</div>
 
<script>
    /***** Canvas *****/
    let canvas = document.querySelector("canvas");
    let ctx = canvas.getContext("2d");
    let canvasWidth = canvas.width;
    let canvasHeight = canvas.height;
    let canvasData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
 
    // Обновляем canvas
    function updateCanvas() {
        ctx.putImageData(canvasData, 0, 0);
    }
 
    /***** Графическая библиотека *****/
    // Рисуем пиксель
    function drawPixel(x, y, color = {r: 255, g: 0, b: 0, a: 255}) {
        const index = (x + y * canvasWidth) * 4;
        canvasData.data[index + 0] = color.r;
        canvasData.data[index + 1] = color.g;
        canvasData.data[index + 2] = color.b;
        canvasData.data[index + 3] = color.a;
        return color;
    }
 
    // Рисуем отрезок по алгоритму Брезенхема
    function drawLine(x1, y1, x2, y2, color = {r: 255, g: 0, b: 0, a: 255}) {
        const deltaX = Math.abs(x2 - x1);
        const deltaY = Math.abs(y2 - y1);
 
        const signX = x1 < x2 ? 1 : -1;
        const signY = y1 < y2 ? 1 : -1;
 
        let error = deltaX - deltaY;
        drawPixel(x2, y2, color);
 
        while (x1 !== x2 || y1 !== y2) {
            drawPixel(x1, y1, color);
            let error2 = error * 2;
 
            if (error2 > -deltaY) {
                error -= deltaY;
                x1 += signX;
            }
            if (error2 < deltaX) {
                error += deltaX;
                y1 += signY;
            }
        }
    }
 
    // Рисуем треугольник
    function drawTriangle(x1, y1, x2, y2, x3, y3, color = {r: 255, g: 0, b: 0, a: 255}) {
        drawLine(x1, y1, x2, y2, color);
        drawLine(x2, y2, x3, y3, color);
        drawLine(x3, y3, x1, y1, color);
    }
 
    // Рисуем многоугольник
    function drawPolygon(color =  {r: 0, g: 0, b: 0, a: 255}) {
        for (let i = 0; i < polygon.length; i++) {
            const newI = (i + 1 === polygon.length ? 0 : i + 1);
            drawLine(polygon[i].x, polygon[i].y, polygon[newI].x, polygon[newI].y, color);
        }
    }
 
    // Получаем цвет пикселя
    function getColor(x, y) {
        const index = (x + y * canvasWidth) * 4;
        const r = canvasData.data[index + 0];
        const g = canvasData.data[index + 1];
        const b = canvasData.data[index + 2];
        const a = canvasData.data[index + 3];
        return {r: r, g: g, b: b, a: a};
    }
 
    // Заливка 4-х связным алгоритмом
    function fill(x, y, color = {r: 255, g: 0, b: 0, a: 255}) {
        let startColor = getColor(x, y);
 
        if (startColor.r === color.r &&
            startColor.g === color.g &&
            startColor.b === color.b &&
            startColor.a === color.a) {
            return;
        }
 
        let q = [{x: x, y: y}];
        for (let i = 0; i !== q.length; i++) {
            let x = q[i].x, y = q[i].y;
 
            let newColor = getColor(x, y);
            if (x >= 0 && y >= 0 && x < canvasWidth && y < canvasHeight && newColor.r === startColor.r
                && newColor.g === startColor.g && newColor.b === startColor.b && newColor.a === startColor.a) {
                newColor = drawPixel(x, y, color);
 
                let length = q.length;
                q[length + 0] = {x: x + 1, y: y};
                q[length + 1] = {x: x - 1, y: y};
                q[length + 2] = {x: x, y: y + 1};
                q[length + 3] = {x: x, y: y - 1};
            }
        }
    }
 
    // Заливка прямоугольника
    function fillRectangle(x1, y1, width, height, color = {r: 255, g: 0, b: 0, a: 255}) {
        for (let i = y1; i <= y1 + height; i++) {
            drawLine(x1, i, x1 + width, i, color);
        }
    }
 
    /***** Создаем многоулогьник *****/
    // Описываем точку
    class Point {
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }
    }
 
    // Многоугольник
    let polygon = [];
 
    // Заполняем массив polygon
    function createPolygon() {
        polygon = [];
        fillRectangle(0, 0, canvasWidth, canvasHeight, {r: 142, g: 67, b: 231, a: 255});
 
        const selectValue = parseInt(document.getElementById("select").value);
 
        let xC = Math.floor(canvasWidth / 2), yC =  Math.floor(canvas.height / 2);
        switch (selectValue) {
            case 0:
                // Polygon 1
                polygon.push(new Point(xC +  0, yC - 40 -  0));
 
                // left
                polygon.push(new Point(xC - 20, yC - 40 - 20));
                polygon.push(new Point(xC - 40, yC - 40 - 30));
                polygon.push(new Point(xC - 60, yC - 40 - 30));
                polygon.push(new Point(xC - 80, yC - 40 - 20));
                polygon.push(new Point(xC - 90, yC - 40 -  0));
                polygon.push(new Point(xC - 90, yC - 40 + 20));
                polygon.push(new Point(xC - 80, yC - 40 + 50));
 
                polygon.push(new Point(xC -  0, yC - 40 + 140));
 
                // right
                polygon.push(new Point(xC + 80, yC - 40 + 50));
                polygon.push(new Point(xC + 90, yC - 40 + 20));
                polygon.push(new Point(xC + 90, yC - 40 -  0));
                polygon.push(new Point(xC + 80, yC - 40 - 20));
                polygon.push(new Point(xC + 60, yC - 40 - 30));
                polygon.push(new Point(xC + 40, yC - 40 - 30));
                polygon.push(new Point(xC + 20, yC - 40 - 20));
                break;
            case 1:
                // Polygon 2
                polygon.push(new Point(xC -  0, yC - 40 + 140));
 
                // right
                polygon.push(new Point(xC + 80, yC - 40 + 50));
                polygon.push(new Point(xC + 90, yC - 40 + 20));
                polygon.push(new Point(xC + 90, yC - 40 -  0));
                polygon.push(new Point(xC + 80, yC - 40 - 20));
                polygon.push(new Point(xC + 60, yC - 40 - 30));
                polygon.push(new Point(xC + 40, yC - 40 - 30));
                polygon.push(new Point(xC + 20, yC - 40 - 20));
 
                polygon.push(new Point(xC +  0, yC - 40 -  0));
 
                // left
                polygon.push(new Point(xC - 20, yC - 40 - 20));
                polygon.push(new Point(xC - 40, yC - 40 - 30));
                polygon.push(new Point(xC - 60, yC - 40 - 30));
                polygon.push(new Point(xC - 80, yC - 40 - 20));
                polygon.push(new Point(xC - 90, yC - 40 -  0));
                polygon.push(new Point(xC - 90, yC - 40 + 20));
                polygon.push(new Point(xC - 80, yC - 40 + 50));
                break;
            case 2:
                // Polygon 3
                let x, y, radius = 200;
                for (let angle = 18; angle <= 360; angle += 72) {
                    x = Math.floor(xC + radius * Math.cos(angle * Math.PI / 180));
                    y = Math.floor(yC - radius * Math.sin(angle * Math.PI / 180));
                    polygon.push(new Point(x, y));
                    x = Math.floor(xC + radius * 2 / 5 * Math.cos((angle + 36) * Math.PI / 180));
                    y = Math.floor(yC - radius * 2 / 5 * Math.sin((angle + 36) * Math.PI / 180));
                    polygon.push(new Point(x, y));
                }
                break;
            case 3:
                // Polygon 4
                polygon.push(new Point(xC + 80, yC - 80));
                polygon.push(new Point(xC - 80, yC - 80));
                polygon.push(new Point(xC - 80, yC + 80));
                polygon.push(new Point(xC + 80, yC + 80));
                break;
            case 4:
                // Polygon 5
                polygon.push(new Point(xC +  0, yC - 60));
                polygon.push(new Point(xC - 60, yC + 60));
                polygon.push(new Point(xC +  0, yC +  0));
                polygon.push(new Point(xC + 60, yC + 60));
                break;
            default:
                console.log("default", selectValue);
                break;
        }
    }
 
    /***** Триангуляция *****/
    // Считает площадь треугольника
    function calculateSquare(A, B, C) {
        return 1 / 2 * Math.abs((B.x - A.x) * (C.y - A.y) - (C.x - A.x) * (B.y - A.y));
    }
 
    // Принадлежит ли точка треугольнику?
    function inTriangle(A, B, C, D) {
        return calculateSquare(A, B, C) === calculateSquare(A, B, D) + calculateSquare(A, C, D) + calculateSquare(B, D, C);
    }
 
    // Левая тройка векторов?
    function isLeft(A, B, C) {
        const AB = {
                x: B.x - A.x,
                y: B.y - A.y
            },
            AC = {
                x: C.x - A.x,
                y: C.y - A.y
            };
 
        return AB.x * AC.y - AC.x * AB.y < 0;
    }
 
    // Есть ли другие точки внутри рассматриваемого треугольника?
    function hasPointOfPolygon(points) {
        const A = points[0],
              B = points[1],
              C = points[2];
 
        for (let p = 3; p < points.length; p++) {
            if (inTriangle(A, B, C, points[p])) return true;
        }
 
        return false;
    }
 
    // Триангуляция
    function triangulate(point = new Point(260, 250), color = {r: 255, g: 255, b: 255, a: 255}) {
        while (polygon.length >= 3) {
            if (isLeft(polygon[0], polygon[1], polygon[2]) && !hasPointOfPolygon(polygon)) {
 
                const x1 = polygon[0].x,
                    y1 = polygon[0].y;
                const x2 = polygon[1].x,
                    y2 = polygon[1].y;
                const x3 = polygon[2].x,
                    y3 = polygon[2].y;
                drawTriangle(x1, y1, x2, y2, x3, y3, color);
 
                if (inTriangle(polygon[0], polygon[1], polygon[2], point)) {
                    let cx = Math.floor((x1 + x2 + x3) / 3);
                    let cy = Math.floor((y1 + y2 + y3) / 3);
                    fill(cx, cy);
                }
 
                polygon.splice(1, 1);
            } else {
                const tmp = polygon[0];
                polygon.shift();
                polygon.push(tmp);
            }
        }
    }
 
    /***** Старт *****/
    // Функция с которой программа начинает работу
    function init() {
        createPolygon();
        drawPolygon();
        triangulate();
        updateCanvas();
    }
</script>