JAVA L-System代码及解析

首先来看看最终效果,如果是你需要的那就继续来看代码的实现过程吧:
(上传的图片有点大个,看在我专门去转了gif大家就凑活看吧)
在这里插入图片描述

在这项程序中,主要创建了三个类,分别是:
定义替换规则和绘图的类:Koch;
监听器(拉杆监听器):Listener
界面:UI

在Koch中主要涉及两个方法:方法defineString实现字符替换,方法drawF实现根据绘图规则绘图,代码如下(这里是有关实现上述内容用到的所有代码,所以有需要的小伙伴可以直接复制看一下效果,应该改一下包名就可以。):

package LSystem;

import java.awt.Graphics;

public class Koch {	
	String str = "F";
	public void defineString(int n,String newstr) {
		//计步
		int number = 0;
		for(int i=0;i<str.length();i++) {
			//将字符串中的F用新的字符串替换
			str=str.replaceAll("F", newstr);			
			System.out.println(str);
			number++;		
		    if(number>=n) {
		    	break;
		    }		   		    		    
		}
	}	
	public void drawF(Graphics g,double startx,double starty,double len,double angle) {
		
		double theta = 0;
		System.out.println(str);
		int Fnum = 0;
		//遍历第一遍确定F个数进而确定此时的len
		for(int i = 0;i<str.length();i++) {
			if((str.charAt(i)=='F')) {
				Fnum++;
			}			
		}
		//确定len长度
		if(Fnum==1) {
			len = len;
		}else {
			len = len/(3*(Fnum/4));
		}	
		//遍历第二遍根据指令绘图
		for(int i = 0;i<str.length();i++) {
			if(str.charAt(i)=='+') {
				theta+=Math.PI/angle;
			}else if((str.charAt(i)=='-')) {
				theta-=Math.PI/angle;
			}else if((str.charAt(i)=='F')) {
			double endx = startx+len*Math.cos(theta);
			double endy = starty-len*Math.sin(theta);		
			g.drawLine((int)startx, (int)starty, (int)(endx), (int)(endy));
		    //端点变起点
		    startx = endx;
		    starty = endy;
			}			
		}		
	}
}

监听器的代码如下:

package LSystem;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class Listener implements ChangeListener{
	 Graphics g;
	 Color color = Color.GREEN;
	 JSlider sliderd;
	 JSlider slidern;
	 JSlider slidertheta;
	 JTextField ruleIn;

	 public void stateChanged(ChangeEvent e) {
		    
		 
		    //更新画布,并在最后设置画笔颜色
	    	Color curColor = g.getColor();
	    	g.setColor(Color.black);			   
			g.fillRect(0,0,1000,1000);    		
			
			//得到滑杆d、n、θ的值
		    double len = sliderd.getValue();
		    int n = slidern.getValue();
		    int theta = slidertheta.getValue();
		    String f = ruleIn.getText();
		    
			g.setColor(color);
		    Koch koch = new Koch();
			koch.defineString(n,f);
			koch.drawF(g, 100, 200, len,theta);
			System.out.println(len);
	 }
}

UI代码如下:

package LSystem;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;

public class UI {
    
	public void showUI() {
		//创建窗体 
		JFrame uiframe = new JFrame();
		uiframe.setSize(600,500);
		uiframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		uiframe.setTitle("L-System");
		//创建东侧面板,放置输入框、滑杆等
		JPanel eastpanel = new JPanel();
		eastpanel.setBackground(new Color(200,200,200));
		Dimension dimension = new Dimension(150,500);
		eastpanel.setPreferredSize(dimension);
		uiframe.add(eastpanel,BorderLayout.EAST);
		//创建一个绘图面板
		JPanel centerpanel = new JPanel();
		centerpanel.setBackground(Color.black);
		uiframe.add(centerpanel,BorderLayout.CENTER);
		
		//对象化监听器
		Listener lis = new Listener();
		
		//在东侧面板添加输入框、滑杆等部件
		eastpanel.setLayout(new GridLayout(13,1));
		eastpanel.add(new JLabel(" "));
		eastpanel.add(new JLabel(" "));
		eastpanel.add(new JLabel("             输入演变规则"));
		//创建文本框对象
		JTextField rule = new JTextField();
		eastpanel.add(rule);
		eastpanel.add(new JLabel("                       n"));		
		//创建滑杆n
		JSlider n = new JSlider(0,10);
        // 设置主刻度间隔
        n.setMajorTickSpacing(5);
        n.setPaintTicks(true);
        n.setPaintLabels(true);
		eastpanel.add(n);
		eastpanel.add(new JLabel("                       θ"));
		//创建滑杆theta
		JSlider theta = new JSlider(1,9);
		eastpanel.add(theta);		
		eastpanel.add(new JLabel("                       d"));		
		//创建滑杆d
		JSlider d = new JSlider(0,3000);
        // 设置主刻度间隔
        d.setMajorTickSpacing(1500);
        // 绘制 刻度 和 标签
        d.setPaintTicks(true);
        d.setPaintLabels(true);
		eastpanel.add(d);
		//设置界面可见
		uiframe.setVisible(true);
		
		//创建窗体的graphics
	    Graphics g = centerpanel.getGraphics();
		//让窗体的graphics等于监听器的
		lis.g = g;
		
		//为滑杆n创建监听器
		n.addChangeListener(lis);
		lis.slidern = n;
		//为滑杆d创建监听器
		d.addChangeListener(lis);
		lis.sliderd = d;
		//为滑杆theta创建监听器 
		theta.addChangeListener(lis);
		lis.slidertheta = theta;
		//获取输入规则里的内容
		lis.ruleIn = rule;		
	}	
	public static void main(String[] args) {
		UI ui = new UI();
		ui.showUI();
	}
}

这样就可以实现依据输入 的绘图规则,如“F+F–F+F”,调整角度和迭代次数或者长度来绘图啦。

当然这个小程序还有很多需要改进的地方,例如可以加入更多的绘图指令,如添加对[]的定义,还有就是每次绘图的起始位置起始可以做的更加智能化 ,设计图形界面时有些代码可能可以进行进一步优化,而不这么机械化,等等等等
继续改进继续加油,希望可以帮助到有需要的小伙伴,小苗要更加努力呀!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值