自然几何之分形(1)

来源:互联网 发布:美国石油钻井平台数据 编辑:程序博客网 时间:2024/04/28 00:09

                                                    自然几何之分形(1)

                                                     ------引言

分形Java Applet源代码:

import java.awt.Graphics;
import java.util.Stack;
import java.util.Vector;
import java.awt.event.*;

public class CLSFractal
    extends java.applet.Applet
    implements Runnable, MouseListener {
    Thread kicker;
    ContextLSystem cls;
    int fractLevel = 1;
    int repaintDelay = 50;
    boolean incrementalUpdates;
    float startAngle = 0;
    float rotAngle = 45;
    float Xmin;
    float Xmax;
    float Ymin;
    float Ymax;
    int border;
    boolean normalizescaling;

    public void init() {
 String s;
 cls = new ContextLSystem(this);
 s = getParameter("level");
 if (s != null) fractLevel = Integer.parseInt(s);
 s = getParameter("incremental");
 if (s != null) incrementalUpdates = s.equalsIgnoreCase("true");
 s = getParameter("delay");
 if (s != null) repaintDelay = Integer.parseInt(s);
 s = getParameter("startAngle");
 if (s != null) startAngle = Float.valueOf(s).floatValue();
 s = getParameter("rotAngle");
 if (s != null) rotAngle = Float.valueOf(s).floatValue();
 rotAngle = rotAngle / 360 * 2 * 3.14159265358f;
 s = getParameter("border");
 if (s != null) border = Integer.parseInt(s);
 s = getParameter("normalizescale");
 if (s != null) normalizescaling = s.equalsIgnoreCase("true");
 addMouseListener(this);
    }

    public void destroy() {
        removeMouseListener(this);
    }

    public void run() {
 Thread me = Thread.currentThread();
 boolean needsRepaint = false;
 while (kicker == me && cls.getLevel() < fractLevel) {
     cls.generate();
     if (kicker == me && incrementalUpdates) {
  repaint();
  try {Thread.sleep(repaintDelay);} catch (InterruptedException e){}
     } else {
  needsRepaint = true;
     }
 }
 if (kicker == me) {
     kicker = null;
     if (needsRepaint) {
  repaint();
     }
 }
    }

    public void start() {
 kicker = new Thread(this);
 kicker.start();
    }

    public void stop() {
 kicker = null;
    }

   
    public void mouseReleased(MouseEvent e) {
        cls = new ContextLSystem(this);
        savedPath = null;
        start();
        e.consume();
    }

    String savedPath;

    public void paint(Graphics g) {
 String fractalPath = cls.getPath();
 if (fractalPath == null) {
     super.paint(g);
     return;
 }
 if (savedPath == null || !savedPath.equals(fractalPath)) {
     savedPath = fractalPath;
     render(null, fractalPath);
 }

 for (int i = 0; i < border; i++) {
     g.draw3DRect(i, i, getSize().width - i * 2, getSize().height - i * 2,false);
 }
 render(g, fractalPath);
    }

    void render(Graphics g, String path) {
 Stack turtleStack = new Stack();
 CLSTurtle turtle;

 if (g == null) {
     Xmin = 1E20f;
     Ymin = 1E20f;
     Xmax = -1E20f;
     Ymax = -1E20f;
     turtle = new CLSTurtle(startAngle, 0, 0, 0, 0, 1, 1);
 } else {
     float frwidth = Xmax - Xmin;
     if (frwidth == 0)
  frwidth = 1;
     float frheight = Ymax - Ymin;
     if (frheight == 0)
  frheight = 1;
     float xscale = (getSize().width - border * 2 - 1) / frwidth;
     float yscale = (getSize().height - border * 2 - 1) / frheight;
     int xoff = border;
     int yoff = border;
     if (normalizescaling) {
  if (xscale < yscale) {
      yoff += ((getSize().height - border * 2)
        - ((Ymax - Ymin) * xscale)) / 2;
      yscale = xscale;
  } else if (yscale < xscale) {
      xoff += ((getSize().width - border * 2)
        - ((Xmax - Xmin) * yscale)) / 2;
      xscale = yscale;
  }
     }
     turtle = new CLSTurtle(startAngle, 0 - Xmin, 0 - Ymin,
       xoff, yoff, xscale, yscale);
 }

 for (int pos = 0; pos < path.length(); pos++) {
     switch (path.charAt(pos)) {
     case '+':
  turtle.rotate(rotAngle);
  break;
     case '-':
  turtle.rotate(-rotAngle);
  break;
     case '[':
  turtleStack.push(turtle);
  turtle = new CLSTurtle(turtle);
  break;
     case ']':
  turtle = (CLSTurtle) turtleStack.pop();
  break;
     case 'f':
  turtle.jump();
  break;
     case 'F':
  if (g == null) {
      includePt(turtle.X, turtle.Y);
      turtle.jump();
      includePt(turtle.X, turtle.Y);
  } else {
      turtle.draw(g);
  }
  break;
     default:
  break;
     }
 }
    }

    void includePt(float x, float y) {
 if (x < Xmin)
     Xmin = x;
 if (x > Xmax)
     Xmax = x;
 if (y < Ymin)
     Ymin = y;
 if (y > Ymax)
     Ymax = y;
    }

 
 }

class CLSTurtle {
    float angle;
    float X;
    float Y;
    float scaleX;
    float scaleY;
    int xoff;
    int yoff;

    public CLSTurtle(float ang, float x, float y,
       int xorg, int yorg, float sx, float sy) {
 angle = ang;
 scaleX = sx;
 scaleY = sy;
 X = x * sx;
 Y = y * sy;
 xoff = xorg;
 yoff = yorg;
    }

    public CLSTurtle(CLSTurtle turtle) {
 angle = turtle.angle;
 X = turtle.X;
 Y = turtle.Y;
 scaleX = turtle.scaleX;
 scaleY = turtle.scaleY;
 xoff = turtle.xoff;
 yoff = turtle.yoff;
    }

    public void rotate(float theta) {
 angle += theta;
    }

    public void jump() {
 X += (float) Math.cos(angle) * scaleX;
 Y += (float) Math.sin(angle) * scaleY;
    }

    public void draw(Graphics g) {
 float x = X + (float) Math.cos(angle) * scaleX;
 float y = Y + (float) Math.sin(angle) * scaleY;
 g.drawLine((int) X + xoff, (int) Y + yoff,
     (int) x + xoff, (int) y + yoff);
 X = x;
 Y = y;
    }
}

/**
 * A (non-)Context sensitive L-System class.
 *
 * This class initializes the rules for Context sensitive L-Systems
 * (pred, succ, lContext, rContext) from the given java.applet.Applet's attributes.
 * The generate() method, however, does not (yet) apply the lContext
 * and rContext parts of the rules.
 */
class ContextLSystem {
    String axiom;
    Vector rules = new Vector();
    int level;

    public ContextLSystem(java.applet.Applet app) {
 axiom = app.getParameter("axiom");
 int num = 1;
 while (true) {
     String pred = app.getParameter("pred"+num);
     String succ = app.getParameter("succ"+num);
     if (pred == null || succ == null) {
  break;
     }
     rules.addElement(new CLSRule(pred, succ,
      app.getParameter("lContext"+num),
      app.getParameter("rContext"+num)));
     num++;
 }
 currentPath = new StringBuffer(axiom);
 level = 0;
    }

    public int getLevel() {
 return level;
    }

    StringBuffer currentPath;

    public synchronized String getPath() {
 return ((currentPath == null) ? null : currentPath.toString());
    }

    private synchronized void setPath(StringBuffer path) {
 currentPath = path;
 level++;
    }

    public void generate() {
 StringBuffer newPath = new StringBuffer();
 int pos = 0;
 while (pos < currentPath.length()) {
     CLSRule rule = findRule(pos);
     if (rule == null) {
  newPath.append(currentPath.charAt(pos));
  pos++;
     } else {
  newPath.append(rule.succ);
  pos += rule.pred.length();
     }
 }
 setPath(newPath);
    }

    public CLSRule findRule(int pos) {
 for (int i = 0; i < rules.size(); i++) {
     CLSRule rule = (CLSRule) rules.elementAt(i);
     if (rule.matches(currentPath, pos)) {
  return rule;
     }
 }
 return null;
    }
}

}

安装jdk和jre后,javac  文件名.java

然后编辑网页文件,嵌入刚才生成的类文件。打开浏览器即可看到效果。

这次只是给一个分形的直观概念。