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

Вход на сайт

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

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

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

огромное спасибо за подробное объяснение про 3д графику на питоне, в интернете очень мало подобной информации
dobryj den, popytalas otkryt prikreplionnyj fail ctoby posmotret kak rabotaet, no mne ego ne pokazyvaet vydajet osibku. Pochemu?
Очень интересно! ии сайт крутой жалко что умирает(
У Вас число превысит максимальное число int. Можно использовать в Вашем случае uint, но лучше все переписать на double.
Добавление к программе строки glutReshapeFunc(changeSize); приводит к тому, что треугольник перестаёт совсем отрисовываться.

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

Рейтинг@Mail.ru Яндекс.Метрика
Скриншот к примеру
Среда программирования: 
NetBeans IDE 8.2

Пример заливки с "жесткостью".
Использование:
В форме FillToleranceExample нажмите на единственную кнопку для генерации тестовой сцены.
В единственном текстовом поле укажите параметр "жесткости" от 0 до 1, затем нажимайте мышью на панели в разных участках сцены. Для очистки сцены повторно нажмите на кнопку.

Код программы: 

Участок из кода формы jForm FillToleranceExample.java, где:
jPanel1 - панель с абстрактной графикой java.awt.Graphics
jButton1 - кнопка, начинающая отрисовку тестовой сцены
jTextField1 - текстовое поле с параметром заливки
(Автоматически сгенерированный код и код формы опущен)

    //вызываем отрисовку тестовой сцены
    private void jButton1MousePressed(java.awt.event.MouseEvent evt) {
        drawer.Clear(Color.WHITE, false);
        DrawCircles(16, 245, 16, new Dot(400, 280), 30, 280);
        drawer.Update();
    }
 
    //начинаем заливку в точке нажатия на панель
    private void jPanel1MousePressed(java.awt.event.MouseEvent evt) {
        drawer.SetColor(Color.RED);
        drawer.Fill(evt.getX(), evt.getY(), new Float(jTextField1.getText()));
        drawer.Update();
    }
 
    //функция отрисовки тестовой сцены из окружностей
    void DrawCircles(int count, int fromColor, int toColor, Dot atPosition, int fromRadius, int toRadius) {
        int curColor = fromColor;
        int stepColor = (toColor - fromColor) / count;
        int curRadius = fromRadius;
        int stepRadius = (toRadius - fromRadius) / count;
        for(int i = 0; i < count; i++) {
            Random rand = new Random();
            drawer.SetColor(new Color(Rand(curColor, 255), Rand(curColor, 255), Rand(curColor, 255)));
            drawer.Circle(atPosition.x, atPosition.y, curRadius, false);
            curColor += stepColor;
            curRadius += stepRadius;
        }
    }
 
    //функция случайного числа в диапазоне
    public static int Rand(int min, int max) {
        return new Random().nextInt((max - min) + 1) + min;
    }

Примитивный дроувер Drawer.java, рисующий на сгенерированном буфферизированном изображении BufferedImage по абстрактной графике (в данном примере, она захватывается из jPanel из формы выше)
Наиболее значимыми являются методы Fill для заливки и ColorCompatible для проверки, удовлетворяет ли выбранный цвет параметру заливки.

import java.awt.Graphics;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.Stack;
 
public class Drawer {
 
    private final BufferedImage bi;
    private final Graphics g;
    private final int w;
    private final int h;
    private Dot lineBuffer;
    private int c;
 
    public Drawer(Graphics graphics, int width, int height, Color color) {
        g = graphics;
        c = color.getRGB();
        w = width - 1;
        h = height - 1;
        bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    }
 
    public void SetColor(Color color) {
        c = color.getRGB();
    }
 
    public void Point(Dot d) { bi.setRGB(d.x, d.y, c); }
    public void Point(int x, int y) {
        bi.setRGB(x, y, c);
    }
 
    public void Rect(Dot s, Dot e) { Rect(s.x, s.y, e.x, e.y, false); }
    public void Rect(Dot s, Dot e, boolean isFilled) { Rect(s.x, s.y, e.x, e.y, isFilled); }
    public void Rect(int x, int y, int w, int h, boolean isFilled) {
        if (isFilled) {
            for (int i = 0; i <= w; i++) {
                for (int j = 0; j <= h; j++) {
                    Point (x + i, y + j);
                }
            }
        } else {
            for (int i = 0; i <= w; i++) {
                Point (x + i, y);
                Point (x + i, y + h);
            }
            for (int j = 0; j <= h; j++) {
                Point (x, y + j);
                Point (x + w, y + j);
            }
        }
    }
 
    public void SetLine(int x, int y) { lineBuffer = new Dot(x, y); }
    public void SetLine(Dot d) {
        lineBuffer = d;
    }
 
    public void MoveLine(int x, int y) { MoveLine(new Dot(x, y)); }
    public void MoveLine(Dot d) {
        if (lineBuffer != null) {
            Line (lineBuffer, d);
            lineBuffer = d;
        }
    }
 
    public void Line(Dot s, Dot e) { Line(s.x, s.y, e.x, e.y); }
    public void Line(int x1, int y1, int x2, int y2) {
        int x = x1, y = y1;
        int dx = Math.abs(x2 - x1), dy = Math.abs(y2 - y1);
        int sx = (x2 - x1) > 0 ? 1 : ((x2 - x1) == 0 ? 0 : -1);
        int sy = (y2 - y1) > 0 ? 1 : ((y2 - y1) == 0 ? 0 : -1);
        int e = 2 * dy - dx;
        Point(x, y);
        if (dy > dx) {
            int swap = dx;
            dx = dy;
            dy = swap;
            for (int k = 1; k <= (dx + dy); k++) {
                if (e < dx) {
                    y += sy;
                    e += 2 * dy;
                } else {
                    x += sx;
                    e -= 2 * dx;
                }
                Point(x, y);
            }
        } else {
            for (int k = 1; k <= (dx + dy); k++) {
                if (e < dx) {
                    x += sx;
                    e += 2 * dy;
                } else {
                    y = y + sy;
                    e -= 2 * dx;
                }
                Point(x, y);
            }
        }
    }
 
    public void LinePolygon(Dot[] points) { LinePolygon(points, false); }
    public void LinePolygon(Dot[] points, boolean isClosed) {
        for (int i = 0; i < points.length - 1; i++) {
            Line (points[i], points[i + 1]);
        }
        if (isClosed) {
            Line (points[points.length - 1], points[0]);
        }
    }
 
    public void Fill(int x, int y) { Fill(new Dot(x, y), 0); }
    public void Fill(int x, int y, float power) { Fill(new Dot(x, y), power); }
    public void Fill(Dot d) { Fill(d, 0); }
    public void Fill(Dot d, float power) {
        int targetColor = bi.getRGB(d.x, d.y);
        if(targetColor == c) {
            return;
        }
        Stack<Dot> dots = new Stack<>();
        dots.add(d);
        while(!dots.isEmpty()) {
            Dot cur = dots.pop();
            int x = cur.x;
            int y = cur.y;
            Point(cur);
            if (x < w && ColorCompatible(bi.getRGB(x + 1, y), targetColor, c, power)) {
                dots.add(new Dot(x + 1, y));
            }
            if (x > 0 && ColorCompatible(bi.getRGB(x - 1, y), targetColor, c, power)) {
                dots.add(new Dot(x - 1, y));
            }
            if (y < h && ColorCompatible(bi.getRGB(x, y + 1), targetColor, c, power)) {
                dots.add(new Dot(x, y + 1));
            }
            if (y > 0 && ColorCompatible(bi.getRGB(x, y - 1), targetColor, c, power)) {
                dots.add(new Dot(x, y - 1));
            }
        }
    }
 
    boolean ColorCompatible(int pickedColor, int tagetColor, int fillColor, float maxPower) {
        if(pickedColor == fillColor) {
            return false;
        }
        float[] ac = new Color(pickedColor).getRGBComponents(new float[4]);
        float[] bc = new Color(tagetColor).getRGBComponents(new float[4]);
        float maxDiff = 0;
        for(int i = 0; i < 3; i++) {
            maxDiff = Math.max(Math.abs(ac[i] - bc[i]), maxDiff);
        }
        return maxDiff <= maxPower;
    }
 
    public void Circle(Dot d, int r) { Circle(d.x, d.y, r, false); }
    public void Circle(Dot d, int r, boolean isFilled) { Circle(d.x, d.y, r, isFilled); }
    public void Circle(int x, int y, int r, boolean isFilled) {
        int sx = 0;
        int sy = r;
        int d = 3 - 2 * r;
        while(sx <= sy) {
            Point (x + sx, y - sy);
            Point (x + sx, y + sy);
            Point (x - sx, y - sy);
            Point (x - sx, y + sy);
            Point (x + sy, y + sx);
            Point (x - sy, y + sx);
            Point (x + sy, y - sx);
            Point (x - sy, y - sx);
            if (d < 0) {
                d += 4 * sx + 6;
            } else {
                d += 4 * (sx - sy) + 10;
                sy--;
            }
            sx += 1;   
        }
        if (isFilled) {
            Fill(x, y);
        }
    }
 
    public void Clear() { Clear(Color.WHITE, true); }
    public void Clear(Color bg) { Clear(bg, true); }
    public void Clear(Color bg, boolean isUpdate) {
        SetColor(bg);
        Rect(0, 0, w, h, true);
        if (isUpdate) {
            Update();
        }
    }
 
    public void Update() {
        g.drawImage(bi, 0, 0, null);
    }
}

Утилитный класс точки Dot.java

public class Dot {
    int x, y;
 
    public Dot(int _x, int _y) {
        x = _x;
        y = _y;
    }
}

Прикрепленный файлРазмер
Собранный проект для NetBeans 8.251.11 кб