📄 drawpanel.java
字号:
package kc.test.kmeans;
import voronoi.VoronoiSegment;
import voronoi.Vertex;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.util.*;
public class DrawPanel extends Canvas implements MouseListener, MouseMotionListener,
ComponentListener
{
private ArrayList<Point> points;
private ArrayList<Centroid> clusters;
private ArrayList<CentroidNode> centroids;
private ArrayList<Point> points_cloned;
private ArrayList<Centroid> clusters_cloned;
private BufferedImage bi;
private Graphics2D big;
private Dimension dim;
private boolean dragging;
private CentroidNode dragNode;
private Centroid dragCenter;
private KMeansAlgorithm algorithm;
private static final int POINT_SIZE = 6;
private static final int CENTROID_SIZE = 10;
private CommandPanel command;
public DrawPanel(CommandPanel cmd) {
addMouseMotionListener(this);
addMouseListener(this);
addComponentListener(this);
algorithm = new KMeansAlgorithm();
points = new ArrayList<Point>();
clusters = new ArrayList<Centroid>();
centroids = new ArrayList<CentroidNode>();
command = cmd;
command.setState(1, 0);
}
public void initialize() {
Random r = new Random();
points.clear();
clusters.clear();
centroids.clear();
for (int j=0; j<command.getClusters(); j++) {
int x = (int) dim.getWidth() - 100;
x = r.nextInt(x) + 50;
int y = (int) dim.getHeight() - 80;
y = r.nextInt(y) + 40;
CentroidNode c = new CentroidNode(x, y, command.getDeviationX(),
command.getDeviationY(), command.getNodes());
centroids.add(c);
}
algorithm.setInit(false);
command.setState(2, 0);
repaint();
}
public void reset() {
if (points_cloned != null) {
points = points_cloned;
clusters = clusters_cloned;
algorithm.setInit(false);
command.setState(3, 0);
repaint();
}
}
public void start() {
Random r = new Random(new Date().getTime());
points.clear();
clusters.clear();
// copy points from centroidNodes to pointlist
for (CentroidNode n : centroids) {
for (java.awt.geom.Point2D p : n.nodes) {
points.add(new Point(p));
}
int x = r.nextInt((int) dim.getWidth() - 100) + 50;
int y = r.nextInt((int) dim.getWidth() - 80) + 40;
int rr = r.nextInt(256);
int gg = r.nextInt(256);
int bb = r.nextInt(256);
clusters.add(new Centroid(new java.awt.geom.Point2D.Double(x, y), new Color(rr, gg, bb)));
}
points_cloned = new ArrayList<Point>();
for (Point p : points) {
points_cloned.add(p.clone());
}
clusters_cloned = new ArrayList<Centroid>();
for (Centroid c : clusters) {
clusters_cloned.add(c.clone());
}
algorithm.init(points, clusters);
command.setState(4, 0);
repaint();
}
public void step() {
algorithm.step();
repaint();
}
public void run() {
int iterations = algorithm.run();
command.setState(5, iterations);
repaint();
}
public void mouseDragged(MouseEvent e) {
if(dragging){
updateLocation(e);
}
}
public void mousePressed(MouseEvent e) {
// check wether we want to drag a centroid
int x = e.getX();
int y = e.getY();
// if algorithm is not yet initialized, we can change layout of data items
if (!algorithm.isInitialized()) {
for (CentroidNode n : centroids) {
if (n.box.contains(x, y)) {
dragging = true;
dragNode = n;
break;
}
}
if (!dragging) {
CentroidNode c = new CentroidNode(e.getX(), e.getY(), command.getDeviationX(),
command.getDeviationY(), command.getNodes());
centroids.add(c);
}
} else {
for (Centroid c : clusters) {
Shape s = new Ellipse2D.Double((int) c.getP().getX() - CENTROID_SIZE / 2,
(int) c.getP().getY() - CENTROID_SIZE / 2, CENTROID_SIZE, CENTROID_SIZE);
if (s.contains(x, y)) {
dragging = true;
dragCenter = c;
break;
}
}
}
}
public void mouseReleased(MouseEvent e) {
dragging = false;
dragNode = null;
dragCenter = null;
repaint();
}
public void mouseMoved(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
// These methods are required by MouseMotionListener.
public void updateLocation(MouseEvent e){
if (dragNode != null)
dragNode.setPosition(e.getX(), e.getY());
if (dragCenter != null)
dragCenter.getP().setLocation(e.getX(), e.getY());
repaint();
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
// Draws the buffered image to the screen.
g2.drawImage(bi, 0, 0, this);
}
public void update(Graphics g){
// Clears the rectangle that was previously drawn.
big.setColor(Color.white);
big.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
big.fillRect(0, 0, dim.width, dim.height);
if (algorithm.isInitialized())
drawAlgo();
else
drawPlacing();
paint(g);
}
private void drawPlacing() {
Rectangle2D.Float r = new Rectangle2D.Float();
for(CentroidNode n: centroids) {
big.setColor(Color.black);
for (java.awt.geom.Point2D p : n.nodes) {
big.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
big.fillOval((int) p.getX() - POINT_SIZE / 2, (int) p.getY() - POINT_SIZE / 2, POINT_SIZE, POINT_SIZE);
big.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
big.drawOval((int) p.getX() - POINT_SIZE / 2, (int) p.getY() - POINT_SIZE / 2, POINT_SIZE, POINT_SIZE);
}
r.setRect(n.box);
big.setColor(Color.red);
big.fill(r);
}
}
private void drawAlgo() {
for(Point p : points) {
drawPoint((int) p.getP().getX(), (int) p.getP().getY(), POINT_SIZE, p.getColor(), p.getColor(), 0.4f);
}
for (Centroid c : clusters) {
java.awt.geom.Point2D old = null;
if (command.getShowHistory()) {
for (java.awt.geom.Point2D hp : c.getHistory()) {
if (old != null) {
big.setColor(Color.black);
big.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
drawArrow(big, (int) old.getX(), (int) old.getY(), (int) hp.getX(), (int) hp.getY());
}
drawPoint((int) hp.getX(), (int) hp.getY(), CENTROID_SIZE, Color.gray, c.getColor(), 0.8f);
old = hp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -