Crossplot на крива на Bezier Аплетът има две основни състояния(modes) Insertion mode
Дата 28.01.2017 Размер 51.67 Kb. #13681
Crossplot на крива на Bezier
Аплетът има две основни състояния(modes)
Insertion mode (по подразбиране).Използва се за интерактивно задаване на точките.Това става с единичен клик на мишката(без значение кой бутон).Двоен клик ще направи две точки !
Drag mode (включва се с натискане на клавиша ‘d’ ,излизането става също с ‘d’ ).Позволява влачене на произволно избрана точка(избирането става с double-left click).Точките от контролния полигон на кривата могат да се движат в произволна посока ,докато тези от контролните полигони на координатните функции могат само да се движат в една посока(абсцисите им са строго фиксирани ).Ако сме избрали точка от контролния полигон на кривата(но не и от контролния полигон на някоя от координатните функции ),с натискане на бутона delete точката се премахва,като това довежда до съответните промени на crossplot-a.
Изтриване на последно добавена точка(независимо от текущото състояние) става с клавиша ‘ r ’ .
За изчистване на екрана се използва клавиша ‘ c ’
Разпечатка на кода на аплета
package kgm;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
/**
*
* @author Plamen
*/
public class Simple extends Applet implements KeyListener, MouseListener, MouseMotionListener, ActionListener {
int width, height, x, y;
int n, offsetX, offsetY;
int interval = 150, index;//index of selected point
boolean showXY = false, mouseRight = false, dragMode = false, pointSelected = false;
String selPointPos = "cpts";//indicates where is the selected point
ArrayList
pts = new ArrayList
();//points of main Bezier curve
ArrayList
cpts = new ArrayList
();//points of control polygon
ArrayList
cptsX = new ArrayList
();//points of control polygon for x = x(y)
ArrayList
cptsY = new ArrayList
();//points of control polygon for y = y(t)
ArrayList
ptsX = new ArrayList
();//points of x coordinate function
ArrayList
ptsY = new ArrayList
();//points of y coordinate function
MouseListener ml;
Graphics2D g2d;
Button rm, drag;
// public boolean mouseClicked = false;
/**
* Initialization method that will be called after the applet is loaded
* into the browser.
*/
@Override
public void init() {
this.setSize(new Dimension(600, 600));
this.setBackground(Color.gray);
addMouseListener(this);
addKeyListener(this);
addMouseMotionListener(this);
width = getSize().width;
offsetX = (width >> 1) - 50;
height = getSize().height;
offsetY = (height >> 1) + 50;
// TODO start asynchronous download of heavy resources
}
public void updateN() {//update index of last point
n = cpts.size() - 1;
}
public void Casteljau(ArrayList
controlPoints, ArrayList
bPoints) {
g2d.setColor(Color.GREEN);
for (int i = 0; i < cpts.size(); i++) {
g2d.fillOval(cpts.get(i).x, cpts.get(i).y, 6, 6);
g2d.fillOval(cptsX.get(i).x, cptsX.get(i).y, 6, 6);
g2d.fillOval(cptsY.get(i).x, cptsY.get(i).y, 6, 6);
}
double t;
bPoints.clear();//remove previous content
Point2D.Double[] tmp = new Point2D.Double[n + 1];
g2d.setColor(Color.BLACK);
for (t = 0; t <= 1.0; t += 0.01) {
for (int k = 0; k <= n; k++) {//fill tmp with control points
tmp[k] = new Point2D.Double(controlPoints.get(k).x, controlPoints.get(k).y);
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= n - i; j++) {
tmp[j] = new Point2D.Double((1 - t) * tmp[j].x + t * tmp[j + 1].x, (1 - t) * tmp[j].y + t * tmp[j + 1].y);
}
}
bPoints.add(tmp[0]);
}
g2d.setColor(Color.RED);
//g.drawString(cnt + "", 50, 50);
for (int i = 0; i < bPoints.size() - 1; i++) {//draw Bezier curve
Line2D.Double l = new Line2D.Double(bPoints.get(i).x, bPoints.get(i).y, bPoints.get(i + 1).x, bPoints.get(i + 1).y);
g2d.draw(l);
//g2d.drawLine((int) (bPoints.get(i).x + 0.5), (int) (bPoints.get(i).y + 0.5), (int) (bPoints.get(i + 1).x + 0.5), (int) (bPoints.get(i + 1).y + 0.5));
}
}
@Override
public void paint(Graphics g) {
g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);//turn on antialiasing for shapes
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);//turn on antialiasing for text
drawAxis();
if (mouseRight) {//show absolute coordinates of a clicked point
drawCoor();
}
g2d.setColor(Color.BLACK);
if (dragMode) {
g2d.drawString("Drag mode.Press 'd' to disable", 20, 20);
} else {
g2d.drawString("Drag mode disabled.Press 'd' to enable", 20, 20);
}
g2d.setColor(Color.GREEN);
if (cpts.size() == 1) {
g2d.fillOval(cpts.get(0).x, cpts.get(0).y, 6, 6);
}
if (cpts.size() >= 2) {
drawControlPolygon(cpts, Color.GREEN);
drawControlPolygon(cptsX, Color.CYAN);
drawControlPolygon(cptsY, Color.ORANGE);
Casteljau(cpts, pts);
Casteljau(cptsX, ptsX);
Casteljau(cptsY, ptsY);
}
// TODO overwrite start(), stop() and destroy() methods
}
public void drawControlPolygon(ArrayList
cPoints, Color c) {
g2d.setColor(c);
for (int i = 0; i < cPoints.size() - 1; i++) {//draw control polygon
g2d.drawLine(cPoints.get(i).x, cPoints.get(i).y, cPoints.get(i + 1).x, cPoints.get(i + 1).y);
//Line2D.Double l = new Line2D.Double(cPoints.get(i).x, cPoints.get(i).y, cPoints.get(i + 1).x, cPoints.get(i + 1).y);
//g2d.draw(l);
}
}
public void clear() {
cpts.clear();
cptsX.clear();
cptsY.clear();
updateN();
repaint();
}
public void mouseClicked(MouseEvent e) { //cpts.add(new Point(e.getX(),e.getY()));
//repaint();
}
public void drawAxis() {
int cx = width >> 1;
int cy = height >> 1;
g2d.setColor(Color.BLACK);
g2d.drawLine(cx, 30, cx, height - 50);
g2d.drawString("Y", cx, 30);
g2d.drawString("T", cx, height - 50);
g2d.drawLine(30, cy, width - 50, cy);
g2d.drawString("X", width - 50, cy);
g2d.drawString("T", 30, cy);
}
public void updateFunc() {//changes the control points of x = x(t) i y = y(t)
if (n > 0) {
for (int i = 0; i <= n; i++) {
cptsX.get(i).y = offsetY + i * interval / n;
cptsY.get(i).x = offsetX - i * interval / n;
}
}
}
public int getPointIndex(int points, int x, int y)//return -1 if point(x,y) not registered
{
ArrayList
p = null;
switch (points) {
case 1:
p = cpts;
break;
case 2:
p = cptsX;
break;
case 3:
p = cptsY;
break;
}
for (int i = 0; i < p.size(); i++) {
if (Math.abs(x - p.get(i).x) <= 3 && Math.abs(y - p.get(i).y) <= 3) {
return i;
}
}
return -1;
}
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3 && showXY) {
x = e.getX();
y = e.getY();
mouseRight = true;
} else if (dragMode) {
String[] ch = {"cpts", "cptsX", "cptsY"};
for (int i = 0; i < ch.length; i++) {
index = getPointIndex(i + 1, e.getX(), e.getY());
if (index != -1) {
pointSelected = true;
selPointPos = ch[i];
break;
}
}
if (index == -1) {
pointSelected = false;
}
} else {
cpts.add(new Point(e.getX(), e.getY()));
updateN();
cptsX.add(new Point(e.getX(), offsetY + n * 30));
cptsY.add(new Point(offsetX - n * 30, e.getY()));
updateFunc();
}
repaint();
}
public void drawCoor() {
mouseRight = false;
g2d.setColor(Color.MAGENTA);
g2d.drawString("(" + x + "," + y + ")", x, y);
}
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == 's') {
showXY = true;
}
if (e.getKeyChar() == 'd') {//key 'd' enables and disables drag mode
dragMode = !dragMode;
repaint();
}
if (e.getKeyChar() == 'c') {
clear();
}
}
public void removeLastPoint() {
if (cpts.size() > 0) {
int size = cpts.size() - 1;
cpts.remove(size);
cptsX.remove(size);
cptsY.remove(size);
updateN();
updateFunc();
repaint();
}
}
public void removePointAt(int index) {
cpts.remove(index);
cptsX.remove(index);
cptsY.remove(index);
updateN();
updateFunc();
repaint();
}
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == 'r') {
removeLastPoint();
}
if (e.getKeyCode() == KeyEvent.VK_DELETE && selPointPos.equals("cpts") && index != -1) {//must be in this method
pointSelected = false;
removePointAt(index);
}
}
public void mouseDragged(MouseEvent e) {
if (dragMode && pointSelected) {
if (selPointPos.equals("cpts")) {
if (e.getX() < width && e.getX() > 0 && e.getY() < height && e.getY() > 0) {
cpts.get(index).x = e.getX();
cpts.get(index).y = e.getY();
cptsX.get(index).x = e.getX();
cptsY.get(index).y = e.getY();
}
} else if (selPointPos.equals("cptsX")) {
if (e.getX() < width && e.getX() > 0) {
cpts.get(index).x = e.getX();
cptsX.get(index).x = e.getX();
}
} else {
if (e.getY() < height && e.getY() > 0) {
cpts.get(index).y = e.getY();
cptsY.get(index).y = e.getY();
}
}
repaint();
}
}
Сподели с приятели: