📄 curve.java
字号:
// point. If so, drop the control point.
if (moving_point >=0) {
moving_point = -1;
repaint();
}
return true;
case Event.MOUSE_DRAG:
// We only care about MOUSE_DRAG's while we are moving a control
// point. Otherwise, do nothing.
if (moving_point >=0) {
ControlPoint pnt = (ControlPoint) points.elementAt(moving_point);
pnt.x = e.x;
pnt.y = e.y;
repaint();
}
return true;
case Event.WINDOW_DESTROY:
System.exit(0);
return true;
default:
return false;
}
}
private void multMatrix(float m[][], float g[][], float mg[][]) {
// This function performs the meat of the calculations for the
// curve plotting. Note that it is not a matrix multiplier in the
// pure sense. The first matrix is the curve matrix (each curve type
// has its own matrix), and the second matrix is the geometry matrix
// (defined by the control points). The result is returned in the
// third matrix.
// First clear the return array
for(int i=0; i<4; i++)
for(int j=0; j<2; j++)
mg[i][j]=0;
// Perform the matrix math
for(int i=0; i<4; i++)
for(int j=0; j<2; j++)
for(int k=0; k<4; k++)
mg[i][j]=mg[i][j] + (m[i][k] * g[k][j]);
}
public void paint(Graphics g) {
int np = points.size(); // number of points
float geom[][] = new float[4][2]; // geometry matrix
float mg[][] = new float[4][2]; //
float plot[][] = new float[4][2];
g.setColor(getForeground());
g.setPaintMode();
// draw a border around the canvas
g.drawRect(0,0, size().width-1, size().height-1);
// draw the control points
for (int i=0; i < np; i++) {
ControlPoint p = (ControlPoint)points.elementAt(i);
g.drawRect(p.x-p.PT_SIZE, p.y-p.PT_SIZE, p.PT_SIZE*2, p.PT_SIZE*2);
g.drawString(String.valueOf(i),p.x+p.PT_SIZE,p.y-p.PT_SIZE);
}
for(int i = 0; i < np-3;) {
// Four control points are needed to create a curve.
// If all the control points are used, the last series of four
// points begins with point np-4.
switch (mode) {
// The geometry matrix for a series of control points is
// different for each curve type.
case(HERMITE):
geom[0][0] = ((ControlPoint)points.elementAt(i)).x;
geom[0][1] = ((ControlPoint)points.elementAt(i)).y;
geom[1][0] = ((ControlPoint)points.elementAt(i+3)).x;
geom[1][1] = ((ControlPoint)points.elementAt(i+3)).y;
geom[2][0] = ((ControlPoint)points.elementAt(i+1)).x-geom[0][0];
geom[2][1] = ((ControlPoint)points.elementAt(i+1)).y-geom[0][1];
geom[3][0] = geom[1][0]-((ControlPoint)points.elementAt(i+2)).x;
geom[3][1] = geom[1][1]-((ControlPoint)points.elementAt(i+2)).y;
multMatrix(hermiteMatrix, geom, mg);
// The beginning of the next Hermite curve is the last
// point of the previous curve.
i += 3;
break;
case(BEZIER):
for(int j = 0; j <4 ;j++) {
geom[j][0] = ((ControlPoint)points.elementAt(i+j)).x;
geom[j][1] = ((ControlPoint)points.elementAt(i+j)).y;
}
multMatrix(bezierMatrix, geom, mg);
// The beginning of the next Bezier curve is the last
// point of the previous curve.
i += 3;
break;
case(BSPLINE):
for(int j = 3; j >= 0; j--) {
geom[3-j][0] = ((ControlPoint)points.elementAt(i+j)).x;
geom[3-j][1] = ((ControlPoint)points.elementAt(i+j)).y;
}
multMatrix(bsplineMatrix, geom, mg);
// B-Spline is the slowest curve, since the beginning of
// the next series of four control points is the second
// control point of the previous series.
i++;
break;
}
// In order to plot the curve using forward differences
// (a speedier way to plot the curve), another matrix
// calculation is required, taking into account the precision
// of the curve.
multMatrix(eMatrix, mg, plot);
float startX = plot[0][0];
float x = startX;
float startY = plot[0][1];
float y = startY;
// Plot the curve using the forward difference method
for(int j=0; j<precision; j++) {
x += plot[1][0];
plot[1][0] += plot[2][0];
plot[2][0] += plot[3][0];
y += plot[1][1];
plot[1][1] += plot[2][1];
plot[2][1] += plot[3][1];
g.drawLine((int)startX,(int)startY,(int)x,(int)y);
startX = x;
startY = y;
}
}
}
}
class CurveControls extends Panel {
CurvePanel target;
Checkbox cb_add;
Checkbox cb_move;
Checkbox cb_delete;
String st_add_label = "Add Points";
String st_move_label = "Move Points";
String st_delete_label = "Delete Points";
public CurveControls(CurvePanel target) {
this.target = target;
setLayout(new FlowLayout(FlowLayout.CENTER));
setBackground(Color.lightGray);
Button clear = new Button("Clear");
add("West",clear);
CheckboxGroup action_group = new CheckboxGroup();
add(cb_add = new Checkbox(st_add_label, action_group, true));
add(cb_move = new Checkbox(st_move_label, action_group, false));
add(cb_delete = new Checkbox(st_delete_label, action_group, false));
}
public void paint(Graphics g) {
Rectangle r = bounds();
g.setColor(Color.lightGray);
g.draw3DRect(0, 0, r.width, r.height, false);
}
public boolean action(Event e, Object arg) {
if (e.target instanceof Checkbox) {
String cbox = ((Checkbox)(e.target)).getLabel();
if (cbox.equals(st_add_label)) {
target.setAction(CurvePanel.ADD);
} else if (cbox.equals(st_move_label)) {
target.setAction(CurvePanel.MOVE);
} else if (cbox.equals(st_delete_label)) {
target.setAction(CurvePanel.DELETE);
}
} else if (e.target instanceof Button) {
String button = ((Button)(e.target)).getLabel();
if (button.equals("Clear")) {
target.clearPoints();
// After clearing the control points, put the user back into
// ADD mode, since none of the other modes make any sense.
cb_add.setState(true);
cb_delete.setState(false);
cb_move.setState(false);
target.setAction(CurvePanel.ADD);
target.repaint();
}
}
return true;
}
}
class CurveControls2 extends Panel {
CurvePanel target;
Checkbox cb_hermite;
Checkbox cb_bezier;
Checkbox cb_bspline;
String st_hermite_label = "Hermite";
String st_bezier_label = "Bezier";
String st_bspline_label = "B-Spline";
Scrollbar scroll;
Label precision_display;
public CurveControls2(CurvePanel target) {
this.target = target;
setLayout(new FlowLayout(1));
CheckboxGroup type_group = new CheckboxGroup();
add(cb_hermite = new Checkbox(st_hermite_label, type_group, true));
add(cb_bezier = new Checkbox(st_bezier_label, type_group, false));
add(cb_bspline = new Checkbox(st_bspline_label, type_group, false));
// Set up the scrollbar: Value 15, Page 5, Min 2, Max 40
add(scroll = new Scrollbar(Scrollbar.HORIZONTAL, 15, 5, 2, 40));
target.setPrecision(scroll.getValue());
add(precision_display = new Label("Precision: "+
String.valueOf(scroll.getValue()),Label.LEFT));
}
public void paint(Graphics g) {
Rectangle r = bounds();
g.setColor(Color.lightGray);
g.draw3DRect(0, 0, r.width, r.height, false);
}
public boolean handleEvent(Event e) {
switch (e.id) {
case Event.SCROLL_LINE_DOWN:
case Event.SCROLL_LINE_UP:
case Event.SCROLL_PAGE_DOWN:
case Event.SCROLL_PAGE_UP:
case Event.SCROLL_ABSOLUTE:
// For any of these events, get the precision value from the
// scrollbar, and update the curve precision, and the label.
target.setPrecision(((Scrollbar)e.target).getValue());
precision_display.setText("Precision: "+
String.valueOf(((Scrollbar)e.target).getValue()));
target.repaint();
return true;
case Event.ACTION_EVENT:
// Handle other action events
if (e.target instanceof Checkbox) {
String cbox = ((Checkbox)(e.target)).getLabel();
if (cbox.equals(st_hermite_label)) {
target.setCurveType(CurvePanel.HERMITE);
} else if (cbox.equals(st_bezier_label)) {
target.setCurveType(CurvePanel.BEZIER);
} else if (cbox.equals(st_bspline_label)) {
target.setCurveType(CurvePanel.BSPLINE);
}
}
target.repaint();
return(true);
default:
return(false);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -