下面列出了怎么用java.awt.geom.CubicCurve2D的API类实例代码及写法,或者点击链接到github查看源代码。
/** Chop the end of this curve. */
public void chopEnd(double t) {
int n = list.size();
t = t * n;
double di = StrictMath.floor(t);
int i = (int) di;
//
if (i < 0)
list.clear();
if (i >= n)
return;
while (i + 1 < list.size())
list.remove(i + 1);
if (list.isEmpty()) {
endX = startX;
endY = startY;
list.add(new CubicCurve2D.Double(endX, endY, endX, endY, endX, endY, endX, endY));
return;
}
CubicCurve2D.Double tmp = new CubicCurve2D.Double();
divide(t - di, list.get(i), tmp, new CubicCurve2D.Double());
list.get(i).setCurve(tmp);
endX = tmp.x2;
endY = tmp.y2;
}
/**
* Given 0<=t<=1 and an existing curve, divide it into two chunks and store the
* two chunks into "first" and "second"
*/
public static void divide(double t, CubicCurve2D.Double curve, CubicCurve2D.Double first, CubicCurve2D.Double second) {
// This algorithm uses de Casteljau's algorithm for chopping one bezier
// curve into two bezier curves
first.x1 = curve.x1;
second.x2 = curve.x2;
first.ctrlx1 = (1 - t) * curve.x1 + t * curve.ctrlx1;
double x = (1 - t) * curve.ctrlx1 + t * curve.ctrlx2;
second.ctrlx2 = (1 - t) * curve.ctrlx2 + t * curve.x2;
first.ctrlx2 = (1 - t) * first.ctrlx1 + t * x;
second.ctrlx1 = (1 - t) * x + t * second.ctrlx2;
second.x1 = first.x2 = (1 - t) * first.ctrlx2 + t * second.ctrlx1;
// now that we've computed the x coordinates, we now compute the y
// coordinates
first.y1 = curve.y1;
second.y2 = curve.y2;
first.ctrly1 = (1 - t) * curve.y1 + t * curve.ctrly1;
double y = (1 - t) * curve.ctrly1 + t * curve.ctrly2;
second.ctrly2 = (1 - t) * curve.ctrly2 + t * curve.y2;
first.ctrly2 = (1 - t) * first.ctrly1 + t * y;
second.ctrly1 = (1 - t) * y + t * second.ctrly2;
second.y1 = first.y2 = (1 - t) * first.ctrly2 + t * second.ctrly1;
}
public Shape getRegiaoDocumento() {
if (Regiao == null) {
final int v1 = getHeight() / 3;
final int h1 = getWidth() / 2;
final int repo = v1 / 3;
final int L = getLeft();
final int T = getTop();
final int TH = T + getHeight() - repo;
final int LW = L + getWidth();
CubicCurve2D c = new CubicCurve2D.Double();
c.setCurve(L, TH, L + h1, TH + v1, LW - h1, TH - v1, LW, TH);
GeneralPath pa = new GeneralPath();
pa.moveTo(LW, TH);
pa.lineTo(LW, T);
pa.lineTo(L, T);
pa.lineTo(L, TH);
pa.append(c, true);
Regiao = pa;
final int ptToMove = 3;
this.reposicionePonto[ptToMove] = new Point(0, -repo);
ptsToMove[ptToMove] = 1;
}
return Regiao;
}
public void paintUsing(Graphics g, BX bx) {
double cx = spin.center.getSX();
double cy = spin.center.getSY();
if(spin.use2D) {
CubicCurve2D.Double curve =
new CubicCurve2D.Double (sx, sy,
cx, cy,
cx, cy,
bx.sx, bx.sy);
((Graphics2D)g).draw(curve);
} else {
drawSpline(g, sx, sy,
cx, cy,
cx, cy,
bx.sx, bx.sy, 5);
}
}
@Test
public void test_getControlBounds() {
BezierCurve c0 = new BezierCurve(1, 1, 1, 10, 10, 1, 10, 10);
assertEquals(new Rectangle(1, 1, 9, 9), c0.getControlBounds());
BezierCurve c1 = new BezierCurve(1, 5, 5, 8, 10, 1);
assertEquals(new Rectangle(1, 1, 9, 7), c1.getControlBounds());
// Check the bounds are comparable to those returned by
// CubicCurve2D.getBounds2D(), which returns the control polygon bounds
// as well
BezierCurve c3 = new BezierCurve(399.05999755859375, 96.6969985961914,
484.6500244140625, 209.1699981689453, 456.27001953125,
302.8699951171875, 438.55999755859375, 348.239990234375);
Rectangle c3CubicCurve2DBounds = AWT2Geometry.toRectangle(
new CubicCurve2D.Double(399.05999755859375, 96.6969985961914,
484.6500244140625, 209.1699981689453, 456.27001953125,
302.8699951171875, 438.55999755859375, 348.239990234375)
.getBounds2D());
assertEquals(c3CubicCurve2DBounds.getHeight(),
c3.getControlBounds().getHeight(), 0.1);
assertEquals(c3CubicCurve2DBounds.getWidth(),
c3.getControlBounds().getWidth(), 0.1);
}
@Override
protected void paint (Graphics2D g,
Params p,
Point location,
Alignment alignment)
{
Point loc = alignment.translatedPoint(TOP_LEFT, p.rect, location);
CubicCurve2D curve = new CubicCurve2D.Double(
loc.x,
loc.y + p.rect.height,
loc.x + ((3 * p.rect.width) / 10),
loc.y + (p.rect.height / 5),
loc.x + (p.rect.width / 2),
loc.y,
loc.x + p.rect.width,
loc.y);
// Slur
g.draw(curve);
}
@Override
protected void paint (Graphics2D g,
Params p,
Point location,
Alignment alignment)
{
Point loc = alignment.translatedPoint(
TOP_LEFT,
p.rect,
location);
CubicCurve2D curve = new CubicCurve2D.Double(
loc.x,
loc.y + p.rect.height,
loc.x + ((3 * p.rect.width) / 10),
loc.y + (p.rect.height / 5),
loc.x + (p.rect.width / 2),
loc.y,
loc.x + p.rect.width,
loc.y);
// Slur
g.draw(curve);
}
public void runTest(Object ctx, int numReps) {
FillCubics.Context cctx = (FillCubics.Context) ctx;
int size = cctx.size;
// Note: 2x2 ends up hitting exactly 1 pixel...
if (size < 2) size = 2;
int x = cctx.initX;
int y = cctx.initY;
int cpoffset = (int) (size/relYmax/2);
CubicCurve2D curve = cctx.curve;
Graphics2D g2d = (Graphics2D) cctx.graphics;
g2d.translate(cctx.orgX, cctx.orgY);
Color rCArray[] = cctx.colorlist;
int ci = cctx.colorindex;
do {
curve.setCurve(x, y+size/2.0,
x+size/2.0, y+size/2.0-cpoffset,
x+size/2.0, y+size/2.0+cpoffset,
x+size, y+size/2.0);
if (rCArray != null) {
g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
}
g2d.fill(curve);
if ((x -= 3) < 0) x += cctx.maxX;
if ((y -= 1) < 0) y += cctx.maxY;
} while (--numReps > 0);
cctx.colorindex = ci;
g2d.translate(-cctx.orgX, -cctx.orgY);
}
/**
* Tests {@link ShapeUtilities#toPrimitive(Shape)}.
*/
@Test
public void testToPrimitive() {
final Path2D path = new Path2D.Double();
path.moveTo(4, 5);
path.lineTo(7, 9);
Shape p = ShapeUtilities.toPrimitive(path);
assertInstanceOf("toPrimitive", Line2D.class, p);
assertEquals("P1", new Point2D.Double(4, 5), ((Line2D) p).getP1());
assertEquals("P2", new Point2D.Double(7, 9), ((Line2D) p).getP2());
path.reset();
path.moveTo(4, 5);
path.quadTo(6, 7, 8, 5);
p = ShapeUtilities.toPrimitive(path);
assertInstanceOf("toPrimitive", QuadCurve2D.class, p);
assertEquals("P1", new Point2D.Double(4, 5), ((QuadCurve2D) p).getP1());
assertEquals("CtrlPt", new Point2D.Double(6, 7), ((QuadCurve2D) p).getCtrlPt());
assertEquals("P2", new Point2D.Double(8, 5), ((QuadCurve2D) p).getP2());
path.reset();
path.moveTo(4, 5);
path.curveTo(6, 7, 8, 6, 9, 4);
p = ShapeUtilities.toPrimitive(path);
assertInstanceOf("toPrimitive", CubicCurve2D.class, p);
assertEquals("P1", new Point2D.Double(4, 5), ((CubicCurve2D) p).getP1());
assertEquals("CtrlP1", new Point2D.Double(6, 7), ((CubicCurve2D) p).getCtrlP1());
assertEquals("CtrlP2", new Point2D.Double(8, 6), ((CubicCurve2D) p).getCtrlP2());
assertEquals("P2", new Point2D.Double(9, 4), ((CubicCurve2D) p).getP2());
}
public static void main(String[] args) throws Exception {
CubicCurve2D c = new CubicCurve2D.Double(0, 0, 4, -4, -2, -4, 2, 0);
Rectangle2D r = new Rectangle2D.Double(0.75, -2.5, 0.5, 2);
if (c.contains(r)) {
throw new Exception("The rectangle should not be contained in the curve");
}
}
public static void main(String[] args) throws Exception {
CubicCurve2D c = new CubicCurve2D.Double(50.0, 300.0,
150.0, 166.6666717529297,
238.0, 456.66668701171875,
350.0, 300.0);
Rectangle2D r = new Rectangle2D.Double(260, 300, 10, 10);
if (!c.intersects(r)) {
throw new Exception("The rectangle is contained. " +
"intersects(Rectangle2D) should return true");
}
}
public void runTest(Object ctx, int numReps) {
FillCubics.Context cctx = (FillCubics.Context) ctx;
int size = cctx.size;
// Note: 2x2 ends up hitting exactly 1 pixel...
if (size < 2) size = 2;
int x = cctx.initX;
int y = cctx.initY;
int cpoffset = (int) (size/relYmax/2);
CubicCurve2D curve = cctx.curve;
Graphics2D g2d = (Graphics2D) cctx.graphics;
g2d.translate(cctx.orgX, cctx.orgY);
Color rCArray[] = cctx.colorlist;
int ci = cctx.colorindex;
do {
curve.setCurve(x, y+size/2.0,
x+size/2.0, y+size/2.0-cpoffset,
x+size/2.0, y+size/2.0+cpoffset,
x+size, y+size/2.0);
if (rCArray != null) {
g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
}
g2d.fill(curve);
if ((x -= 3) < 0) x += cctx.maxX;
if ((y -= 1) < 0) y += cctx.maxY;
} while (--numReps > 0);
cctx.colorindex = ci;
g2d.translate(-cctx.orgX, -cctx.orgY);
}
public void runTest(Object ctx, int numReps) {
DrawCubics.Context cctx = (DrawCubics.Context) ctx;
int size = cctx.size;
// Note: 2x2 ends up hitting exactly 1 pixel...
if (size < 2) size = 2;
int x = cctx.initX;
int y = cctx.initY;
int cpoffset = (int) (size/relYmax/2);
CubicCurve2D curve = cctx.curve;
Graphics2D g2d = (Graphics2D) cctx.graphics;
g2d.translate(cctx.orgX, cctx.orgY);
Color rCArray[] = cctx.colorlist;
int ci = cctx.colorindex;
do {
curve.setCurve(x, y+size/2.0,
x+size/2.0, y+size/2.0-cpoffset,
x+size/2.0, y+size/2.0+cpoffset,
x+size, y+size/2.0);
if (rCArray != null) {
g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
}
g2d.draw(curve);
if ((x -= 3) < 0) x += cctx.maxX;
if ((y -= 1) < 0) y += cctx.maxY;
} while (--numReps > 0);
cctx.colorindex = ci;
g2d.translate(-cctx.orgX, -cctx.orgY);
}
/**
* Report whether the provided curve is below the notes (turned
* upwards) or above the notes (turned downwards).
*
* @param curve the provided curve to check
* @return true if below, false if above
*/
private static boolean isBelow (CubicCurve2D curve)
{
// Determine arc orientation (above or below)
final double DX = curve.getX2() - curve.getX1();
final double DY = curve.getY2() - curve.getY1();
final double power = (curve.getCtrlX1() * DY)
- (curve.getCtrlY1() * DX) - (curve.getX1() * DY)
+ (curve.getY1() * DX);
return power < 0;
}
public void runTest(Object ctx, int numReps) {
FillCubics.Context cctx = (FillCubics.Context) ctx;
int size = cctx.size;
// Note: 2x2 ends up hitting exactly 1 pixel...
if (size < 2) size = 2;
int x = cctx.initX;
int y = cctx.initY;
int cpoffset = (int) (size/relYmax/2);
CubicCurve2D curve = cctx.curve;
Graphics2D g2d = (Graphics2D) cctx.graphics;
g2d.translate(cctx.orgX, cctx.orgY);
Color rCArray[] = cctx.colorlist;
int ci = cctx.colorindex;
do {
curve.setCurve(x, y+size/2.0,
x+size/2.0, y+size/2.0-cpoffset,
x+size/2.0, y+size/2.0+cpoffset,
x+size, y+size/2.0);
if (rCArray != null) {
g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
}
g2d.fill(curve);
if ((x -= 3) < 0) x += cctx.maxX;
if ((y -= 1) < 0) y += cctx.maxY;
} while (--numReps > 0);
cctx.colorindex = ci;
g2d.translate(-cctx.orgX, -cctx.orgY);
}
public void runTest(Object ctx, int numReps) {
DrawCubics.Context cctx = (DrawCubics.Context) ctx;
int size = cctx.size;
// Note: 2x2 ends up hitting exactly 1 pixel...
if (size < 2) size = 2;
int x = cctx.initX;
int y = cctx.initY;
int cpoffset = (int) (size/relYmax/2);
CubicCurve2D curve = cctx.curve;
Graphics2D g2d = (Graphics2D) cctx.graphics;
g2d.translate(cctx.orgX, cctx.orgY);
Color rCArray[] = cctx.colorlist;
int ci = cctx.colorindex;
do {
curve.setCurve(x, y+size/2.0,
x+size/2.0, y+size/2.0-cpoffset,
x+size/2.0, y+size/2.0+cpoffset,
x+size, y+size/2.0);
if (rCArray != null) {
g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
}
g2d.draw(curve);
if ((x -= 3) < 0) x += cctx.maxX;
if ((y -= 1) < 0) y += cctx.maxY;
} while (--numReps > 0);
cctx.colorindex = ci;
g2d.translate(-cctx.orgX, -cctx.orgY);
}
private static Shape makeCurve(int x1, int x2, int y1, int y2, boolean forward) {
int width = x2 - x1;
if (forward) {
return new CubicCurve2D.Double(x1, y1,
x1 + width * CTRL_PROXIMITY_X, y1,
x1 + width * (1.0 - CTRL_PROXIMITY_X), y2,
x1 + width, y2);
}
else {
return new CubicCurve2D.Double(x1 + width, y2,
x1 + width * (1.0 - CTRL_PROXIMITY_X), y2,
x1 + width * CTRL_PROXIMITY_X, y1,
x1, y1);
}
}
public static void main(String[] args) throws Exception {
CubicCurve2D c = new CubicCurve2D.Double(50.0, 300.0,
150.0, 166.6666717529297,
238.0, 456.66668701171875,
350.0, 300.0);
Rectangle2D r = new Rectangle2D.Double(260, 300, 10, 10);
if (!c.intersects(r)) {
throw new Exception("The rectangle is contained. " +
"intersects(Rectangle2D) should return true");
}
}
/**
* 画随机码图
*
* @param fontColor 随机字体颜色
* @param strs 字符数组
* @param flag 透明度
* @param besselXY 干扰线参数
* @return BufferedImage
*/
private BufferedImage graphicsImage(Color[] fontColor, char[] strs, int flag, int[][] besselXY) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) image.getGraphics();
// 填充背景颜色
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
// 抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 画干扰圆圈
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f * num(10))); // 设置透明度
drawOval(2, g2d);
// 画干扰线
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f)); // 设置透明度
g2d.setStroke(new BasicStroke(1.2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
g2d.setColor(fontColor[0]);
CubicCurve2D shape = new CubicCurve2D.Double(besselXY[0][0], besselXY[0][1], besselXY[1][0], besselXY[1][1], besselXY[2][0], besselXY[2][1], besselXY[3][0], besselXY[3][1]);
g2d.draw(shape);
// 画验证码
g2d.setFont(getFont());
FontMetrics fontMetrics = g2d.getFontMetrics();
int fW = width / strs.length; // 每一个字符所占的宽度
int fSp = (fW - (int) fontMetrics.getStringBounds("W", g2d).getWidth()) / 2; // 字符的左右边距
for (int i = 0; i < strs.length; i++) {
// 设置透明度
AlphaComposite ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
g2d.setComposite(ac3);
g2d.setColor(fontColor[i]);
int fY = height - ((height - (int) fontMetrics.getStringBounds(String.valueOf(strs[i]), g2d).getHeight()) >> 1); // 文字的纵坐标
g2d.drawString(String.valueOf(strs[i]), i * fW + fSp - 3, fY - 3);
}
g2d.dispose();
return image;
}
/**
* 画随机码图
*
* @param fontColor 随机字体颜色
* @param strs 字符数组
* @param flag 透明度
* @param besselXY 干扰线参数
* @return BufferedImage
*/
private BufferedImage graphicsImage(Color[] fontColor, char[] strs, int flag, int[][] besselXY) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) image.getGraphics();
// 填充背景颜色
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
// 抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 画干扰圆圈
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f * num(10))); // 设置透明度
drawOval(2, g2d);
// 画干扰线
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f)); // 设置透明度
g2d.setStroke(new BasicStroke(1.2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
g2d.setColor(fontColor[0]);
CubicCurve2D shape = new CubicCurve2D.Double(besselXY[0][0], besselXY[0][1], besselXY[1][0], besselXY[1][1], besselXY[2][0], besselXY[2][1], besselXY[3][0], besselXY[3][1]);
g2d.draw(shape);
// 画验证码
g2d.setFont(getFont());
FontMetrics fontMetrics = g2d.getFontMetrics();
int fW = width / strs.length; // 每一个字符所占的宽度
int fSp = (fW - (int) fontMetrics.getStringBounds("W", g2d).getWidth()) / 2; // 字符的左右边距
for (int i = 0; i < strs.length; i++) {
// 设置透明度
AlphaComposite ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
g2d.setComposite(ac3);
g2d.setColor(fontColor[i]);
int fY = height - ((height - (int) fontMetrics.getStringBounds(String.valueOf(strs[i]), g2d).getHeight()) >> 1); // 文字的纵坐标
g2d.drawString(String.valueOf(strs[i]), i * fW + fSp + 3, fY - 3);
}
g2d.dispose();
return image;
}
public static void main(String[] args) throws Exception {
CubicCurve2D c = new CubicCurve2D.Double(0, 0, 4, -4, -2, -4, 2, 0);
Rectangle2D r = new Rectangle2D.Double(0.75, -2.5, 0.5, 2);
if (c.contains(r)) {
throw new Exception("The rectangle should not be contained in the curve");
}
}
public void runTest(Object ctx, int numReps) {
DrawCubics.Context cctx = (DrawCubics.Context) ctx;
int size = cctx.size;
// Note: 2x2 ends up hitting exactly 1 pixel...
if (size < 2) size = 2;
int x = cctx.initX;
int y = cctx.initY;
int cpoffset = (int) (size/relYmax/2);
CubicCurve2D curve = cctx.curve;
Graphics2D g2d = (Graphics2D) cctx.graphics;
g2d.translate(cctx.orgX, cctx.orgY);
Color rCArray[] = cctx.colorlist;
int ci = cctx.colorindex;
do {
curve.setCurve(x, y+size/2.0,
x+size/2.0, y+size/2.0-cpoffset,
x+size/2.0, y+size/2.0+cpoffset,
x+size, y+size/2.0);
if (rCArray != null) {
g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
}
g2d.draw(curve);
if ((x -= 3) < 0) x += cctx.maxX;
if ((y -= 1) < 0) y += cctx.maxY;
} while (--numReps > 0);
cctx.colorindex = ci;
g2d.translate(-cctx.orgX, -cctx.orgY);
}
public static void main(String[] args) throws Exception {
CubicCurve2D c = new CubicCurve2D.Double(0, 0, 4, -4, -2, -4, 2, 0);
Rectangle2D r = new Rectangle2D.Double(0.75, -2.5, 0.5, 2);
if (c.contains(r)) {
throw new Exception("The rectangle should not be contained in the curve");
}
}
public void runTest(Object ctx, int numReps) {
DrawCubics.Context cctx = (DrawCubics.Context) ctx;
int size = cctx.size;
// Note: 2x2 ends up hitting exactly 1 pixel...
if (size < 2) size = 2;
int x = cctx.initX;
int y = cctx.initY;
int cpoffset = (int) (size/relYmax/2);
CubicCurve2D curve = cctx.curve;
Graphics2D g2d = (Graphics2D) cctx.graphics;
g2d.translate(cctx.orgX, cctx.orgY);
Color rCArray[] = cctx.colorlist;
int ci = cctx.colorindex;
do {
curve.setCurve(x, y+size/2.0,
x+size/2.0, y+size/2.0-cpoffset,
x+size/2.0, y+size/2.0+cpoffset,
x+size, y+size/2.0);
if (rCArray != null) {
g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
}
g2d.draw(curve);
if ((x -= 3) < 0) x += cctx.maxX;
if ((y -= 1) < 0) y += cctx.maxY;
} while (--numReps > 0);
cctx.colorindex = ci;
g2d.translate(-cctx.orgX, -cctx.orgY);
}
public static Shape shapeFromSvgRelativeBezierPath(String pathString, float scalingFactor) {
String[] points = pathString.split(" ");
float x1, y1, x2, y2, cx1, cy1, cx2, cy2;
x2 = y2 = 0;
float s = scalingFactor;
Path2D.Float path = new Path2D.Float();
for (int i = 0; i < points.length / 3; ++i) {
String c1String = points[i * 3 + 0];
String c2String = points[i * 3 + 1];
String targetString = points[i * 3 + 2];
String[] c1Split = c1String.split(",");
String[] c2Split = c2String.split(",");
String[] targetSplit = targetString.split(",");
x1 = x2;
y1 = y2;
x2 = s * Float.parseFloat(targetSplit[0]) + x1;
y2 = s * Float.parseFloat(targetSplit[1]) + y1;
cx1 = s * Float.parseFloat(c1Split[0]) + x1;
cy1 = s * Float.parseFloat(c1Split[1]) + y1;
cx2 = s * Float.parseFloat(c2Split[0]) + x1;
cy2 = s * Float.parseFloat(c2Split[1]) + y1;
CubicCurve2D.Float curve = new CubicCurve2D.Float(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
path.append(curve, true);
}
return path;
}
/**
* Draws the given curve smoothly (assuming the curve is monotonic vertically)
*/
public void drawSmoothly(Curve curve) {
final int smooth = 15;
double cx = 0, cy = 0, slope;
for (int n = curve.list.size(), i = 0; i < n; i++) {
CubicCurve2D.Double c = new CubicCurve2D.Double(), c2 = (i + 1 < n) ? curve.list.get(i + 1) : null;
c.setCurve(curve.list.get(i));
if (i > 0) {
c.ctrlx1 = cx;
c.ctrly1 = cy;
}
if (c2 == null) {
draw(c, false);
return;
}
if ((c.x1 < c.x2 && c2.x2 < c2.x1) || (c.x1 > c.x2 && c2.x2 > c2.x1))
slope = 0;
else
slope = (c2.x2 - c.x1) / (c2.y2 - c.y1);
double tmp = c.y2 - smooth, tmpx = c.x2 - smooth * slope;
if (tmp > c.ctrly1 && tmp < c.y2 && in(c.x1, tmpx, c.x2)) {
c.ctrly2 = tmp;
c.ctrlx2 = tmpx;
}
double tmp2 = c2.y1 + smooth, tmp2x = c2.x1 + smooth * slope;
if (tmp2 > c2.y1 && tmp2 < c2.ctrly2 && in(c2.x1, tmp2x, c2.x2)) {
cy = tmp2;
cx = tmp2x;
} else {
cy = c2.ctrly1;
cx = c2.ctrlx1;
}
draw(c, false);
}
}
public void runTest(Object ctx, int numReps) {
DrawCubics.Context cctx = (DrawCubics.Context) ctx;
int size = cctx.size;
// Note: 2x2 ends up hitting exactly 1 pixel...
if (size < 2) size = 2;
int x = cctx.initX;
int y = cctx.initY;
int cpoffset = (int) (size/relYmax/2);
CubicCurve2D curve = cctx.curve;
Graphics2D g2d = (Graphics2D) cctx.graphics;
g2d.translate(cctx.orgX, cctx.orgY);
Color rCArray[] = cctx.colorlist;
int ci = cctx.colorindex;
do {
curve.setCurve(x, y+size/2.0,
x+size/2.0, y+size/2.0-cpoffset,
x+size/2.0, y+size/2.0+cpoffset,
x+size, y+size/2.0);
if (rCArray != null) {
g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
}
g2d.draw(curve);
if ((x -= 3) < 0) x += cctx.maxX;
if ((y -= 1) < 0) y += cctx.maxY;
} while (--numReps > 0);
cctx.colorindex = ci;
g2d.translate(-cctx.orgX, -cctx.orgY);
}
protected void paintEdges(Graphics g, Tree parent) {
if (!getTree().isLeaf(parent)) {
BasicStroke stroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND);
((Graphics2D)g).setStroke(stroke);
Rectangle2D.Double parentBounds = getBoundsOfNode(parent);
double x1 = parentBounds.getCenterX();
double y1 = parentBounds.getMaxY();
for (Tree child : getTree().getChildren(parent)) {
Rectangle2D.Double childBounds = getBoundsOfNode(child);
double x2 = childBounds.getCenterX();
double y2 = childBounds.getMinY();
if (getUseCurvedEdges()) {
CubicCurve2D c = new CubicCurve2D.Double();
double ctrlx1 = x1;
double ctrly1 = (y1+y2)/2;
double ctrlx2 = x2;
double ctrly2 = y1;
c.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
((Graphics2D) g).draw(c);
} else {
g.drawLine((int) x1, (int) y1,
(int) x2, (int) y2);
}
paintEdges(g, child);
}
}
}
public static void main(String[] args) throws Exception {
CubicCurve2D c = new CubicCurve2D.Double(50.0, 300.0,
150.0, 166.6666717529297,
238.0, 456.66668701171875,
350.0, 300.0);
Rectangle2D r = new Rectangle2D.Double(260, 300, 10, 10);
if (!c.intersects(r)) {
throw new Exception("The rectangle is contained. " +
"intersects(Rectangle2D) should return true");
}
}
void bendUp(double x, double y1, double y2, double gap) {
for (int i = 0; i < list.size(); i++) {
CubicCurve2D.Double c = list.get(i);
if (intersects(c.x1, c.y1, c.x2, c.y2, x, y1, y2)) {
list.set(i, makeline(c.x1, c.y1, x, y1 - gap));
list.add(i + 1, makeline(x, y1 - gap, c.x2, c.y2));
return;
}
}
}