src/org/math/plot/render/AWTDrawer.java

00001 /*
00002  * Created on 31 mai 2005 by richet
00003  */
00004 package org.math.plot.render;
00005 
00006 import java.awt.*;
00007 import java.awt.font.*;
00008 import java.awt.geom.*;
00009 
00010 import org.math.plot.canvas.*;
00011 
00012 import static java.lang.Math.*;
00013 
00014 public abstract class AWTDrawer extends AbstractDrawer {
00015 
00016         protected Projection projection;
00017 
00018         public AWTDrawer(PlotCanvas _canvas) {
00019                 super(_canvas);
00020         }
00021 
00022         /*
00023          * (non-Javadoc)
00024          * 
00025          * @see org.math.plot.render.AbstractDrawer#resetProjection()
00026          */
00027         public void resetBaseProjection() {
00028                 projection.initBaseCoordsProjection();
00029         }
00030 
00031         /*
00032          * (non-Javadoc)
00033          * 
00034          * @see org.math.plot.render.AbstractDrawer#setColor(java.awt.Color)
00035          */
00036         public void setColor(Color c) {
00037                 comp2D.setColor(c);
00038         }
00039         
00040         /*
00041          * (non-Javadoc)
00042          * 
00043          * @see org.math.plot.render.AbstractDrawer#setGradient
00044          */
00045         public void setGradient(double[] xy0, Color c0, double[] xy1, Color c1) {
00046                 int[] s0=project(xy0);
00047                 int[] s1=project(xy1);
00048                 comp2D.setPaint(new GradientPaint(s0[0],s0[1],c0,s1[0],s1[1],c1));
00049         }
00050 
00051         /*
00052          * (non-Javadoc)
00053          * 
00054          * @see org.math.plot.render.AbstractDrawer#setFont(java.awt.Font)
00055          */
00056         public void setFont(Font f) {
00057                 comp2D.setFont(f);
00058         }
00059 
00060         /*
00061          * (non-Javadoc)
00062          * 
00063          * @see org.math.plot.render.AbstractDrawer#getColor()
00064          */
00065         public Color getColor() {
00066                 return comp2D.getColor();
00067         }
00068 
00069         /*
00070          * (non-Javadoc)
00071          * 
00072          * @see org.math.plot.render.AbstractDrawer#getFont()
00073          */
00074         public Font getFont() {
00075                 return comp2D.getFont();
00076         }
00077 
00078         /*
00079          * (non-Javadoc)
00080          * 
00081          * @see org.math.plot.render.AbstractDrawer#project(double[])
00082          */
00083         public int[] project(double... pC) {
00084                 return projection.screenProjection(pC);
00085         }
00086 
00087         /*
00088          * (non-Javadoc)
00089          * 
00090          * @see org.math.plot.render.AbstractDrawer#projectRatio(double[])
00091          */
00092         public int[] projectBase(double... rC) {
00093                 return projection.screenProjectionBaseRatio(rC);
00094         }
00095 
00096         /*
00097          * (non-Javadoc)
00098          * 
00099          * @see org.math.plot.render.AbstractDrawer#translate(int[])
00100          */
00101         public void translate(int... t) {
00102                 projection.translate(t);
00103         }
00104 
00105         /*
00106          * (non-Javadoc)
00107          * 
00108          * @see org.math.plot.render.AbstractDrawer#dilate(int[], double[])
00109          */
00110         public void dilate(int[] screenOrigin, double[] screenRatio) {
00111                 projection.dilate(screenOrigin, screenRatio);
00112         }
00113 
00114         /*
00115          * (non-Javadoc)
00116          * 
00117          * @see org.math.plot.render.AbstractDrawer#drawString(java.lang.String,
00118          *      double[], double, double, double)
00119          */
00120         public void drawText(String label, double... pC) {
00121                 int[] sC = projection.screenProjection(pC);
00122 
00123                 // Corner offset adjustment : Text Offset is used Here
00124                 FontRenderContext frc = comp2D.getFontRenderContext();
00125                 Font font1 = comp2D.getFont();
00126                 int x = sC[0];
00127                 int y = sC[1];
00128                 double w = font1.getStringBounds(label, frc).getWidth();
00129                 double h = font1.getSize2D();
00130                 x -= (int) (w * text_Eastoffset);
00131                 y += (int) (h * text_Northoffset);
00132 
00133                 if (text_angle != 0)
00134                         comp2D.rotate(text_angle, x + w / 2, y - h / 2);
00135 
00136                 comp2D.drawString(label, x, y);
00137 
00138                 if (text_angle != 0)
00139                         comp2D.rotate(-text_angle, x + w / 2, y - h / 2);
00140         }
00141 
00142         /*
00143          * (non-Javadoc)
00144          * 
00145          * @see org.math.plot.render.AbstractDrawer#drawStringRatio(java.lang.String,
00146          *      double[], double, double, double)
00147          */
00148         public void drawTextBase(String label, double... rC) {
00149                 int[] sC = projection.screenProjectionBaseRatio(rC);
00150 
00151                 // Corner offset adjustment : Text Offset is used Here
00152                 FontRenderContext frc = comp2D.getFontRenderContext();
00153                 Font font1 = comp2D.getFont();
00154                 int x = sC[0];
00155                 int y = sC[1];
00156                 double w = font1.getStringBounds(label, frc).getWidth();
00157                 double h = font1.getSize2D();
00158                 x -= (int) (w * text_Eastoffset);
00159                 y += (int) (h * text_Northoffset);
00160 
00161                 if (text_angle != 0)
00162                         comp2D.rotate(text_angle, x + w / 2, y - h / 2);
00163 
00164                 comp2D.drawString(label, x, y);
00165 
00166                 if (text_angle != 0)
00167                         comp2D.rotate(-text_angle, x + w / 2, y - h / 2);
00168         }
00169 
00170         /*
00171          * (non-Javadoc)
00172          * 
00173          * @see org.math.plot.render.AbstractDrawer#drawLineRatio(double[],
00174          *      double[])
00175          */
00176         public void drawLineBase(double[]... rC) {
00177                 int[][] sC = new int[rC.length][];
00178                 for (int i = 0; i < sC.length; i++)
00179                         sC[i] = projection.screenProjectionBaseRatio(rC[i]);
00180                 drawLine(sC);
00181         }
00182 
00183         /*
00184          * (non-Javadoc)
00185          * 
00186          * @see org.math.plot.render.AbstractDrawer#drawLine(double[], double[])
00187          */
00188         public void drawLine(double[]... pC) {
00189                 int[][] sC = new int[pC.length][];
00190                 for (int i = 0; i < sC.length; i++)
00191                         sC[i] = projection.screenProjection(pC[i]);
00192                 drawLine(sC);
00193         }
00194 
00195         private void drawLine(int[]... c) {
00196                 Stroke s = null;
00197                 switch (line_type) {
00198                 case CONTINOUS_LINE:
00199                         s = new BasicStroke(line_width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
00200                         break;
00201                 case DOTTED_LINE:
00202                         s = new BasicStroke(line_width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1f, new float[] { 2f }, 0f);
00203                         break;
00204                 }
00205                 comp2D.setStroke(s);
00206 
00207                 int[] x = new int[c.length];
00208                 for (int i = 0; i < c.length; i++)
00209                         x[i] = c[i][0];
00210                 int[] y = new int[c.length];
00211                 for (int i = 0; i < c.length; i++)
00212                         y[i] = c[i][1];
00213                 comp2D.drawPolyline(x, y, c.length);
00214         }
00215 
00216         /*
00217          * (non-Javadoc)
00218          * 
00219          * @see org.math.plot.render.AbstractDrawer#drawDot(double[])
00220          */
00221         public void drawDot(double... pC) {
00222                 int[] sC = projection.screenProjection(pC);
00223                 switch (dot_type) {
00224                 case ROUND_DOT:
00225                         comp2D.fillOval(sC[0] - dot_radius, sC[1] - dot_radius, 2 * dot_radius, 2 * dot_radius);
00226                         break;
00227                 case CROSS_DOT:
00228                         comp2D.drawLine(sC[0] - dot_radius, sC[1] - dot_radius, sC[0] + dot_radius, sC[1] + dot_radius);
00229                         comp2D.drawLine(sC[0] + dot_radius, sC[1] - dot_radius, sC[0] - dot_radius, sC[1] + dot_radius);
00230                         break;
00231                 case PATTERN_DOT:
00232                         int yoffset = (int)Math.ceil(dot_pattern.length / 2.0);
00233                         int xoffset = (int)Math.ceil(dot_pattern[0].length / 2.0);
00234                         for (int i = 0; i < dot_pattern.length; i++)
00235                                 for (int j = 0; j < dot_pattern[i].length; j++)
00236                                         if (dot_pattern[i][j])
00237                                                 // comp2D.setColor(new Color(getColor())
00238                                                 comp2D.fillRect(sC[0] - xoffset + j, sC[1] - yoffset + i, 1, 1);
00239                         break;
00240                 }
00241         }
00242 
00243         /*
00244          * (non-Javadoc)
00245          * 
00246          * @see org.math.plot.render.AbstractDrawer#drawPloygon(double[][])
00247          */
00248         public void drawPolygon(double[]... pC) {
00249                 int[][] c = new int[pC.length][2];
00250                 for (int i = 0; i < pC.length; i++)
00251                         c[i] = projection.screenProjection(pC[i]);
00252 
00253                 int[] x = new int[c.length];
00254                 for (int i = 0; i < c.length; i++)
00255                         x[i] = c[i][0];
00256                 int[] y = new int[c.length];
00257                 for (int i = 0; i < c.length; i++)
00258                         y[i] = c[i][1];
00259                 comp2D.drawPolygon(x, y, c.length);
00260         }
00261 
00262         /*
00263          * (non-Javadoc)
00264          * 
00265          * @see org.math.plot.render.AbstractDrawer#fillPloygon(double[][])
00266          */
00267         public void fillPolygon(float alpha,double[]... pC) {
00268                 int[][] c = new int[pC.length][2];
00269                 for (int i = 0; i < pC.length; i++)
00270                         c[i] = projection.screenProjection(pC[i]);
00271 
00272                 int[] x = new int[c.length];
00273                 for (int i = 0; i < c.length; i++)
00274                         x[i] = c[i][0];
00275                 int[] y = new int[c.length];
00276                 for (int i = 0; i < c.length; i++)
00277                         y[i] = c[i][1];
00278                 Composite cs = comp2D.getComposite();
00279                 comp2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha));
00280                 comp2D.fillPolygon(x, y, c.length);
00281                 comp2D.setComposite(cs);
00282         }
00283 
00284         public void drawImage(Image img, float alpha, double[] _xyzSW, double[] _xyzSE, double[] _xyzNW) {
00285                 Composite cs = comp2D.getComposite();
00286                 comp2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
00287                 comp2D.drawImage(img,getAffineTransform(img.getWidth(canvas),img.getHeight(canvas),_xyzSW,  _xyzSE,  _xyzNW) , canvas);
00288                 comp2D.setComposite(cs);
00289         }
00290         
00291         /*public void drawShape(Shape shape, float alpha, double[] _xyzSW, double[] _xyzSE, double[] _xyzNW) {
00292                 AffineTransform t = getAffineTransform(shape.getBounds().width,shape.getBounds().height, _xyzSW,  _xyzSE,  _xyzNW);
00293                 Shape t_shape = t.createTransformedShape(shape);
00294                 Composite cs = comp2D.getComposite();
00295                 comp2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
00296                 comp2D.draw(t_shape);
00297                 comp2D.setComposite(cs);
00298         }*/
00299 
00300         static boolean isDiff(double[] x, int[] y) {
00301                 return abs(x[0] - y[0]) > 1 || abs(x[1] - y[1]) > 1;
00302         }
00303 
00304         static double sign(double x) {
00305                 if (x != 0)
00306                         return signum(x);
00307                 else
00308                         return 1.0;
00309         }
00310         
00311         static double sqr(double x) {
00312                 return x * x;
00313         }
00314         
00315         public AffineTransform getAffineTransform(int width, int height, double[] _xyzSW, double[] _xyzSE, double[] _xyzNW) {
00316                 int[] cornerNW = projection.screenProjection(_xyzNW);
00317                 int[] cornerSE = projection.screenProjection(_xyzSE);
00318                 int[] cornerSW = projection.screenProjection(_xyzSW);
00319 
00320                 double[] vectWE = { (double) cornerSE[0] - (double) cornerSW[0], (double) cornerSE[1] - (double) cornerSW[1] };
00321                 double normvectWE = sqrt(sqr(vectWE[0]) + sqr(vectWE[1]));
00322                 double[] vectSN = { (double) cornerNW[0] - (double) cornerSW[0], (double) cornerNW[1] - (double) cornerSW[1] };
00323                 double normvectSN = sqrt(sqr(vectSN[0]) + sqr(vectSN[1]));
00324                 double angleSW = acos((vectWE[0] * vectSN[0] + vectWE[1] * vectSN[1]) / (normvectWE * normvectSN));
00325 
00326                 AffineTransform t = new AffineTransform();
00327 
00328                 t.translate(cornerNW[0], cornerNW[1]);
00329                 t.scale(sign(vectWE[0]), -sign(vectSN[1]));
00330                 t.rotate(-atan(vectSN[0] / vectSN[1]));
00331                 t.shear(0, 1 / tan(PI - angleSW));
00332                 t.scale(normvectWE * cos(angleSW - PI / 2) / (double) width, normvectSN / (double) height);
00333 
00334                 double[] _cornerSE_tr = new double[2];
00335                 double[] _cornerSE = { width, height };
00336                 t.transform(_cornerSE, 0, _cornerSE_tr, 0, 1);
00337 
00338                 if (isDiff(_cornerSE_tr, cornerSE)) {
00339                         double[] vectSE_NW_1 = { (double) cornerNW[0] - (double) cornerSE[0], (double) cornerNW[1] - (double) cornerSE[1] };
00340                         double[] vectSE_NW_2 = { (double) cornerNW[0] - (double) _cornerSE_tr[0], (double) cornerNW[1] - (double) _cornerSE_tr[1] };
00341 
00342                         double normvect_1 = sqrt(sqr(vectSE_NW_1[0]) + sqr(vectSE_NW_1[1]));
00343                         double normvect_2 = sqrt(sqr(vectSE_NW_1[0]) + sqr(vectSE_NW_1[1]));
00344 
00345                         double cos_angle = (((vectSE_NW_1[0] * vectSE_NW_2[0] + vectSE_NW_1[1] * vectSE_NW_2[1]) / (normvect_1 * normvect_2)));
00346                         double vect = (vectSE_NW_1[0] * vectSE_NW_2[1] - vectSE_NW_1[1] * vectSE_NW_2[0]);
00347 
00348                         AffineTransform t2 = new AffineTransform();
00349                         if (vect < 0)
00350                                 t2.rotate(acos(cos_angle), cornerNW[0], cornerNW[1]);
00351                         else
00352                                 t2.rotate(-acos(cos_angle), cornerNW[0], cornerNW[1]);
00353                         t.preConcatenate(t2);
00354                 }
00355                 
00356                 // TODO patch for many cases...
00357                 
00358                 /*double[] _cornerSW_tr = new double[2];
00359                 double[] _cornerSW = { 0, img.getHeight(canvas) };
00360                 t.transform(_cornerSW, 0, _cornerSW_tr, 0, 1);
00361                 
00362                 if (isDiff(_cornerSW_tr, cornerSW)) {
00363                         double[] vectSW_NW_1 = { (double) cornerNW[0] - (double) cornerSW[0], (double) cornerNW[1] - (double) cornerSW[1] };
00364                         double[] vectSW_NW_2 = { (double) cornerNW[0] - (double) _cornerSW_tr[0], (double) cornerNW[1] - (double) _cornerSW_tr[1] };
00365 
00366                         double normvect_1 = sqrt(sqr(vectSW_NW_1[0]) + sqr(vectSW_NW_1[1]));
00367                         double normvect_2 = sqrt(sqr(vectSW_NW_1[0]) + sqr(vectSW_NW_1[1]));
00368 
00369                         double cos_angle = (((vectSW_NW_1[0] * vectSW_NW_2[0] + vectSW_NW_1[1] * vectSW_NW_2[1]) / (normvect_1 * normvect_2)));
00370                         double vect = (vectSW_NW_1[0] * vectSW_NW_2[1] - vectSW_NW_1[1] * vectSW_NW_2[0]);
00371 
00372                         System.out.println(cos_angle + " " + vect + " -> " + toDegrees(acos(cos_angle)));
00373 
00374                         //System.out.println(" "+vectSE_NW_1[0]+","+vectSE_NW_1[1]+"  "+vectSE_NW_2[0]+","+vectSE_NW_2[1]);
00375                         AffineTransform t2 = new AffineTransform();
00376                         if (vect > 0)
00377                                 t2.rotate(acos(cos_angle), cornerNW[0], cornerNW[1]);
00378                         else
00379                                 t2.rotate(-acos(cos_angle), cornerNW[0], cornerNW[1]);
00380                         t.preConcatenate(t2);
00381 
00382                 }*/
00383                 
00384                 return t;
00385         }
00386         
00387 }

Generated on Wed Sep 5 21:44:02 2007 for jmathplot by  doxygen 1.5.1