下面列出了怎么用java.awt.geom.Path2D的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Create a thin (1 mm wide) rectangle path representing a line.
*
* @param line the line.
* @return rectangle path for the line.
*/
private static Path2D createLinePath(Line2D line) {
// Make rectangle width 1mm.
double width = .001D;
double length = line.getP1().distance(line.getP2());
double centerX = (line.getX1() + line.getX2()) / 2D;
double centerY = (line.getY1() + line.getY2()) / 2D;
double x1 = centerX - (width / 2D);
double y1 = centerY - (length / 2D);
Rectangle2D lineRect = new Rectangle2D.Double(x1, y1, width, length);
double facing = getDirection(line.getP1(), line.getP2());
Path2D rectPath = getPathFromRectangleRotation(lineRect, facing);
return rectPath;
}
static void testAddQuad(Path2D pathA, boolean isEmpty) {
try {
addQuads(pathA);
}
catch (IllegalPathStateException ipse) {
if (isEmpty) {
log("testAddQuad: passed "
+ "(expected IllegalPathStateException catched).");
return;
} else {
throw ipse;
}
}
if (isEmpty) {
throw new IllegalStateException("IllegalPathStateException not thrown !");
}
log("testAddQuad: passed.");
}
private void renderNorthArrow(double[] pt0,double[] pt1){
//
double
da=GD.getDirection_PointPoint(pt0[0],pt0[1],pt1[0],pt1[1]),
dright=GD.normalizeDirection(da+GD.HALFPI),
dleft=GD.normalizeDirection(da-GD.HALFPI);
double[]
p0=GD.getPoint_PointDirectionInterval(pt0[0],pt0[1],da,ARROWOFFSET0),
p1=GD.getPoint_PointDirectionInterval(p0[0],p0[1],da,ARROWSHAFTLENGTH),
p2=GD.getPoint_PointDirectionInterval(p1[0],p1[1],da,ARROWHEADLENGTH),
pleft=GD.getPoint_PointDirectionInterval(p1[0],p1[1],dleft,ARROWHEADWIDTH),
pright=GD.getPoint_PointDirectionInterval(p1[0],p1[1],dright,ARROWHEADWIDTH);
Path2D path=new Path2D.Double();
path.moveTo(p0[0],p0[1]);
path.lineTo(p1[0],p1[1]);
graphics.setStroke(createStroke(STROKETHICKNESS2*imagescale));
graphics.draw(path);
path=new Path2D.Double();
path.moveTo(p2[0],p2[1]);
path.lineTo(pleft[0],pleft[1]);
path.lineTo(pright[0],pright[1]);
path.closePath();
graphics.fill(path);}
static void testAddCubic(Path2D pathA, boolean isEmpty) {
try {
addCubics(pathA);
}
catch (IllegalPathStateException ipse) {
if (isEmpty) {
log("testAddCubic: passed "
+ "(expected IllegalPathStateException catched).");
return;
} else {
throw ipse;
}
}
if (isEmpty) {
throw new IllegalStateException("IllegalPathStateException not thrown !");
}
log("testAddCubic: passed.");
}
static void testAddCubic(Path2D pathA, boolean isEmpty) {
try {
addCubics(pathA);
}
catch (IllegalPathStateException ipse) {
if (isEmpty) {
log("testAddCubic: passed "
+ "(expected IllegalPathStateException catched).");
return;
} else {
throw ipse;
}
}
if (isEmpty) {
throw new IllegalStateException("IllegalPathStateException not thrown !");
}
log("testAddCubic: passed.");
}
private GeneralPath getShape(int index) {
Random r = new Random(index * 100000);
GeneralPath path = new GeneralPath(
r.nextBoolean() ? Path2D.WIND_EVEN_ODD : Path2D.WIND_NON_ZERO);
path.moveTo(r.nextFloat() * 100, r.nextFloat() * 100);
for (int a = 0; a < 3; a++) {
int k;
if (type.getSelectedIndex() == 0) {
k = r.nextInt(3);
} else {
k = type.getSelectedIndex() - 1;
}
if (k == 0) {
path.lineTo(r.nextFloat() * 100, r.nextFloat() * 100);
} else if (k == 1) {
path.quadTo(r.nextFloat() * 100, r.nextFloat() * 100,
r.nextFloat() * 100, r.nextFloat() * 100);
} else {
path.curveTo(r.nextFloat() * 100, r.nextFloat() * 100,
r.nextFloat() * 100, r.nextFloat() * 100,
r.nextFloat() * 100, r.nextFloat() * 100);
}
}
return path;
}
@Override
public void draw(DrawRequest r) {
Graphics2D g = r.getGraphics();
Decoration d = r.getDecoration();
Path2D shape = new Path2D.Double();
float w = (float) strokeWidth / 4.0f;
if (spanningTree == null) {
HashSet<Point2D> points = new HashSet<>();
Collection<VisualBundledTransition> transitions = ((VisualPolicy) r.getModel()).getTransitionsOfBundle(this);
for (VisualBundledTransition t: transitions) {
Point2D point = TransformHelper.getTransformToRoot(t).transform(t.getCenter(), null);
points.add(point);
}
spanningTree = buildSpanningTree(points);
}
for (Line2D l: spanningTree) {
shape.moveTo(l.getX1(), l.getY1());
shape.lineTo(l.getX2(), l.getY2());
}
g.setColor(ColorUtils.colorise(color, d.getColorisation()));
g.setStroke(new BasicStroke(w, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 1.0f, new float[]{10 * w, 10 * w}, 0.0f));
g.draw(shape);
}
private void renderArrowHead(Graphics2D graphics,GlyphSystemModel glyphsystemmodel,Color color){
graphics.setPaint(color);
DPoint
p0=glyphsystemmodel.glyphpath.get(glyphsystemmodel.glyphpath.size()-2),
p1=glyphsystemmodel.glyphpath.get(glyphsystemmodel.glyphpath.size()-1);
double forward=p0.getDirection(p1);
DPoint
forewardpoint=p1.getPoint(
forward,
UI.EDITJIG_EDITSECTIONS_GLYPHARROWLENGTH*UI.EDITJIG_EDITSECTIONS_GLYPHINSET),
leftpoint=p1.getPoint(
GD.normalizeDirection(forward-GD.HALFPI),
UI.EDITJIG_EDITSECTIONS_GLYPHARROWWIDTH*UI.EDITJIG_EDITSECTIONS_GLYPHINSET/2),
rightpoint=p1.getPoint(
GD.normalizeDirection(forward+GD.HALFPI),
UI.EDITJIG_EDITSECTIONS_GLYPHARROWWIDTH*UI.EDITJIG_EDITSECTIONS_GLYPHINSET/2);
Path2D triangle=new Path2D.Double();
triangle.moveTo(leftpoint.x,leftpoint.y);
triangle.lineTo(forewardpoint.x,forewardpoint.y);
triangle.lineTo(rightpoint.x,rightpoint.y);
triangle.closePath();
graphics.fill(triangle);}
void doShape(SunGraphics2D sg2d, Shape s, boolean isfill) {
Path2D.Float p2df;
int transX;
int transY;
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
if (s instanceof Path2D.Float) {
p2df = (Path2D.Float)s;
} else {
p2df = new Path2D.Float(s);
}
transX = sg2d.transX;
transY = sg2d.transY;
} else {
p2df = new Path2D.Float(s, sg2d.transform);
transX = 0;
transY = 0;
}
try {
doShape((GDIWindowSurfaceData)sg2d.surfaceData,
sg2d.getCompClip(), sg2d.composite, sg2d.eargb,
transX, transY, p2df, isfill);
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
}
private Path2D decodePath3() {
path.reset();
path.moveTo(decodeX(0.0f), decodeY(1.3333334f));
path.curveTo(decodeAnchorX(0.0f, 2.678571428571433f), decodeAnchorY(1.3333333730697632f, 8.881784197001252E-16f), decodeAnchorX(1.3678570985794067f, -6.214285714285715f), decodeAnchorY(0.20714285969734192f, -0.03571428571428292f), decodeX(1.3678571f), decodeY(0.20714286f));
path.lineTo(decodeX(1.5642858f), decodeY(0.20714286f));
path.curveTo(decodeAnchorX(1.5642857551574707f, 8.329670329670357f), decodeAnchorY(0.20714285969734192f, 0.002747252747249629f), decodeAnchorX(2.5999999046325684f, -5.2857142857142705f), decodeAnchorY(1.3333333730697632f, 0.03571428571428559f), decodeX(2.6f), decodeY(1.3333334f));
path.lineTo(decodeX(3.0f), decodeY(1.3333334f));
path.lineTo(decodeX(3.0f), decodeY(1.6666667f));
path.lineTo(decodeX(2.6f), decodeY(1.6666667f));
path.curveTo(decodeAnchorX(2.5999999046325684f, -5.321428571428569f), decodeAnchorY(1.6666667461395264f, 0.0357142857142847f), decodeAnchorX(1.5642857551574707f, 8.983516483516496f), decodeAnchorY(2.799999952316284f, 0.03846153846153122f), decodeX(1.5642858f), decodeY(2.8f));
path.lineTo(decodeX(1.3892857f), decodeY(2.8f));
path.curveTo(decodeAnchorX(1.389285683631897f, -6.714285714285704f), decodeAnchorY(2.799999952316284f, 0.0f), decodeAnchorX(0.0f, 2.6071428571428568f), decodeAnchorY(1.6666667461395264f, 0.03571428571428559f), decodeX(0.0f), decodeY(1.6666667f));
path.lineTo(decodeX(0.0f), decodeY(1.3333334f));
path.closePath();
return path;
}
private static Path2D.Double nearestNeighbour(double[] scaledX, double[] scaledY) {
Path2D.Double line = new Path2D.Double();
line.moveTo(scaledX[0], scaledY[0]);
for (int i = 1; i < scaledY.length; i++) {
double halfX = scaledX[i - 1] + (scaledX[i] - scaledX[i - 1]) / 2;
if (!java.lang.Double.isNaN(scaledY[i-1])) {
line.lineTo(halfX, scaledY[i - 1]);
if (!java.lang.Double.isNaN(scaledY[i]))
line.lineTo(halfX, scaledY[i]);
} else {
line.moveTo(halfX, scaledY[i]);
}
}
line.lineTo(scaledX[scaledX.length - 1], scaledY[scaledY.length - 1]);
return line;
}
public int getRegion(double x, double y) {
int stx = getXIndex(x);
int sty = getYIndex(y);
if(stx >= xs) {
stx = xs - 1;
}
if(sty >= ys) {
sty = ys - 1;
}
if(stx < 0) {
stx = 0;
}
if(sty < 0) {
sty = 0;
}
for(int p: grid[stx][sty].polys) {
Path2D.Double poly = polygons.get(p);
if(poly.contains(x, y)) {
return p;
}
}
return -1;
}
static void testGetBounds(Path2D pathA, Path2D pathB) {
final Rectangle rA = pathA.getBounds();
final Rectangle rB = pathB.getBounds();
if (!rA.equals(rB)) {
throw new IllegalStateException("Bounds are not equals [" + rA
+ "|" + rB + "] !");
}
final Rectangle2D r2dA = pathA.getBounds2D();
final Rectangle2D r2dB = pathB.getBounds2D();
if (!equalsRectangle2D(r2dA, r2dB)) {
throw new IllegalStateException("Bounds2D are not equals ["
+ r2dA + "|" + r2dB + "] !");
}
log("testGetBounds: passed.");
}
static void testAddQuad(Path2D pathA, boolean isEmpty) {
try {
addQuads(pathA);
}
catch (IllegalPathStateException ipse) {
if (isEmpty) {
log("testAddQuad: passed "
+ "(expected IllegalPathStateException catched).");
return;
} else {
throw ipse;
}
}
if (isEmpty) {
throw new IllegalStateException("IllegalPathStateException not thrown !");
}
log("testAddQuad: passed.");
}
private void renderBracket(double[] pt0,double[] pt1){
double
dforeward=GD.getDirection_PointPoint(pt0[0],pt0[1],pt1[0],pt1[1]),
dbackward=GD.normalizeDirection(dforeward-GD.PI),
dout=GD.normalizeDirection(dforeward+GD.HALFPI);
double[]
b0p0=GD.getPoint_PointDirectionInterval(pt0[0],pt0[1],dout,FISHBRACKETOFFSET),
b0p1=GD.getPoint_PointDirectionInterval(b0p0[0],b0p0[1],dout,FISHBRACKETSPAN0),
b0p2=GD.getPoint_PointDirectionInterval(b0p1[0],b0p1[1],dforeward,FISHBRACKETSPAN1),
b1p0=GD.getPoint_PointDirectionInterval(pt1[0],pt1[1],dout,FISHBRACKETOFFSET),
b1p1=GD.getPoint_PointDirectionInterval(b1p0[0],b1p0[1],dout,FISHBRACKETSPAN0),
b1p2=GD.getPoint_PointDirectionInterval(b1p1[0],b1p1[1],dbackward,FISHBRACKETSPAN1);
//
graphics.setStroke(createStroke(STROKETHICKNESS2*imagescale));
Path2D path=new Path2D.Double();
path.moveTo(b0p0[0],b0p0[1]);
path.lineTo(b0p1[0],b0p1[1]);
path.lineTo(b0p2[0],b0p2[1]);
graphics.draw(path);
path=new Path2D.Double();
path.moveTo(b1p0[0],b1p0[1]);
path.lineTo(b1p1[0],b1p1[1]);
path.lineTo(b1p2[0],b1p2[1]);
graphics.draw(path);
}
public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
int transx, int transy,
Path2D.Float p2df)
{
PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
ProcessPath.drawPath(
new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
sg2d.strokeHint),
p2df, transx, transy
);
}
@Before
public void setUp() throws Exception {
// Draw a "Z"
path = new Path2D.Double();
path.moveTo(0, 0);
path.lineTo(3, 0);
path.lineTo(0, 3);
path.lineTo(3, 3);
product = new Product("p", "t", 4, 4);
band = product.addBand("b", "4 * (Y-0.5) + (X-0.5) + 0.1");
dataSourceConfig = new ProfilePlotPanel.DataSourceConfig();
SimpleFeatureTypeBuilder ftb = new SimpleFeatureTypeBuilder();
ftb.setName("ft");
ftb.add("lat", Double.class);
ftb.add("lon", Double.class);
ftb.add("data", Double.class);
SimpleFeatureType ft = ftb.buildFeatureType();
DefaultFeatureCollection fc = new DefaultFeatureCollection("id", ft);
fc.add(new SimpleFeatureImpl(new Object[]{0, 0, 0.3}, ft, new FeatureIdImpl("id1"), false));
fc.add(new SimpleFeatureImpl(new Object[]{0, 0, 0.5}, ft, new FeatureIdImpl("id2"), false));
fc.add(new SimpleFeatureImpl(new Object[]{0, 0, 0.7}, ft, new FeatureIdImpl("id3"), false));
fc.add(new SimpleFeatureImpl(new Object[]{0, 0, 0.1}, ft, new FeatureIdImpl("id4"), false));
dataSourceConfig.pointDataSource = new VectorDataNode("vd", fc);
dataSourceConfig.dataField = ft.getDescriptor("data");
dataSourceConfig.boxSize = 1;
dataSourceConfig.computeInBetweenPoints = true;
}
private Path2D getCurrentSubPath() {
if (subPaths_.isEmpty()) {
final Path2D subPath = new Path2D.Double();
subPaths_.add(subPath);
return subPath;
}
return subPaths_.get(subPaths_.size() - 1);
}
static void testEqual(Path2D pathA, Path2D pathB) {
final PathIterator itA = pathA.getPathIterator(null);
final PathIterator itB = pathB.getPathIterator(null);
float[] coordsA = new float[6];
float[] coordsB = new float[6];
int n = 0;
for (; !itA.isDone() && !itB.isDone(); itA.next(), itB.next(), n++) {
int typeA = itA.currentSegment(coordsA);
int typeB = itB.currentSegment(coordsB);
if (typeA != typeB) {
throw new IllegalStateException("Path-segment[" + n + "] "
+ " type are not equals [" + typeA + "|" + typeB + "] !");
}
if (!equalsArray(coordsA, coordsB, getLength(typeA))) {
throw new IllegalStateException("Path-segment[" + n + "] coords"
+ " are not equals [" + Arrays.toString(coordsA) + "|"
+ Arrays.toString(coordsB) + "] !");
}
}
if (!itA.isDone() || !itB.isDone()) {
throw new IllegalStateException("Paths do not have same lengths !");
}
log("testEqual: " + n + " segments.");
}
/**
Turn a list of coordinates into a shape.
@param coords The coordinates.
@return A new shape.
*/
public static Shape coordsToShape(List<GMLCoordinates> coords) {
Path2D path = new Path2D.Double();
Iterator<GMLCoordinates> it = coords.iterator();
GMLCoordinates c = it.next();
path.moveTo(c.getX(), c.getY());
while (it.hasNext()) {
c = it.next();
path.lineTo(c.getX(), c.getY());
}
path.closePath();
return path;
}
public void FillPath(SunGraphics2D sg2d, SurfaceData sData,
int transX, int transY,
Path2D.Float p2df)
{
tracePrimitive(target);
target.FillPath(sg2d, sData, transX, transY, p2df);
}
public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
int transx, int transy, Path2D.Float p2df)
{
PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
ProcessPath.drawPath(
new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
sg2d.strokeHint),
p2df, transx, transy
);
}
public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
int transx, int transy, Path2D.Float p2df)
{
PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
ProcessPath.drawPath(
new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
sg2d.strokeHint),
p2df, transx, transy
);
}
public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
int transX, int transY,
Path2D.Float p2df)
{
tracePrimitive(target);
target.DrawPath(sg2d, sData, transX, transY, p2df);
}
@Override
public void execute(Path2D.Double path, Context ctx){
double x1 = ctx.getValue(arg1);
double y1 = ctx.getValue(arg2);
double x2 = ctx.getValue(arg3);
double y2 = ctx.getValue(arg4);
double x3 = ctx.getValue(arg5);
double y3 = ctx.getValue(arg6);
path.curveTo(x1, y1, x2, y2, x3, y3);
}
private Path2D.Double createPath() {
Random r = new Random(0);
int numberOfSegments = 20;
Path2D.Double p = new Path2D.Double();
p.moveTo(1000 * r.nextFloat(), 1000 * r.nextFloat());
for (int b = 0; b < numberOfSegments; b++) {
p.curveTo(1000 * r.nextFloat(), 1000 * r.nextFloat(),
1000 * r.nextFloat(), 1000 * r.nextFloat(),
1000 * r.nextFloat(), 1000 * r.nextFloat());
}
p.closePath();
return p;
}
public static boolean fillPath(DrawHandler dhnd, Path2D.Float p2df,
int transX, int transY)
{
FillProcessHandler fhnd = new FillProcessHandler(dhnd);
if (!doProcessPath(fhnd, p2df, transX, transY)) {
return false;
}
FillPolygon(fhnd, p2df.getWindingRule());
return true;
}
/**
* Draws a smooth curve through the given array of points.
*
* <p>This algorithm is called Spline-Interpolation because the Apache-commons-math library we are
* using here does not accept values but {@code f(x)=y} with x having to increase all the time the
* idea behind this is to use a parameter array - the so called index as x array and splitting the
* points into a x and y coordinates array.
*
* <p>Finally those 2 interpolated arrays get unified into a single {@linkplain Point2D} array and
* drawn to the Map
*
* @param graphics The {@linkplain Graphics2D} Object to be drawn on
* @param points The Knot Points for the Spline-Interpolator aka the joints
*/
private void drawCurvedPath(final Graphics2D graphics, final Point2D[] points) {
final double[] index = newParameterizedIndex(points);
final PolynomialSplineFunction xcurve =
splineInterpolator.interpolate(index, getValues(points, Point2D::getX));
final double[] xcoords = getCoords(xcurve, index);
final PolynomialSplineFunction ycurve =
splineInterpolator.interpolate(index, getValues(points, Point2D::getY));
final double[] ycoords = getCoords(ycurve, index);
final List<Path2D> paths = routeCalculator.getAllNormalizedLines(xcoords, ycoords);
for (final Path2D path : paths) {
drawTransformedShape(graphics, path);
}
// draws the Line to the Cursor on every possible screen, so that the line ends at the cursor no
// matter what...
final List<Point2D[]> finishingPoints =
routeCalculator.getAllPoints(
new Point2D.Double(xcoords[xcoords.length - 1], ycoords[ycoords.length - 1]),
points[points.length - 1]);
final boolean hasArrowEnoughSpace =
points[points.length - 2].distance(points[points.length - 1]) > ARROW_LENGTH;
for (final Point2D[] finishingPointArray : finishingPoints) {
drawTransformedShape(
graphics, new Line2D.Double(finishingPointArray[0], finishingPointArray[1]));
if (hasArrowEnoughSpace) {
drawArrow(graphics, finishingPointArray[0], finishingPointArray[1]);
}
}
}
/**
* {@inheritDoc}
*/
public void clip(final RenderingBackend.WindingRule windingRule,
final com.gargoylesoftware.htmlunit.javascript.host.canvas.Path2D path) {
if (LOG.isDebugEnabled()) {
LOG.debug("[" + id_ + "] clip(" + windingRule + ", " + path + ")");
}
if (path == null && subPaths_.isEmpty()) {
graphics2D_.setClip(null);
return;
}
final Path2D currentPath;
if (path == null) {
currentPath = subPaths_.get(subPaths_.size() - 1);
}
else {
// currentPath = path.getPath2D();
currentPath = null;
}
currentPath.closePath();
switch (windingRule) {
case NON_ZERO:
currentPath.setWindingRule(Path2D.WIND_NON_ZERO);
break;
default:
currentPath.setWindingRule(Path2D.WIND_EVEN_ODD);
break;
}
graphics2D_.clip(currentPath);
}
/**
* A List of Lines which represent all possible lines on multiple screens size may vary.
*
* @param xcoords an array of xCoordinates
* @param ycoords an array of yCoordinates
* @return a List of corresponding Lines on every possible screen
*/
public List<Path2D> getAllNormalizedLines(final double[] xcoords, final double[] ycoords) {
final Path2D path = getNormalizedLines(xcoords, ycoords);
return MapScrollUtil.getPossibleTranslations(isInfiniteX, isInfiniteY, mapWidth, mapHeight)
.stream()
.map(t -> new Path2D.Double(path, t))
.collect(Collectors.toList());
}