Trying to draw text at an angle

Thread Solved

Join Date: Jan 2008
Posts: 3,803
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 501
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster

Re: Trying to draw text at an angle

 
0
  #11
Aug 23rd, 2008
Originally Posted by sciwizeh View Post
yes, the blurry text is because of int rounding error. a better way to do it would be affinetransform, but i haven't used it much, and the sun tutorial confused me a bit, i think that this may also help.
Great. Thank you. I will check those links out.
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 4,423
Reputation: Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of 
Solved Threads: 507
Moderator
Featured Poster
Ezzaral's Avatar
Ezzaral Ezzaral is offline Offline
Industrious Poster

Re: Trying to draw text at an angle

 
0
  #12
Aug 25th, 2008
You have made this a bit more complex than need be. For simple transformations, the Graphics2D methods rotate() and translate() will suffice (they additively modify the current AffineTransform of the graphics context) without any need to obtain or work with an AffineTransform object directly.

I wrote this small example that might help
  1. import java.awt.BorderLayout;
  2. import java.awt.Color;
  3. import java.awt.EventQueue;
  4. import java.awt.FontMetrics;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import javax.swing.JFrame;
  8. import javax.swing.JPanel;
  9.  
  10. public class TextExample extends JFrame {
  11.  
  12. GraphicPanel gPanel;
  13.  
  14. public TextExample() {
  15. setDefaultCloseOperation(EXIT_ON_CLOSE);
  16. setLayout(new BorderLayout());
  17. gPanel = new GraphicPanel();
  18. getContentPane().add(gPanel, BorderLayout.CENTER);
  19. setBounds(100, 100, 200, 200);
  20. setVisible(true);
  21. }
  22.  
  23. class GraphicPanel extends JPanel {
  24. protected void paintComponent(Graphics g) {
  25. Graphics2D g2 = (Graphics2D)g;
  26. g2.setBackground(Color.BLACK);
  27. g2.clearRect(0, 0, getWidth(), getHeight());
  28. g2.setColor(Color.WHITE);
  29. String msg = "Hi Vernon";
  30. FontMetrics metrics = g2.getFontMetrics();
  31. // translate context to center of panel
  32. // the point 0,0 now resides here
  33. g2.translate(getWidth() / 2, getHeight() / 2);
  34. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  35. metrics.getMaxAscent() / 2);
  36. // rotate 45 deg
  37. g2.rotate(-Math.PI / 4);
  38. g2.setColor(Color.YELLOW);
  39. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  40. metrics.getMaxAscent() / 2);
  41. // rotate 45 deg again - these transforms are additive
  42. g2.rotate(-Math.PI / 4);
  43. g2.setColor(Color.ORANGE);
  44. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  45. metrics.getMaxAscent() / 2);
  46. }
  47. }
  48.  
  49. public static void main(String... args) {
  50. EventQueue.invokeLater(new Runnable() {
  51. public void run() {
  52. new TextExample();
  53. }
  54. });
  55. }
  56. }
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 3,803
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 501
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster

Re: Trying to draw text at an angle

 
0
  #13
Aug 25th, 2008
Originally Posted by Ezzaral View Post
You have made this a bit more complex than need be. For simple transformations, the Graphics2D methods rotate() and translate() will suffice (they additively modify the current AffineTransform of the graphics context) without any need to obtain or work with an AffineTransform object directly.

I wrote this small example that might help
  1. import java.awt.BorderLayout;
  2. import java.awt.Color;
  3. import java.awt.EventQueue;
  4. import java.awt.FontMetrics;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import javax.swing.JFrame;
  8. import javax.swing.JPanel;
  9.  
  10. public class TextExample extends JFrame {
  11.  
  12. GraphicPanel gPanel;
  13.  
  14. public TextExample() {
  15. setDefaultCloseOperation(EXIT_ON_CLOSE);
  16. setLayout(new BorderLayout());
  17. gPanel = new GraphicPanel();
  18. getContentPane().add(gPanel, BorderLayout.CENTER);
  19. setBounds(100, 100, 200, 200);
  20. setVisible(true);
  21. }
  22.  
  23. class GraphicPanel extends JPanel {
  24. protected void paintComponent(Graphics g) {
  25. Graphics2D g2 = (Graphics2D)g;
  26. g2.setBackground(Color.BLACK);
  27. g2.clearRect(0, 0, getWidth(), getHeight());
  28. g2.setColor(Color.WHITE);
  29. String msg = "Hi Vernon";
  30. FontMetrics metrics = g2.getFontMetrics();
  31. // translate context to center of panel
  32. // the point 0,0 now resides here
  33. g2.translate(getWidth() / 2, getHeight() / 2);
  34. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  35. metrics.getMaxAscent() / 2);
  36. // rotate 45 deg
  37. g2.rotate(-Math.PI / 4);
  38. g2.setColor(Color.YELLOW);
  39. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  40. metrics.getMaxAscent() / 2);
  41. // rotate 45 deg again - these transforms are additive
  42. g2.rotate(-Math.PI / 4);
  43. g2.setColor(Color.ORANGE);
  44. g2.drawString(msg, -metrics.stringWidth(msg) / 2,
  45. metrics.getMaxAscent() / 2);
  46. }
  47. }
  48.  
  49. public static void main(String... args) {
  50. EventQueue.invokeLater(new Runnable() {
  51. public void run() {
  52. new TextExample();
  53. }
  54. });
  55. }
  56. }
Thank you. I will try that out. I sort of stumbled onto the knowledge that it wasn't nearly as difficult as I thought when I spent about two and a half hours going through the Java tutorial. I kept deleting things from their code till I got to the bare minimum, then finally realized that the bare minimum was only a couple of lines. But it took a while for me to keep deleting stuff from Sun's super cool example till I got to the part of it that I cared about. Thanks.
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 4,423
Reputation: Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of 
Solved Threads: 507
Moderator
Featured Poster
Ezzaral's Avatar
Ezzaral Ezzaral is offline Offline
Industrious Poster

Re: Trying to draw text at an angle

 
2
  #14
Aug 26th, 2008
Yes, some of their examples can be more complex than need be and obscure the usage they are trying to demonstrate.

One more thing worth noting with respect to AffineTransforms is that they represent the current state of the coordinate system within the graphics context. Since you can store references to as many AffineTransforms as you want, you can effectively "save" any state (translation, orientation, scale, and sheer) you wish and restore it at will. If you have many objects that render themselves independently, each can maintain it's own transform that it uses for rendering. When that object's turn to be rendered comes, you can save the current transform of your graphics context, apply that object's transform, render it, and then restore the original transform.

Here's an example of that:
  1. import java.awt.BorderLayout;
  2. import java.awt.Color;
  3. import java.awt.EventQueue;
  4. import java.awt.FontMetrics;
  5. import java.awt.Graphics;
  6. import java.awt.Graphics2D;
  7. import java.awt.Point;
  8. import java.awt.geom.AffineTransform;
  9. import javax.swing.JFrame;
  10. import javax.swing.JPanel;
  11.  
  12. public class TransformExample extends JFrame {
  13.  
  14. GraphicPanel gPanel;
  15.  
  16. public TransformExample() {
  17. setDefaultCloseOperation(EXIT_ON_CLOSE);
  18. gPanel = new GraphicPanel();
  19. getContentPane().add(gPanel);
  20. setBounds(100, 100, 200, 200);
  21. setVisible(true);
  22. }
  23.  
  24. class GraphicPanel extends JPanel {
  25. TextLabel label1;
  26. TextLabel label2;
  27. TextLabel label3;
  28.  
  29. protected void paintComponent(Graphics g) {
  30. if (label1 == null) {
  31. // lazy initilization so I have dimensions to work with
  32. FontMetrics fm = g.getFontMetrics();
  33. int width = getWidth();
  34. int height = getHeight();
  35.  
  36. label1 = new TextLabel("Hi Vernon", Color.YELLOW,
  37. 20, height/2, -Math.PI/2);
  38.  
  39. String labelText = "I'm over here";
  40. int labelLen = fm.stringWidth(labelText);
  41. label2 = new TextLabel(labelText, Color.CYAN,
  42. width-labelLen, height/2, -Math.PI/4);
  43.  
  44. labelText = "Standing on my head";
  45. labelLen = fm.stringWidth(labelText);
  46. label3 = new TextLabel(labelText, Color.ORANGE,
  47. (width+labelLen)/2, height-20, Math.PI);
  48. }
  49.  
  50. Graphics2D g2 = (Graphics2D)g;
  51. g2.setBackground(Color.BLACK);
  52. g2.clearRect(0, 0, getWidth(), getHeight());
  53.  
  54. label1.draw(g2);
  55. label2.draw(g2);
  56. label3.draw(g2);
  57. }
  58. }
  59.  
  60. class TextLabel {
  61. private AffineTransform transform;
  62. private Point location;
  63. private double rotation;
  64. private String text;
  65. private Color color;
  66.  
  67. public TextLabel(String text, Color color, int x, int y,
  68. double rotation) {
  69.  
  70. this.text = text;
  71. this.color = color;
  72. this.location = new Point(x, y);
  73. this.rotation = rotation;
  74. transform = new AffineTransform();
  75. transform.translate(location.x, location.y);
  76. transform.rotate(rotation);
  77. }
  78.  
  79. public void draw(Graphics2D g){
  80. // save current color and transform
  81. AffineTransform currentTransform = g.getTransform();
  82. Color currentColor = g.getColor();
  83.  
  84. // apply my own color and transform
  85. g.setTransform(transform);
  86. g.setColor(color);
  87. // this will be left aligned at the origin
  88. // a parameter for left/center/right alignment
  89. // could be added easily
  90. g.drawString(text, 0, 0);
  91.  
  92. // restore the original state
  93. g.setColor(currentColor);
  94. g.setTransform(currentTransform);
  95. }
  96. }
  97.  
  98. public static void main(String... args) {
  99. EventQueue.invokeLater(new Runnable() {
  100. public void run() {
  101. new TransformExample();
  102. }
  103. });
  104. }
  105. }
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 3,803
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 501
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster

Re: Trying to draw text at an angle

 
0
  #15
Aug 26th, 2008
Originally Posted by Ezzaral View Post
Yes, some of their examples can be more complex than need be and obscure the usage they are trying to demonstrate.

One more thing worth noting with respect to AffineTransforms is that they represent the current state of the coordinate system within the graphics context. Since you can store references to as many AffineTransforms as you want, you can effectively "save" any state (translation, orientation, scale, and sheer) you wish and restore it at will. If you have many objects that render themselves independently, each can maintain it's own transform that it uses for rendering. When that object's turn to be rendered comes, you can save the current transform of your graphics context, apply that object's transform, render it, and then restore the original transform.

Here's an example of that:

Perfect! My project is a type of ColorForms/CAD program where the user can draw pentagons, ovals, rectangles, text, etc., on the screen and they can all be different sizes and different angles and I'm going to try to give the option where a user can spin one shape and/or piece of text and leave the others the same or spin them all or spin some but not others or change one or more sizes, etc. Potentially you could have hundreds or even thousands of objects on the screen, all with different sizes and different angles. To rotate a polygon, I was doing the math and changing the polygon coordinates myself, but the idea of keeping the same points and having a different AffineTransformation for each of them is very appealing and seems like less calculation for me. Plus the goal is to be able to tilt images too eventually. This method has fantastic potential compared to my earlier approach. Thanks again. As usual, you gave great sample code.
Last edited by VernonDozier; Aug 26th, 2008 at 9:29 pm.
Reply With Quote Quick reply to this message  
Reply


This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the Java Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC