Java实现Vicsek分形绘制异常问题咨询
Vicsek分形绘制问题修复方案
问题根因
- 迭代公式权重错误:Vicsek分形混沌游戏的正确迭代规则是新坐标 = (2*顶点坐标 + 当前点坐标)/3,你原先写的
(firstDotx + 顶点x)/3权重完全颠倒,顶点仅占1/3权重,导致生成的图案不断缩小、偏移到角落;而你尝试的firstDotx*3/2计算逻辑会让坐标快速超出绘制区域,自然完全无显示。 - 成员变量状态残留:你将当前点坐标
firstDotx、firstDoty设为类成员变量,第一次绘制完成后坐标已经缩到异常范围,后续重绘会直接在错误位置迭代,无法生成图案。 - 点绘制兼容问题:使用
drawRect(x,y,0,0)在部分Swing渲染配置下不会显示1像素点,容易出现无绘制内容的问题。 - case4注释笔误:case4对应右上角顶点,注释写为bottom left属于笔误,不影响代码运行。
修复后代码
SquarePanel.java
package fractals; import java.awt.Color; import javax.swing.JPanel; import java.awt.Graphics; import java.awt.Graphics2D; public class SquarePanel extends JPanel { static final int[] xPoints = new int[]{270, 270, 810, 810};//正方形x坐标 static final int[] yPoints = new int[]{92, 632, 632, 92};//正方形y坐标 public final static int iterations = 100000; @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // 每次绘制都重新初始化随机初始点,避免状态残留 int firstDotx = 270 + (int) (Math.random() * ((810 - 270) + 1)); int firstDoty = 92 + (int) (Math.random() * ((632 - 92) + 1)); Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.black); g2.drawPolygon(xPoints, yPoints, 4); g2.fillRect(firstDotx, firstDoty, 1, 1); for (int i = 0; i <= iterations; i++) { int midpointX; int midpointY; int Vertex = (int) (Math.random() * 5 + 1); switch (Vertex) { case 1: //左上角 g2.setColor(Color.blue); midpointX = (firstDotx + 2*270) / 3; midpointY = (firstDoty + 2*92) / 3; g2.fillRect(midpointX, midpointY, 1, 1); firstDotx = midpointX; firstDoty = midpointY; break; case 2://左下角 g2.setColor(Color.blue); midpointX = (firstDotx + 2*270) / 3; midpointY = (firstDoty + 2*632) / 3; g2.fillRect(midpointX, midpointY, 1, 1); firstDotx = midpointX; firstDoty = midpointY; break; case 3://右下角 g2.setColor(Color.blue); midpointX = (firstDotx + 2*810) / 3; midpointY = (firstDoty + 2*632) / 3; g2.fillRect(midpointX, midpointY, 1, 1); firstDotx = midpointX; firstDoty = midpointY; break; case 4://右上角 g2.setColor(Color.blue); midpointX = (firstDotx + 2*810) / 3; midpointY = (firstDoty + 2*92) / 3; g2.fillRect(midpointX, midpointY, 1, 1); firstDotx = midpointX; firstDoty = midpointY; break; case 5://中心 g2.setColor(Color.red); midpointX = (firstDotx + 2*540) / 3; midpointY = (firstDoty + 2*384) / 3; g2.fillRect(midpointX, midpointY, 1, 1); firstDotx = midpointX; firstDoty = midpointY; break; default: break; } } } }
SqaureFrame.java(和原代码一致,无修改)
package fractals; import javax.swing.JButton; import javax.swing.JFrame; import static javax.swing.JFrame.EXIT_ON_CLOSE; public class SqaureFrame { public static void main(String[] args) { JFrame Sframe = new JFrame("Vicsek Fractal"); Sframe.setSize(1080, 768); Sframe.setLocation(300, 200); Sframe.setDefaultCloseOperation(EXIT_ON_CLOSE); SquarePanel Vicsek = new SquarePanel(); JButton Square = new JButton("Click for the Vicsek Fractal"); Sframe.add(Vicsek); Sframe.setVisible(true); } }
修复后运行即可在指定正方形区域生成完整的Vicsek分形,四个角落区域为蓝色,中心区域为红色。
内容的提问来源于stack exchange,提问作者Joshycookie
相关产品推荐
相关产品推荐

