java - AffineTransform without transforming Stroke? -


when using graphics2d scale() function 2 different parameters (scaling different ratios in x- , y-direction), drawn later on graphics2d object scaled too. has strange effect lines drawn in 1 direction thicker in direction. following program produces effect, shows window:

example screenshot

public class strokeexample extends jpanel {       public void paintcomponent(graphics context) {         super.paintcomponent(context);         graphics2d g = (graphics2d)context.create();         g.setstroke(new basicstroke(0.2f));          int height = getheight();         int width = getwidth();          g.scale(width/7.0, height/4.0);          g.setcolor(color.black);         g.draw(new rectangle( 2, 1, 4, 2));     }      public static void main(string[] params) {         eventqueue.invokelater(new runnable(){public void run() {              strokeexample example = new strokeexample();              jframe f = new jframe("strokeexample");             f.setsize(100, 300);             f.getcontentpane().setlayout(new borderlayout());             f.getcontentpane().add(example);             f.setdefaultcloseoperation(windowconstants.dispose_on_close);             f.setvisible(true);         }});      }  } 

i'm using coordinate transform avoid having manually transform application model coordinates (the (2,1, 2,4) in example) screen (or component) pixel coordinates, don't want stroke distortion. in other words, i want have lines same width, independent of current x- , y-scale-factors.

i know produces effect (the stroke object creates stroked shape of rectangle painted in user coordinates, translated screen coordinates), i'm not sure on how solve this.

  • should create new stroke implementation strokes shapes differently in x- , y-direction (thereby undoing distortion here)? (or knows such implementation?)
  • should transform shapes screen coordinates , stroke there?
  • any other (better) ideas?

turns out question not horrible difficult, , 2 ideas given in question same idea. here transformedstroke class implements distorted stroke transforming shape.

import java.awt.*; import java.awt.geom.*;   /**  * implementation of {@link stroke} transforms stroke  * {@link affinetransform} before stroking it.  *  * class immutable long underlying stroke  * immutable.  */ public class transformedstroke     implements stroke {     /**      * make serializable without problems.      */     private static final long serialversionuid = 1;      /**      * affinetransform used transform shape before stroking.      */     private affinetransform transform;     /**      * inverse of {@link #transform}, used transform      * after stroking.      */     private affinetransform inverse;      /**      * our base stroke.      */     private stroke stroke;       /**      * creates transformedstroke based on stroke      * , affinetransform.      */     public transformedstroke(stroke base, affinetransform at)         throws noninvertibletransformexception     {         this.transform = new affinetransform(at);         this.inverse = transform.createinverse();         this.stroke = base;     }       /**      * strokes given shape stroke, creating outline.      *      * outline distorted our affinetransform relative      * outline given base stroke, in terms      * of scaling (i.e. thickness of lines), translation , rotation      * undone after stroking.      */     public shape createstrokedshape(shape s) {         shape strans = transform.createtransformedshape(s);         shape stransstroked = stroke.createstrokedshape(strans);         shape sstroked = inverse.createtransformedshape(stransstroked);         return sstroked;     }  } 

my paint-method using looks this:

public void paintcomponent(graphics context) {     super.paintcomponent(context);     graphics2d g = (graphics2d)context.create();      int height = getheight();     int width = getwidth();      g.scale(width/4.0, height/7.0);      try {         g.setstroke(new transformedstroke(new basicstroke(2f),                                           g.gettransform()));     }     catch(noninvertibletransformexception ex) {         // should not occur if width , height > 0         ex.printstacktrace();     }      g.setcolor(color.black);     g.draw(new rectangle( 1, 2, 2, 4)); } 

then window looks this:

screenshot of undistorted stroke

i'm quite content this, if has more ideas, feel free answer nevertheless.


attention: g.gettransform() returning complete transformation of g relative device space, not transformation applied after .create(). so, if did scaling before giving graphics component, still draw 2-device-pixel width stroke, not 2 pixels of grapics given method. if problem, use this:

public void paintcomponent(graphics context) {     super.paintcomponent(context);     graphics2d g = (graphics2d)context.create();      affinetransform trans = new affinetransform();      int height = getheight();     int width = getwidth();      trans.scale(width/4.0, height/7.0);     g.transform(trans);      try {         g.setstroke(new transformedstroke(new basicstroke(2f),                                           trans));     }     catch(noninvertibletransformexception ex) {         // should not occur if width , height > 0         ex.printstacktrace();     }      g.setcolor(color.black);     g.draw(new rectangle( 1, 2, 2, 4)); } 

in swing graphics given paintcomponent translated (so (0,0) upper left corner of component), not scaled, there no difference.


Comments

Popular posts from this blog

apache - Add omitted ? to URLs -

redirect - bbPress Forum - rewrite to wwww.mysite prohibits login -

php - How can I stop spam on my custom forum/blog? -