/*
* JavaXYQ Source Code
* by kylixs
* at 2009-11-25
* please visit http://javaxyq.googlecode.com
* or mail to kylixs@qq.com
*/
package com.javaxyq.search;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
/**
* @author dewitt
* @date 2009-11-25 create
*/
public class SearchUtils {
/**
* ����������ֱ��·��
*
* @param x1
* @param y1
* @param x2
* @param y2
* @return
*/
public static List<Point> getLinePath(int x1, int y1, int x2, int y2) {
List<Point> path = new ArrayList<Point>();
int x, y;
int dx, dy;
int incx, incy;
int balance;
int i = 0;
if (x2 >= x1) {
dx = x2 - x1;
incx = 1;
} else {
dx = x1 - x2;
incx = -1;
}
if (y2 >= y1) {
dy = y2 - y1;
incy = 1;
} else {
dy = y1 - y2;
incy = -1;
}
x = x1;
y = y1;
if (dx >= dy) {
dy <<= 1;
balance = dy - dx;
dx <<= 1;
while (x != x2) {
path.add(new Point(x, y));
if (balance >= 0) {
y += incy;
balance -= dx;
}
balance += dy;
x += incx;
i++;
}
path.add(new Point(x, y));
} else {
dx <<= 1;
balance = dx - dy;
dy <<= 1;
while (y != y2) {
path.add(new Point(x, y));
if (balance >= 0) {
x += incx;
balance -= dy;
}
balance += dx;
y += incy;
i++;
}
path.add(new Point(x, y));
}
return path;
}
/**
* ��ȡ�����Ķ�������
*
* @param path
* @param p
* @return
*/
public static List<Point> getBezierPath(Point source, Point target) {
Point[] vertexs = new Point[4];
// ���ö������ߵĿ��Ƶ�
int dx = (target.x - source.x) / 3;
int dy = (target.y - source.y) / 3;
vertexs[0] = source;
vertexs[1] = new Point(source.x + dx, target.y - dy);
vertexs[2] = new Point(target.x - dx , source.y + dy);
vertexs[3] = target;
List<Point> path = new ArrayList<Point>();
getBezierPath(path, vertexs);
return path;
}
private static List<Point> getBezierPath(List<Point> path, Point[] p) {
Point[][] result = new Point[2][4];
Point[] q = new Point[4];
Point[] r = new Point[4];
if (Math.max(distance(p[1], p[0], p[3]), distance(p[2], p[0], p[3])) <= 1.0d)
// g.drawLine(p[0].x, p[0].y, p[3].x, p[3].y);
path.addAll(getLinePath(p[0].x, p[0].y, p[3].x, p[3].y));
else {
result = curve_split(p);
for (int i = 0; i < 4; i++) {
q[i] = new Point(result[0][i].x, result[0][i].y);
r[i] = new Point(result[1][i].x, result[1][i].y);
}
getBezierPath(path, q);
getBezierPath(path, r);
}
return path;
}
/**
*
* Bresenham Line Algorithm ����
*
* @author Turbo Chen ����
* @version 1.0 copyright 2001 ����
* @email turbochen@163.com ����
* @param dashedMask
* �������͵����ߵļ����Ϊ0��ʵ�ߡ� ����
* @param lineWidth
* �����߿� ����
* @param x1
* ����
* @param y1
* @param x2
* ����
* @param y2
* ����
*/
public static void bresenhamLine(java.awt.Graphics g, int dashedMask, int lineWidth, int x1, int y1, int x2, int y2) {
int x, y;
int dx, dy;
int incx, incy;
int balance;
int i = 0;
if (x2 >= x1) {
dx = x2 - x1;
incx = 1;
} else {
dx = x1 - x2;
incx = -1;
}
if (y2 >= y1) {
dy = y2 - y1;
incy = 1;
} else {
dy = y1 - y2;
incy = -1;
}
x = x1;
y = y1;
if (dx >= dy) {
dy <<= 1;
balance = dy - dx;
dx <<= 1;
while (x != x2) {
if ((i & dashedMask) == 0)
g.fillOval(x, y, lineWidth, lineWidth);
if (balance >= 0) {
y += incy;
balance -= dx;
}
balance += dy;
x += incx;
i++;
}
if ((i & dashedMask) == 0)
g.fillOval(x, y, lineWidth, lineWidth);
} else {
dx <<= 1;
balance = dx - dy;
dy <<= 1;
while (y != y2) {
if ((i & dashedMask) == 0)
g.fillOval(x, y, lineWidth, lineWidth);
if (balance >= 0) {
x += incx;
balance -= dy;
}
balance += dx;
y += incy;
i++;
}
if ((i & dashedMask) == 0)
g.fillOval(x, y, lineWidth, lineWidth);
}
}
void draw_Bezier(Graphics g, Point[] p) {
Point[][] result = new Point[2][4];
Point[] q = new Point[4];
Point[] r = new Point[4];
if (Math.max(distance(p[1], p[0], p[3]), distance(p[2], p[0], p[3])) <= 1.0d)
g.drawLine(p[0].x, p[0].y, p[3].x, p[3].y);
else {
result = curve_split(p);
for (int i = 0; i < 4; i++) {
q[i] = new Point(result[0][i].x, result[0][i].y);
r[i] = new Point(result[1][i].x, result[1][i].y);
}
draw_Bezier(g, q);
draw_Bezier(g, r);
}
}
static Point[][] curve_split(Point[] p) {
Point[][] result = new Point[2][4];
Point[] q = new Point[4];
Point[] r = new Point[4];
System.arraycopy(p, 0, q, 0, p.length);
for (int i = 1; i < 4; i++) {
r[4 - i] = new Point(q[3].x, q[3].y);
for (int j = 3; j >= i; j--) {
q[j].x = (q[j].x + q[j - 1].x) >> 1;
q[j].y = (q[j].y + q[j - 1].y) >> 1;
}
}
r[0] = new Point(q[3].x, q[3].y);
for (int i = 0; i < 4; i++) {
result[0][i] = new Point(q[i].x, q[i].y);
result[1][i] = new Point(r[i].x, r[i].y);
}
return result;
}
static double distance(Point p1, Point p2, Point p3) {
double d;
Line2D.Float line = new Line2D.Float(p2.x, p2.y, p3.x, p3.y);
d = line.ptLineDist(p1);
return d;
}
}