Drawing Smooth Curves in Java Graphics
Solution 1
You need to enable antaliasing for Graphics2D object.
Do it like this
Graphics graphics = ...
Graphics2D g2d = (Graphics2D) graphics;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// You can also enable antialiasing for text:
g2d.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
Do this before drawing anything using the graphics
object.
Also see the RenderingHints javadoc.
Solution 2
Use the Graphics2D
with the antialising:
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//...
g2.draw(gp);
stk1234
Updated on June 04, 2022Comments
-
stk1234 almost 2 years
I am trying to draw smooth, bezier-type curves to fit a set of data I have in order to plot it in a java graphics drawing. Below is the code I am currently using to plot. It is plotting the points just fine, except that the curves have sharp edges and sometimes have small fractures in them. Is there a better way that I can make a smooth, fitted curve using java graphics?
int numProfiles = speedList.size(); int lenOfList; System.out.println(); System.out.println("Creating a new general path"); //BasicStroke boldStroke = new BasicStroke(.3f); //((Graphics2D)g).setStroke(boldStroke); for (int i=0; i<numProfiles; i++){ GeneralPath gp = new GeneralPath(); g.setColor(colors[i]); lenOfList = speedList.get(i).length; if (lenOfList < 3) { double xPlotVal1 = xMarginLeft + (((speedList.get(i)[0].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal1 = yMarginTopAxisTop + (((depthList.get(i)[0].getVal() - yMin) / (yMax - yMin)) * height); double xPlotVal2 = xMarginLeft + (((speedList.get(i)[1].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal2 = yMarginTopAxisTop + (((depthList.get(i)[1].getVal() - yMin) / (yMax - yMin)) * height); g.drawLine((int) xPlotVal1, (int) yPlotVal1, (int) xPlotVal2, (int) yPlotVal2); } else { System.out.println("More than 2 pts"); for (int j = 0; j < (lenOfList - 2); j++) { double xPlotVal1 = xMarginLeft + (((speedList.get(i)[j].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal1 = yMarginTopAxisTop + (((depthList.get(i)[j].getVal() - yMin) / (yMax - yMin)) * height); double xPlotVal2 = xMarginLeft + (((speedList.get(i)[j + 1].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal2 = yMarginTopAxisTop + (((depthList.get(i)[j + 1].getVal() - yMin) / (yMax - yMin)) * height); double xPlotVal3 = xMarginLeft + (((speedList.get(i)[j + 2].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal3 = yMarginTopAxisTop + (((depthList.get(i)[j + 2].getVal() - yMin) / (yMax - yMin)) * height); gp.moveTo(xPlotVal1, yPlotVal1); if (j==0) gp.moveTo(xPlotVal1, yPlotVal1); // gp.moveTo(xPlotVal1, yPlotVal1); gp.curveTo(xPlotVal1, yPlotVal1, xPlotVal2, yPlotVal2, xPlotVal3, yPlotVal3); } ((Graphics2D) g).draw(gp); } }
Here is a picture of what it's drawing:
//June 26, 2012 at 7:34AM //Here is the updated code after I added the rendering hint
// the profiles Graphics2D g2d = (Graphics2D)g; int numProfiles = speedList.size(); int lenOfList; for (int i=0; i<numProfiles; i++){ GeneralPath gp = new GeneralPath(); g2d.setColor(colors[i]); lenOfList = speedList.get(i).length; if (lenOfList < 3) { double xPlotVal1 = xMarginLeft + (((speedList.get(i)[0].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal1 = yMarginTopAxisTop + (((depthList.get(i)[0].getVal() - yMin) / (yMax - yMin)) * height); double xPlotVal2 = xMarginLeft + (((speedList.get(i)[1].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal2 = yMarginTopAxisTop + (((depthList.get(i)[1].getVal() - yMin) / (yMax - yMin)) * height); g2d.drawLine((int) xPlotVal1, (int) yPlotVal1, (int) xPlotVal2, (int) yPlotVal2); } else { for (int j = 0; j < (lenOfList - 2); j++) { double xPlotVal1 = xMarginLeft + (((speedList.get(i)[j].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal1 = yMarginTopAxisTop + (((depthList.get(i)[j].getVal() - yMin) / (yMax - yMin)) * height); double xPlotVal2 = xMarginLeft + (((speedList.get(i)[j + 1].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal2 = yMarginTopAxisTop + (((depthList.get(i)[j + 1].getVal() - yMin) / (yMax - yMin)) * height); double xPlotVal3 = xMarginLeft + (((speedList.get(i)[j + 2].getVal() - xMin) / (xMax - xMin)) * width); double yPlotVal3 = yMarginTopAxisTop + (((depthList.get(i)[j + 2].getVal() - yMin) / (yMax - yMin)) * height); gp.moveTo(xPlotVal1, yPlotVal1); if (j==0) gp.moveTo(xPlotVal1, yPlotVal1); //only move at the begining of the curve drawing // gp.moveTo(xPlotVal1, yPlotVal1); gp.curveTo(xPlotVal1, yPlotVal1, xPlotVal2, yPlotVal2, xPlotVal3, yPlotVal3); } g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.draw(gp); } }
Here is the newest picture. I am not sure why it's making my background grid lines disappear. I plot the grid lines after I plot the colored profiles.
-
stk1234 almost 12 yearsHmm. I tried the Rendering Hint code and it is still drawing the same picture.
-
npe almost 12 yearsPost the updated code, perhaps your enabling the hints too late, or on the wrong object. And post your java version too.
-
stk1234 almost 12 yearsOk, just posted the updated version in my original post below the first try at the code.
-
npe almost 12 yearsWell, I can see the difference on the new image - the lines are slightly smoother. As to the gridlines - they are visible, but are really faint, you may want to disable anti-aliasing for them (using
setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_OFF)
. -
stk1234 almost 12 yearsOkay, awesome. The grid lines are back. The curves are smoother--but there is still that sharp corner with the pink one and the hairline split in the green one.
-
npe almost 12 yearsI'd say, that's because of how your path is build. It just contains those points.