Форум программистов, компьютерный форум, киберфорум
Java: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
0 / 0 / 1
Регистрация: 24.02.2019
Сообщений: 34

Медленный рендеринг изображения при зуммировании

24.02.2020, 15:05. Показов 1078. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Написал программу для построения фракталов типа треугольник Серпинского. Зум происходит относительно мыши. Почему то чем больше зум, тем больше фризов, но почему так? Ведь количество точек, которые нужно проверить не меняется. Вот код:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.*;
 
public class prog {
    public static void main(String[] args) {
        Frame frame = new Frame();
    }
}
class Frame extends JFrame{
    Frame(){
        Dimension sSize = Toolkit.getDefaultToolkit().getScreenSize();
        Panel panel = new Panel();
        Container container = getContentPane();
        container.add(panel);
        setBounds(0, 0, sSize.width, sSize.height);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setTitle("Fractal");
    }
}
class Panel extends JPanel{
    Dimension sSize = Toolkit.getDefaultToolkit().getScreenSize();
    int width = sSize.width;
    int height = sSize.height;
    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    ArrayList<Point> point = new ArrayList<>();
    int ch = 7;
    double M = 1;
    double centX, centY, Dx, Dy, oldX, oldY, newX, newY, v;
    
    class MyMouse implements MouseWheelListener{
        public void mouseWheelMoved(MouseWheelEvent e) {
            double t = e.getWheelRotation();
            M -= (t/10)*M;
            render();
        }
    }
    
    class MyMouse1 implements MouseMotionListener{
        public void mouseDragged(MouseEvent e) {
            centX=e.getX();
            centY=e.getY();
            render();
        }
        public void mouseMoved(MouseEvent e) {
            v++;
            oldX = e.getX();
            oldY = e.getY();
            if (v>1){
                Dx += (newX-oldX)*(1/M);
                Dy += (newY-oldY)*(1/M);
            }
            centX=e.getX();
            centY=e.getY();
            render();
            newX = e.getX();
            newY = e.getY();
        }
    }
    
    class MyMouse2 implements MouseListener{
        public void mouseClicked(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}
        public void mousePressed(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {
            v=0;
        }
    }
    
    Panel(){
        point.add(new Point());
        point.get(0).x = 100;
        point.get(0).y = 100;
        
        point.add(new Point());
        point.get(1).x = 100;
        point.get(1).y = 500;
        
        point.add(new Point());
        point.get(2).x = 500;
        point.get(2).y = 500;
        
        point.add(new Point());
        point.get(3).x = 500;
        point.get(3).y = 100;
        
        point.add(new Point());
        point.get(4).x = 300;
        point.get(4).y = 0;
        
        point.add(new Point());
        point.get(5).x = 300;
        point.get(5).y = 600;
        
        point.add(new Point());
        point.get(6).x = 0;
        point.get(6).y = 300;
        
        point.add(new Point());
        point.get(7).x = 600;
        point.get(7).y = 300;
        
        setBackground(Color.BLACK);
        addMouseWheelListener(new MyMouse());
        addMouseMotionListener(new MyMouse1());
        addMouseListener(new MyMouse2());
        
        for (int i=0; i<100000; i++){update();}
        
        Timer tmDraw = new Timer(10, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //update();
                repaint();
            }
        });
        tmDraw.start();
    }
    public void update(){
        int random = (int)(Math.random()*8+1);
        if (random==1){
            point.add(new Point());
            point.get(point.size()-1).x = (point.get(point.size()-2).x+point.get(0).x)/ch;
            point.get(point.size()-1).y = (point.get(point.size()-2).y+point.get(0).y)/ch;
        }
        if (random==2){
            point.add(new Point());
            point.get(point.size()-1).x = (point.get(point.size()-2).x+point.get(1).x)/ch;
            point.get(point.size()-1).y = (point.get(point.size()-2).y+point.get(1).y)/ch;
        }
        if (random==3){
            point.add(new Point());
            point.get(point.size()-1).x = (point.get(point.size()-2).x+point.get(2).x)/ch;
            point.get(point.size()-1).y = (point.get(point.size()-2).y+point.get(2).y)/ch;
        }
        if (random==4){
            point.add(new Point());
            point.get(point.size()-1).x = (point.get(point.size()-2).x+point.get(3).x)/ch;
            point.get(point.size()-1).y = (point.get(point.size()-2).y+point.get(3).y)/ch;
        }
        if (random==5){
            point.add(new Point());
            point.get(point.size()-1).x = (point.get(point.size()-2).x+point.get(4).x)/ch;
            point.get(point.size()-1).y = (point.get(point.size()-2).y+point.get(4).y)/ch;
        }
        if (random==6){
            point.add(new Point());
            point.get(point.size()-1).x = (point.get(point.size()-2).x+point.get(5).x)/ch;
            point.get(point.size()-1).y = (point.get(point.size()-2).y+point.get(5).y)/ch;
        }
        if (random==7){
            point.add(new Point());
            point.get(point.size()-1).x = (point.get(point.size()-2).x+point.get(6).x)/ch;
            point.get(point.size()-1).y = (point.get(point.size()-2).y+point.get(6).y)/ch;
        }
        if (random==8){
            point.add(new Point());
            point.get(point.size()-1).x = (point.get(point.size()-2).x+point.get(7).x)/ch;
            point.get(point.size()-1).y = (point.get(point.size()-2).y+point.get(7).y)/ch;
        }
    }
    public void render(){
        img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        for (int i=0; i<point.size(); i++){
            try {
                img.setRGB((int)(((point.get(i).x-0.5)+Dx)*M+centX), (int)(((point.get(i).y-0.5)+Dy)*M+centY), Color.WHITE.getRGB());
            } catch (Exception e) {}
        }
    }
    public void paintComponent(Graphics gr){
        
        super.paintComponent(gr);
        
        Graphics2D g2 = (Graphics2D) gr; 
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); 
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2.setStroke(new BasicStroke(1.0f)); 
        
        gr.drawImage(img, 0, 0, null);
        
    }
}
class Point{
    double x, y;
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.02.2020, 15:05
Ответы с готовыми решениями:

Глюк при зуммировании графиков.
Где может быть ошибка??? Как лечить? Раньше все отлично работало, а сейчас не хочет. В то же время на соседнем компе - работает. ...

Выход серии за границы Chart-а при зуммировании
Приветствую! Подскажите, как исправить? При зуммировании, серия выходит за границы

SharpDX: неверная позиция курсора мыши при зуммировании
При зуммировании в позицию курсора мыши или изменении размера окна изменяю RenderTarget через свойство Transform. В результате...

3
Модератор
Эксперт Java
 Аватар для alecss131
2856 / 1363 / 406
Регистрация: 11.08.2017
Сообщений: 4,351
Записей в блоге: 2
24.02.2020, 16:17
Для начала стоит код привести к нормальному виду. Вместо кучи if использовать switch-case, вместо двух внутренних классов сделать implement интерфейсов к внешнему классу а там где использовались вложенные классы написать this, для класса point создать конструктор как минимум, как максимум еще гетеры-сетеры, не понимаю нафига наследовать от jpanel и jframe. Если у панели меняется только фон то не стоит переопределять методы а просто менять фон.
1
Модератор
Эксперт Java
 Аватар для alecss131
2856 / 1363 / 406
Регистрация: 11.08.2017
Сообщений: 4,351
Записей в блоге: 2
24.02.2020, 22:31
Лучший ответ Сообщение было отмечено Logoqaz как решение

Решение

Вот переписал ваш код, больше не тормозит, работает так же как и ваш с тормозами (в смысле при некотором увеличении прерывается прогрессия).
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
 
public class Prog {
 
    public static void main(String[] args) {
        new Prog();
    }
 
    Prog() {
        JFrame wnd = new JFrame();
        Dimension sSize = Toolkit.getDefaultToolkit().getScreenSize();
        int width = sSize.width;
        int height = sSize.height;
        wnd.setTitle("Fractal");
        wnd.setBounds(0, 0, width, height);
        wnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        wnd.setResizable(false);
        Panel panel = new Panel(width, height);
        wnd.add(panel);
        wnd.setVisible(true);
    }
}
 
class Panel extends JPanel implements MouseWheelListener, MouseMotionListener, MouseListener {
    private static final long serialVersionUID = 1L;
    private int width;
    private int height;
    private BufferedImage img;
    private ArrayList<Point> point = new ArrayList<>();
    private int ch = 7;
    private double M = 1;
    private double centX, centY, Dx, Dy, oldX, oldY, newX, newY, v;
 
    @Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        double t = e.getWheelRotation();
        M -= (t / 10) * M;
        render();
    }
 
    @Override
    public void mouseDragged(MouseEvent e) {
        centX = e.getX();
        centY = e.getY();
        render();
    }
 
    @Override
    public void mouseMoved(MouseEvent e) {
        v++;
        oldX = e.getX();
        oldY = e.getY();
        if (v > 1) {
            Dx += (newX - oldX) * (1 / M);
            Dy += (newY - oldY) * (1 / M);
        }
        centX = e.getX();
        centY = e.getY();
        render();
        newX = e.getX();
        newY = e.getY();
    }
 
    @Override
    public void mouseClicked(MouseEvent e) {
    }
 
    @Override
    public void mouseEntered(MouseEvent e) {
    }
 
    @Override
    public void mouseExited(MouseEvent e) {
    }
 
    @Override
    public void mousePressed(MouseEvent e) {
    }
 
    @Override
    public void mouseReleased(MouseEvent e) {
        v = 0;
    }
 
    Panel(int width, int height) {
        this.width = width;
        this.height = height;
        addMouseListener(this);
        addMouseMotionListener(this);
        addMouseWheelListener(this);
        point.add(new Point(100.0, 100.0));
        point.add(new Point(100.0, 500.0));
        point.add(new Point(500.0, 500.0));
        point.add(new Point(500.0, 100.0));
        point.add(new Point(300.0, 0.0));
        point.add(new Point(300.0, 600.0));
        point.add(new Point(0.0, 300.0));
        point.add(new Point(600.0, 300.0));
        for (int i = 0; i < 100000; i++) {
            update();
        }
        img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        render();
    }
 
    public void update() {
        int num = new Random().nextInt(8);
        double x = (point.get(point.size() - 1).getX() + point.get(num).getX()) / ch;
        double y = (point.get(point.size() - 1).getY() + point.get(num).getY()) / ch;
        point.add(new Point(x, y));
    }
 
    public void render() {
        Graphics2D g2 = (Graphics2D) img.getGraphics();
        g2.setColor(Color.black);
        g2.fillRect(0, 0, width, height);
        g2.setColor(Color.white);
        int x, y;
        for (int i = 0; i < point.size(); i++) {
            x = (int) (((point.get(i).getX() - 0.5) + Dx) * M + centX);
            y = (int) (((point.get(i).getY() - 0.5) + Dy) * M + centY);
            g2.drawLine(x, y, x, y);
        }
        repaint();
    }
 
    @Override
    public void paintComponent(Graphics gr) {
        Graphics2D g2 = (Graphics2D) gr;
        g2.drawImage(img, 0, 0, null);
    }
}
 
class Point {
    private double x;
    private double y;
 
    Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
 
    public double getX() {
        return x;
    }
 
    public double getY() {
        return y;
    }
}
Это вам не игра чтобы рендерить постоянно, достаточно перерисовывать изображение только при событиях. Судя по редактуре кода, тормоза пропали при замене отрисовки картинки с img.setRGB() на g2.drawLine()
0
0 / 0 / 1
Регистрация: 24.02.2019
Сообщений: 34
24.02.2020, 22:36  [ТС]
alecss131, храни тебя Господь
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.02.2020, 22:36
Помогаю со студенческими работами здесь

3д моделирование и рендеринг одно и тоже?Что такое рендеринг?
3д моделирование и рендеринг одно и тоже?Что такое рендеринг?

Медленный ввод в текстовые поля / медленный отклик в google chrome?
Привет! Может кто знает, Сегодня заметил, что ввод текста в браузере chrome стал очень медленным и отклик тоже. Например, при наборе...

Acer5742g при нагрузках(рендеринг видео, игры) перестаёт заряжаться
Добрый день, столкнулся с такой проблемой: при сильных нагрузках на ноутбук Acer5742g: рендеринг, игры, начинает моргать светодиод на...

DirectShow: Рендеринг кадра при смене put_CurrentPosition в режиме паузы
Господа, приветствую! Просьба натолкнуть на верный путь. Граф построен, все замечательно. Решил прикрутить трекбар для изменения...

Визуальное перелистывание изображения при переходе от одного изображения к другому
Здравствуйте,нужна помощь,как можно в C#,windows form создать приложение которое делает визуальное перелистывание изображения при переходе...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru