Java迭代分形——3D图形

        迭代分形是一种数学上的概念,是指通过一种简单的规则,不断重复运算,最终得到复杂的图形。我们通过画板来实现图像的生成,迭代图像即通过一定的坐标推算公式,从初始坐标点不断获取新的坐标值并打点,修改点迹颜色以形成一个有深浅变化的图像。用代码实现自然界的美,生成一系列二维,三维的图像,它们不是杂乱无章的,而是具有一定规则的富有美感的图像。

        首先创建一个窗体类,这样可以在窗体类中重写容器的paint方法。添加和创建一些基本组件:画板标题、画板大小、关闭方式等。

public class DrawPad extends JFrame{
		public DrawPad(){
			setTitle ("迭代分形");
			setSize (800,800);
			setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
			setVisible (true);
			setLocationRelativeTo (null);
		}	

        要想在窗体中呈现一些图案还需要添加一些数据,利用数学函数的方式,利用循环不断的更新点的坐标,使成千上万的点组成我们需要创建的图案。

	    public void paint(Graphics g){			
			super.paint (g);
			drawIFS_01 (g);

        public void drawIFS_01(Graphics g){
			double a = -1.8, b = -2.0, c = -0.5, d = -0.9;
            double xn = 0, yn = 0;
			for(int i = 0; i < 100000; i++){
                double tempx = Math.sin (a * yn) + c * Math.cos (a * xn);
			    double tempy = Math.sin (b * xn) + d * Math.cos (b * yn);
                // 迭代给下一次 xn yn
				xn = tempx;
				yn = tempy;
				int px = (int) (tempx * 100) + 400;
				int py= (int) (tempy * 100) + 400;
				g.setColor (Color.blue);
				g.drawLine (px, py, px, py);
			}
		}
        public static void main(String[] args){
			new DrawPad ();			
		}

        以上是迭代图像的实现方法,在写这段代码的过程中我们要注意几个要点。首先,坐标通过公式计算后数值很小,需要放大并移到屏幕中央,打点后再进行迭代,再打点,直到循环结束,其中每一次迭代都使颜色加深。此处a,b,c,d的值是我们自己定义的。颜色可以根据自己的喜好更改即可。修改这里的函数和参数图形会相应地发生改变。如下图是这段代码运行后画出的图案。

g.setColor (Color.blue); //修改颜色的迭代函数

        以上程序画出来的是一个2D的平面图形。下面利用内存缓冲,记录每次绘制的点,每个值都是一张图片,随着点连续不断的增加,就实现了动画的效果。

窗体类:

package DrawDongHua;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;


//用一个内存队列,来保存要画的对象
//一个线程,来画
public class Game extends JFrame {
    //队列对象
    private ArrayList<Shape>  al=new ArrayList();
    public void initUI(){
        this.setSize(600,800);
        this.setDefaultCloseOperation(3);
        FlowLayout fl=new FlowLayout();
        this.setLayout(fl);
        this.setVisible(true);

        JButton buSend=new JButton("绘制");
        this.add(buSend);

        Graphics g=this.getGraphics();

        BuAction ba=new BuAction(g);
        buSend.addActionListener(ba);
    }

    public static void main(String args[]) {
        Game wu=new Game();
        wu.initUI();
    }
}

监听器类:

package DrawDongHua;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

public class BuAction implements ActionListener {
    private Graphics g=null;
    public  BuAction(Graphics g){
        this.g=g;
    }
    public void actionPerformed(ActionEvent e) {
        double x = 0f;
        double y = 0f;
        double a=-1.8;
//        double b = -2.0;
        double c = -0.5, d = -0.9;
        for (double b = -2; b < 2; b += 0.001) { //b的值每次增加0.001
//            a=b;
            try {
                Thread.sleep(10);
            }catch (Exception ef){}

            //内存缓冲
            BufferedImage bi=new BufferedImage(800,800,BufferedImage.TYPE_INT_RGB);
            Graphics g2=bi.getGraphics();
            g2.setColor(Color.GREEN);

            for (int i = 0; i < 20000; i++) {
                //计算下一次的x,y
                double temx = Math.sin(a * y) + c * Math.cos(a * x);
                double temy = Math.sin(b * x) + d * Math.cos(b * y);

                //对x1,y1转型,放大,移动到屏幕坐标系:
                int x1 = (int) (temx * 130 + 300);
                int y1 = (int) (temy * 130 + 400);
                g2.fillOval(x1, y1, 2, 2);
                //
                x = temx;
                y = temy;
            }
            //生成一张图片之后,则画到界面上:
            g.drawImage(bi,0,100,null);

        }
    }
}

 如下利用迭代函数以及数学中图形的基本思想,构建图形的偏移连接,完成一个3D的立体图形。

        与上述步骤一样,先创建一个窗体类,继承构建图案的paint类。

package draw;
import javax.swing.*;
import java.awt.*;
import java.util.Random;

@SuppressWarnings("serial")
public class DrawPad extends JFrame{
		public DrawPad(){
			setTitle ("迭代分形");
			setSize (800,800);
			setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
			setVisible (true);
			setLocationRelativeTo (null);
		}	

        接下来,根据数学思维,定义立方体所需的值,画出一个正方形,用 g.drawRect() 函数,填入相应值,画出其相对面,用 g.drawLine() 函数连接两个面之间八个顶点构成正方体。

            int x = 100, y = 250, w = 300, h = 300, dx = w / 3, dy = h / 3;//正方形初始值
//x图形页面左边距 y页面上边距 w正方形的宽 h正方形的高 dx在x轴偏移距离 dy在y轴偏移的距离			
            g.drawRect (x + dx, y - dy, w, h);//构建相对面
            //绘制两正方形间八个顶点的连接线
			g.drawLine (x, y, x + dx, y - dy);
			g.drawLine (x + w, y, x + w + dx, y - dy);
			g.drawLine (x, y + h, x + dx, y + h - dy);
			g.drawLine (x + w, y + h, x + w + dx, y + h - dy);
            
            g.setColor (Color.red);//定义颜色,初始正方形为红色线
			g.drawRect (x, y, w, h);

        同样画出一个3D球体,先画出一个圆,利用循环和颜色的改变,使多个圆形不断叠加变成一个球体。

			for(int i = 0; i < 255; i++){
				g.setColor (new Color (i, i, 0));//设置颜色
				g.fillOval (160 + i/4 , 200 + i/4, 255 -i, 255-i );
                //(左上角x坐标,左上角y坐标,圆宽、圆高)
			}

        不断调整球体在坐标中的位置,使球体放在立方体的内部。运行结果后的效果图如下:

         在这里我还拓展了一个函数。g.fillPolygon (); 定义一个多边形的内部,先定义一个函数值,输入相对的顶点坐标,够建一个面,可以更改面的颜色。

            //选择正方形的四个点构成面
			Polygon polygon = new Polygon ();
			polygon.addPoint (x, y);
			polygon.addPoint (x + dx, y - dy);
			polygon.addPoint (x + dx, y - dy+h);
			polygon.addPoint (x, y + h);
			g.setColor(Color.gray);
			g.fillPolygon (polygon);// fillPolygon 定义多边形内部

        这样就给立方体的一个面添加了颜色,将上述代码运行一下看看效果。

 这样,一个立方体内部添加一个球体的图形就完成了,只需添加一个主函数即可。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值