import java.awt.*;
import java.applet.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
public class SmoothTest extends Applet {
Button draw1Button, draw2Button, modifyButton, deleteButton, clearButton;
myCanvas canvas;
TextField statusBar;
public void init() {
GridBagLayout layout = new GridBagLayout();
setLayout(layout);
GridBagConstraints constraints = new GridBagConstraints();
draw1Button = new Button("Draw Bezier");
draw2Button = new Button("Draw B-Spline");
modifyButton = new Button("Modify");
deleteButton = new Button("Delete curve");
clearButton = new Button("Clear All");
constraints.fill = GridBagConstraints.BOTH;
constraints.weightx = 1;
layout.setConstraints(draw1Button, constraints);
add(draw1Button);
layout.setConstraints(draw2Button, constraints);
add(draw2Button);
layout.setConstraints(modifyButton, constraints);
add(modifyButton);
constraints.gridwidth = GridBagConstraints.RELATIVE;
layout.setConstraints(deleteButton, constraints);
add(deleteButton);
constraints.gridwidth = GridBagConstraints.REMAINDER;
layout.setConstraints(clearButton, constraints);
add(clearButton);
canvas = new myCanvas();
constraints.weighty = 1;
layout.setConstraints(canvas, constraints);
add(canvas);
//canvas.test();
//g.drawLine(476, 429, 490, 411);
statusBar = new TextField("Draw Bezier: click to add a point, double click to finish drawing", 45);
statusBar.setEditable(false);
constraints.weighty = 0;
layout.setConstraints(statusBar, constraints);
add(statusBar);
resize(1280, 760); //Set window size
}
}
class myCanvas extends Canvas {
PointList pts[];
int nline;
int curObj;
boolean drawing;
int action;
final int DRAW_BEZIER = 1, DRAW_BSPLINE = 2, MODIFY = 3, DELETE = 4;
ErrorFrame errDlg;
// double buffering
Image img = null;
Graphics backg;
public myCanvas() {
pts = new PointList[200];
nline = -1;
drawing = false;
action = DRAW_BEZIER;
errDlg = new ErrorFrame(" Too many points!");
}
void setcursor(boolean working) {
Cursor curs;
if (working) {
curs = new Cursor(Cursor.HAND_CURSOR);
} else {
curs = new Cursor(Cursor.DEFAULT_CURSOR);
}
setCursor(curs);
}
public void test(){
if (action == DRAW_BEZIER || action == DRAW_BSPLINE) {
System.out.println(nline);
pts[0].draw(backg);
// nline++;
System.out.println("drawing false");
pts[nline] = new bezierLine();
if (!pts[nline].done()) {
if (!errDlg.isShowing()) {
errDlg.show();
}
nline--;
}
//repaint();
}
nline=0;
}
public void paint(Graphics g) {
update(g);
}
public void update(Graphics g) { //Don't bother
int i, n;
int w=0;
PointList temp[] = new PointList[30];
Dimension d = size();
int flag1=-1, x21=0,y21=0,x22=0,y22=0;
int flag2=-1;
if (img == null) {
img = createImage(d.width, d.height);
backg = img.getGraphics();
}
backg.setColor(new Color(255, 255, 255)); //Set color for background
backg.fillRect(0, 0, d.width, d.height); //Draw Backround
// draw border
backg.setColor(new Color(0, 0, 0));
backg.drawRect(1, 1, d.width - 3, d.height - 3);
/* for (n = 0; n <= nline; n++) {
pts[n].draw(backg);
}*/
g.setColor(Color.red);
try
{
Scanner br= new Scanner(new FileReader("route1.txt"));
while (br.hasNextInt())
{
if (w==0)// 1st run
{
w=1;
x21=br.nextInt();
y21=br.nextInt();
flag1=br.nextInt();
x22=br.nextInt();
y22=br.nextInt();
flag2=br.nextInt();
if (flag1==0 && flag2==0)
{
g.drawLine(x21, y21, x22, y22);
x21=x22;
y21=y22;
flag1=flag2;
}
}
else
{
if (flag1==0 && flag2==0)
{
g.drawLine(x21, y21, x22, y22);
x21=x22;
y21=y22;
flag1=flag2;
}
else if(flag1==0 && flag2==1)// start of curve found
{
g.drawLine(x21, y21, x22, y22);
temp[nline].addCurve(x22, y22);
nline++;
x21=x22;
y21=y22;
flag1=flag2;
}
else if (flag1==1 && flag2==1)// mid curve
{
temp[nline].addCurve(x22, y22);
nline++;
flag2=flag1;
}
else if (flag1==1 && flag2==0)// end of curve
{
// System.out.println("Flag1: "+flag1 +" Flag2: "+flag2);
temp[nline].addCurve(x22, y22);
nline++;
x21=x22;
y21=y22;
flag1=flag2;
for (int z=0;z<=nline;z++)
{
temp[z]= new bezierLine();
temp[z].draw(g);
}
temp[0].resetCurve();
nline=0;
}
}
x22=br.nextInt();
y22=br.nextInt();
flag2=br.nextInt();
}
}
catch(Exception e)
{
}
}
}
class ErrorFrame extends Frame {
Label label;
Button button;
String errMsg;
ErrorFrame(String msg) {
super("Error!");
errMsg = msg;
BorderLayout layout = new BorderLayout();
setLayout(layout);
label = new Label(errMsg);
add("North", label);
button = new Button("Ok");
add("South", button);
resize(200, 100);
}
public boolean action(Event evt, Object arg) {
if (arg == "Ok") {
dispose();
}
return true;
}
}
class PointList {
Point pt[];
int num;
int x, y, z; // color
boolean showLine;
int curPt;
final int MAXCNTL = 150;
final int range = 5;
PointList() {
num = 0;
curPt = -1;
pt = new Point[MAXCNTL];
x = (int) (Math.random() * 255);
y = (int) (Math.random() * 255);
z = (int) (Math.random() * 255);
}
void addCurve(int x3,int y3)
{
pt[num] = new Point(x3,y3);
num++;
}
void resetCurve ()
{
num=0;
}
void changeModPoint(int x, int y) {
pt[curPt].x = x;
pt[curPt].y = y;
}
boolean createFinal() {
return true;
}
boolean done() {
return true;
}
void setShow(boolean show) {
showLine = show;
}
int inRegion(int x, int y) {
int i;
for (i = 0; i < num; i++) {
if (Math.abs(pt[i].x - x) < range && Math.abs(pt[i].y - y) < range) {
curPt = i;
return i;
}
}
curPt = -1;
return -1;
}
void draw(Graphics g) {
int i;
int l = 3;
for (i = 0; i < num - 1; i++) {
g.drawLine(pt[i].x - l, pt[i].y, pt[i].x + l, pt[i].y);
g.drawLine(pt[i].x, pt[i].y - l, pt[i].x, pt[i].y + l);
}
g.drawLine(pt[i].x - l, pt[i].y, pt[i].x + l, pt[i].y);
g.drawLine(pt[i].x, pt[i].y - l, pt[i].x, pt[i].y + l);
}
}
class bezierLine extends PointList {
Point bpt[];
int bnum;
boolean ready;
final int MAXPOINT = 1800;
final int ENOUGH = 2;
final int RECURSION = 900;
int nPointAlloc;
int enough; // control how well we draw the curve.
int nRecur; // counter of number of recursion
Point buffer[][];
int nBuf, nBufAlloc;
bezierLine() {
bpt = new Point[MAXPOINT];
nPointAlloc = MAXPOINT;
bnum = 0;
enough = ENOUGH;
showLine = true;
ready = false;
buffer = null;
}
protected int distance(Point p0, Point p1, Point p2) {
int a, b, y1, x1, d1, d2;
if (p1.x == p2.x && p1.y == p2.y) {
return Math.min(Math.abs(p0.x - p1.x), Math.abs(p0.y - p1.y));
}
a = p2.x - p1.x;
b = p2.y - p1.y;
y1 = b * (p0.x - p1.x) + a * p1.y;
x1 = a * (p0.y - p1.y) + b * p1.x;
d1 = Math.abs(y1 - a * p0.y);
d2 = Math.abs(x1 - b * p0.x);
if (a == 0) {
return Math.abs(d2 / b);
}
if (b == 0) {
return Math.abs(d1 / a);
}
return Math.min(Math.abs(d1 / a), Math.abs(d2 / b));
}
protected void curve_split(Point p[], Point q[], Point r[], int num) {
int i, j;
for (i = 0; i < num; i++) {
q[i].copy(p[i]);
}
for (i = 1; i <= num - 1; i++) {
r[num - i].copy(q[num - 1]);
for (j = num - 1; j >= i; j--) {
q[j].x = (q[j - 1].x + q[j].x) / 2;
q[j].y = (q[j - 1].y + q[j].y) / 2;
}
}
r[0].copy(q[num - 1]);
}
private Point get_buf (int num)
[]
{
Point b[];
if (buffer == null) {
buffer = new Point[500][num];
nBufAlloc = 500;
nBuf = 0;
}
if (nBuf == 0) {
b = new Point[num];
for (int i = 0; i < num; i++) {
b[i] = new Point();
}
return b;
} else {
nBuf--;
b = buffer[nBuf];
return b;
}
}
protected boolean bezier_generation(Point pt[], int num, Point result[], int n[]) {
Point qt[], rt[]; // for split
int d[], i, max;
nRecur++;
if (nRecur > RECURSION) {
return false;
}
d = new int[MAXCNTL];
for (i = 1; i < num - 1; i++) {
d[i] = distance(pt[i], pt[0], pt[num - 1]);
}
max = d[1];
for (i = 2; i < num - 1; i++) {
if (d[i] > max) {
max = d[i];
}
}
if (max <= enough || nRecur > RECURSION) {
if (n[0] == 0) {
if (bnum > 0) {
result[0].copy(pt[0]);
} else {
result[0] = new Point(pt[0]);
}
n[0] = 1;
}
//reuse
if (bnum > n[0]) {
result[n[0]].copy(pt[num - 1]);
} else {
result[n[0]] = new Point(pt[num - 1]);
}
n[0]++;
if (n[0] == MAXPOINT - 1) {
return false;
}
} else {
qt = get_buf(num);
rt = get_buf(num);
curve_split(pt, qt, rt, num);
if (!bezier_generation(qt, num, result, n)) {
return false;
}
if (!bezier_generation(rt, num, result, n)) {
return false;
}
}
return true;
}
public boolean try_bezier_generation(Point pt[], int num, Point result[], int n[]) {
int oldN = n[0];
if (enough == ENOUGH && num > 6) {
enough += 3;
}
nRecur = 0;
while (!bezier_generation(pt, num, bpt, n)) {
n[0] = oldN;
enough += 5;
nRecur = 0;
}
return true;
}
boolean createFinal() {
int n[];
n = new int[1];
if (!try_bezier_generation(pt, num, bpt, n)) {
bnum = 0;
return false;
} else {
bnum = n[0];
return true;
}
}
boolean done() {
num--;
showLine = false;
ready = true;
return createFinal();
}
void draw(Graphics g) {
g.setColor(Color.red);
if (ready) {
for (int i = 0; i < bnum - 1; i++) {
g.drawLine(bpt[i].x, bpt[i].y, bpt[i + 1].x, bpt[i + 1].y);
}
}
}
}
class Point {
int x, y;
Point(Point p) {
x = p.x;
y = p.y;
}
Point(int _x, int _y) {
x = _x;
y = _y;
}
Point() {
x = 0;
y = 0;
}
void copy(Point p) {
x = p.x;
y = p.y;
}
}