How to Draw a Continuous Line on Java

I am writing a 2D traditional animation program in Java using swing and JPen. The application works well. However, i am dissatisfied with the results I am getting when I draw lines.

when drawing, the line seems to "rotating" as you move from one point to another.  It then produces the annoying effect you see where the line appears non continuous.  Note.

Using the JPen API, the swing panel listens for the stylus input and its code is:

                      /**  * This method is called whenever the stylus makes contact with the tablet while inside of the JPanel functioning  * as the Drawing Canvas.  * @param evt  */ public void penLevelEvent(PLevelEvent evt) {     // Get kind of event: does it come from mouse (CURSOR), STYLUS or ERASER?     PKind kind = evt.pen.getKind();      // Discard events from mouse     if (kind == PKind.valueOf(PKind.Type.CURSOR)){         //System.out.println("returning since this is only a mouse cursor");        return;      }       // Get the current cursor location     // position value is in with respect to entire application window     // Get the tilt values (not with a Bamboo... so untested!)     float curX      = evt.pen.getLevelValue(PLevel.Type.X);     float curY      = evt.pen.getLevelValue(PLevel.Type.Y);     float pressure  = evt.pen.getLevelValue(PLevel.Type.PRESSURE);// 0.0 - 1.0     float xTilt     = evt.pen.getLevelValue(PLevel.Type.TILT_X);     float yTilt     = evt.pen.getLevelValue(PLevel.Type.TILT_Y);      // Set the brush's size, and darkness relative to the pressure     float darkness = 255 * pressure;       // Transform them to azimuthX and altitude, two angles with the projection of the pen against the X-Y plane     // azimuthX is the angle (clockwise direction) between this projection and the X axis. Range: -pi/2 to 3*pi/2.     // altitude is the angle between this projection and the pen itself. Range: 0 to pi/2.     // Might be more pratical to use than raw x/y tilt values.     double[] aa = { 0.0, 0.0 };     PLevel.Type.evalAzimuthXAndAltitude(aa, xTilt, yTilt);     // or just PLevel.Type.evalAzimuthXAndAltitude(aa, evt.pen);     double azimuthX = aa[0];     double altitude = aa[1];      //-------------------------------------------------------------------------------------     // If the stylus is being pressed down, we want to draw a black     // line onto the screen. If it's the eraser, we want to create     // a white line, effectively "erasing" the black line     //-------------------------------------------------------------------------------------     if (kind == PKind.valueOf(PKind.Type.STYLUS)) {         //System.out.println("Darkness "+darkness);         int alpha = 255 - (int)darkness;         color = new Color(0,0,255,  255 - alpha);     }     else if (kind == PKind.valueOf(PKind.Type.ERASER)) {         System.out.println("Handle eraser");     }     else {         return; // IGNORE or CUSTOM...     }      //If movement of the stylus is occuring     if (evt.isMovement()) {         //and the buttonIsDown(boolean)         if(buttonIsDown) {             //drawingCanvas:JPanel -> instruct the jpanel to draw at the following coordinate using the specified pressure             drawingCanvas.stylusMovementInput( prevXPos,prevYPos, curX,curY, pressure);         }         prevXPos = curX;         prevYPos = curY;     }      prevXPos = curX;     prevYPos = curY;  }                  

So after the above method is invoked, the jpanel(drawingCanvas) starts to draw on a BufferedImage by obtaining the image's graphics2D. Here is the code stylusMovementInput->calls -> performDrawOnBufferImageGraphic2D :

          /**  * Draw on the active frame that is selected.  Then call channel refresh, to refresh the the composite image derived  * from call changes related to the current frame  * @param cX current  * @param cY current  * @param oX previous  * @param oY previous  * @param pressure pressure 0 - 1f  */ private void performDrawOnBufferImageGraphic2D(float oX, float oY, float cX, float cY, float pressure){     //Obtain the current layer that user wants to draw one     //MyImageData is encapsulating a BufferedImage     MyImageData $activeData = getActiveLayer();     //Exit if one is not valid     if( $activeData == null) return;     //if valid layer, get the, get the bufferedImage.getGraphics     Graphics2D $activeDataGFX = $activeData.getImageGraphics();       // Customize the drawing brush (create a BasicStroke)     Stroke thickness = Sys.makeStroke(getPencilSize(pressure), null);     // Determine the tranparency with respect to the pressure     int alpha = (int)(255 * pressure * getPencilOpacityPercentage());     // Get the current color found in the color wheel     Color cwVal = Sys.getColorFromColorWheel();      Color drawingColor ;     if(cwVal != null){         // add alpha value to it         drawingColor = new Color(cwVal.getRed(), cwVal.getGreen(), cwVal.getBlue(), alpha);      }else throw new RuntimeException("ColorWheel is null drawing stylus draw");      //set the brush and drawingColor     $activeDataGFX.setStroke(thickness);      // Save reference to the current bufferedImage graphic component     Composite originalComposite =$activeDataGFX.getComposite();     if(getCurrentTool() == DrawingCanvasTool.ERASER){         //If eraser,  set new composite information, to allow erasing to transparency         $activeDataGFX.setPaint( new Color(255,255,255, 0));         $activeDataGFX.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 0.0f));     }else {         //set the drawing color         $activeDataGFX.setPaint(drawingColor);     }       //---------------------------------------------------------------     // Rotate, Translate, Zoom the image according to the panning, zoom, and rotate     // set by the user     //---------------------------------------------------------------     //Figure out the canvas center, as it is used for rotating     float theta  = (float)Math.toRadians(canvasRotation);     Dimension drawingAreaComponentSize = getSize();     float centerX = drawingAreaComponentSize.width/2;     float centerY = drawingAreaComponentSize.height/2;     AffineTransform transform = new AffineTransform();     transform.rotate(-theta, centerX, centerY);     transform.scale(1.0f / canvasZoom, 1.0f / canvasZoom);//erase     transform.translate(-canvasPan.x, -canvasPan.y);//erase     $activeDataGFX.setTransform(transform);       //Now Draw inside of the active data graphics object       Shape line = new Line2D.Float(cX,cY, oX, oY);     Path2D.Float t = new Path2D.Float(line);     $activeDataGFX.draw(t);      //drawing is complete     if(getCurrentTool() ==DrawingCanvasTool.ERASER){         //Restore the old composite object         $activeDataGFX.setComposite(originalComposite);     }      //Refresh basically merges frames along a frame column into a single preview buffered image     //which will later be used to view the tool animation when user clicks "play" button     channelPannel.refreshFrameOut(  channelPannel.getCurrentFrame()  ); }                  

I commented a lot of the code, and provided the critical points related to the question. Any help is much appreciated. And again, the problem is how do i draw a smooth line worthy of a descent drawing program.

munroeforrout.blogspot.com

Source: https://stackoverflow.com/questions/32924112/how-to-draw-smooth-continuous-line-in-java-swing-that-also-varies-in-size

0 Response to "How to Draw a Continuous Line on Java"

Enviar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel