package algorithm;
import java.awt.Point;
/**
*
* @author Zhong Jiawu
* @version 1.0
*/
public class BresenhamArc extends Algorithm
{
private int R = -1;
private Point O = new Point();
private int start_degree = -1;
private int stop_degree = -1;
private Point start_point = new Point();
private Point stop_point = new Point();
private int start_quandrant = Quandrant.NE;
private int stop_quandrant = Quandrant.NW;
private int dD;
private int cur_quandrant = Quandrant.NE;
private int cur_xSign = 1;
private int cur_ySign = 1;
private Point cur_point = new Point();
private Point cur_begin_point = new Point();
private Point cur_end_point = new Point();
private static class Direction
{
public static final int H = 0;
public static final int D = 1;
public static final int V = 2;
}
private static class Quandrant
{
public static final int NE = 0;
public static final int NW = 1;
public static final int SW = 2;
public static final int SE = 3;
public static int getXSign(int q)
{
q %= 4;
if (q == SE || q == NE)
return 1;
else
return -1;
}
public static int getYSign(int q)
{
q %= 4;
if (q == NE || q == NW)
return 1;
else
return -1;
}
public static int next(int q)
{
return (q + 1);
}
public static int getQuandrant(int degree)
{
if (degree >= 0 && degree <= 90)
return Quandrant.NE;
else if (degree >= 90 && degree <= 180)
return Quandrant.NW;
else if (degree >= 180 && degree <= 270)
return Quandrant.SW;
else
return Quandrant.SE;
}
public static boolean isClockwise(int q)
{
q = q % 4;
if (q == NE || q == SW)
return true;
else
return false;
}
public static boolean equals(int q1, int q2)
{
q1 %= 4;
q2 %= 4;
return q1 == q2;
}
}
public BresenhamArc()
{
super();
}
public void begin()
{
R = (int) point1.distance(point2);
O = point1;
start_quandrant = Quandrant.getQuandrant(start_degree);
start_point.x = (int) Math.abs((double) R
* Math.cos(Math.PI / 180 * start_degree));
start_point.y = (int) Math.abs((double) R
* Math.sin(Math.PI / 180 * start_degree));
stop_quandrant = Quandrant.getQuandrant(stop_degree);
stop_quandrant = start_degree <= stop_degree ? stop_quandrant
: stop_quandrant + 4;
stop_point.x = (int) Math.abs((double) R
* Math.cos(Math.PI / 180 * stop_degree));
stop_point.y = (int) Math.abs((double) R
* Math.sin(Math.PI / 180 * stop_degree));
cur_quandrant = start_quandrant;
cur_xSign = Quandrant.getXSign(cur_quandrant);
cur_ySign = Quandrant.getYSign(cur_quandrant);
if (Quandrant.equals(cur_quandrant, stop_quandrant)
&& start_degree < stop_degree)
{
if (Quandrant.isClockwise(cur_quandrant))
{
cur_begin_point = stop_point;
cur_end_point = start_point;
} else
{
cur_begin_point = start_point;
cur_end_point = stop_point;
}
} else
{
if (start_point.equals(stop_point))
{
cur_begin_point = start_point;
cur_end_point = stop_point;
} else if (Quandrant.isClockwise(cur_quandrant))
{
cur_begin_point = new Point(0, R);
cur_end_point = start_point;
} else
{
cur_begin_point = start_point;
cur_end_point = new Point(R, 0);
}
}
cur_point = cur_begin_point;
dD = cur_point.x * 2 - cur_point.y * 2 + 2;
return;
}
public void gotoNextQuandrant()
{
cur_quandrant = Quandrant.next(cur_quandrant);
cur_xSign = Quandrant.getXSign(cur_quandrant);
cur_ySign = Quandrant.getYSign(cur_quandrant);
if (Quandrant.equals(cur_quandrant, stop_quandrant))
{
if (Quandrant.isClockwise(cur_quandrant))
{
cur_begin_point = stop_point;
cur_end_point = new Point(R, 0);
} else
{
cur_begin_point = new Point(0, R);
cur_end_point = stop_point;
}
} else
{
cur_begin_point = new Point(0, R);
cur_end_point = new Point(R, 0);
}
cur_point = cur_begin_point;
dD = cur_point.x * 2 - cur_point.y * 2 + 2;
}
public boolean hasNext()
{
if (cur_point.y >= cur_end_point.y)
{
return true;
} else
{
if (cur_quandrant == stop_quandrant)
{
return false;
} else
{
gotoNextQuandrant();
return true;
}
}
}
public Point next()
{
int direction;
if (dD > 0)
{
int dDV = 2 * (dD - cur_point.x) - 1;
if (dDV <= 0)
{
direction = Direction.D;
} else
{
direction = Direction.V;
}
} else if (dD < 0)
{
int dHD = 2 * (dD + cur_point.y) - 1;
if (dHD <= 0)
{
direction = Direction.H;
} else
{
direction = Direction.D;
}
} else
{
direction = Direction.D;
}
switch (direction)
{
case Direction.D:
{
cur_point.x++;
cur_point.y--;
dD += 2 * cur_point.x - 2 * cur_point.y + 2;
break;
}
case Direction.H:
{
cur_point.x++;
dD += 2 * cur_point.x + 1;
break;
}
case Direction.V:
{
cur_point.y--;
dD += -2 * cur_point.y + 1;
break;
}
}
Point point = new Point(this.O);
point.x += cur_point.x * cur_xSign;
point.y += cur_point.y * cur_ySign;
return point;
}
/**
* @param start_degree
* the start_degree to set
*/
public void setStart(int start_degree)
{
this.start_degree = start_degree;
}
/**
* @param stop_degree
* the stop_degree to set
*/
public void setStop(int stop_degree)
{
this.stop_degree = stop_degree;
}
}
评论0