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

Вход на сайт

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

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

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

torrvic, возможно, Вам нужно добавить -lGLU
Извините за тупой вопрос. У меня при сборке Вашего примера выходит ошибка: "undefined reference to gluLookAt". Не могу найти в какой библиотеке находится эта функция. У меня задано: -lGL -lglut ... Искал в /usr/lib таким образом: nm lib*so* | grep...
Здравствуйте. Спасибо за проект. У меня вопрос, по какой причине определение принадлежности точки многоугольнику работает некорректно, если координаты из больших чисел состоят, например: int[] vertex = new int[] {...
Сейчас проверила нашла причину не запускания // Создание контекста воспроизведения OpenGL и привязка его к панели на форме OpenGLControl1:=TOpenGLControl.Create(Self); with OpenGLControl1 do begin Name:='OpenGLControl1'; //вот тут...
Ну..кажется что то пошло не так http://pp.usera...

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

Рейтинг@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 кб