rotate.C

Go to the documentation of this file.
00001 /* Gnome gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  * 
00005  * Gxsm Plugin Name: rotate.C
00006  * ========================================
00007  * 
00008  * Copyright (C) 1999 The Free Software Foundation
00009  *
00010  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00011  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00026  */
00027 
00028 /* Please do not change the Begin/End lines of this comment section!
00029  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00030  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00031  * All "% PlugInXXX" commentary tags are mandatory
00032  * All "% OptPlugInXXX" tags are optional
00033  * --------------------------------------------------------------------------------
00034 % BeginPlugInDocuSection
00035 % PlugInDocuCaption: Rotate a scan area
00036 % PlugInName: rotate
00037 % PlugInAuthor: Percy Zahl
00038 % PlugInAuthorEmail: zahl@users.sf.net
00039 % PlugInMenuPath: Math/Transformation/Rotate
00040 
00041 % PlugInDescription
00042 To rotate a selected area select a \GxsmEmph{Rectangle} of the area to
00043 be rotated into. Think inverse, the result is the cropped area of the
00044 source scan, which is rotated before around the center of the selected
00045 area. If needed data points are outside, they are replaced by the
00046 value found a the closed edge.
00047 
00048 % PlugInUsage
00049 Place a rectangle object and call
00050 \GxsmMenu{Math/Transformation/Rotate}. It prompts for the rotation
00051 angle (clockwise) if not set to any other default than zero via the
00052 PlugIn configurator.
00053 
00054 % OptPlugInSources
00055 The active channel is used as data source.
00056 
00057 % OptPlugInObjects
00058 A rectangle object is needed.
00059 
00060 % OptPlugInDest
00061 The computation result is placed into an existing math channel, else into a new created math channel.
00062 
00063 % OptPlugInConfig
00064 The PlugIn configurator allows to set a default angle. If this is non
00065 zero the user is not prompted for a rotation angle!
00066 
00067 % EndPlugInDocuSection
00068  * -------------------------------------------------------------------------------- 
00069  */
00070 
00071 #include <gtk/gtk.h>
00072 #include "config.h"
00073 #include "gxsm/plugin.h"
00074 
00075 static void rotate_about( void );
00076 static void rotate_configuration( void );
00077 static gboolean rotate_run( Scan *Src, Scan *Dest );
00078 
00079 GxsmPlugin rotate_pi = {
00080   NULL,
00081   NULL,
00082   0,
00083   NULL,
00084   "Rotate-M1S-TR",
00085   NULL,
00086   NULL,
00087   "Percy Zahl",
00088   "_Math/_Transformations/",
00089   N_("Rotate"),
00090   N_("Rotate selection of scan"),
00091   "no more info",
00092   NULL,
00093   NULL,
00094   NULL,
00095   NULL,
00096   rotate_about,
00097   rotate_configuration,
00098   NULL,
00099   NULL
00100 };
00101 
00102 GxsmMathOneSrcPlugin rotate_m1s_pi = {
00103   rotate_run
00104 };
00105 
00106 static const char *about_text = N_("Gxsm Rotate Math-Plugin\n\n"
00107                                    "Affine Transformation:\n"
00108                                    "Rotate selection of Scan by arb. angle.");
00109 
00110 double PhiDefault = 0.;
00111 double PhiLast = 0.;
00112 
00113 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00114   rotate_pi.description = g_strdup_printf(N_("Gxsm MathOneArg rotate plugin %s"), VERSION);
00115   return &rotate_pi; 
00116 }
00117 
00118 GxsmMathOneSrcPlugin *get_gxsm_math_one_src_plugin_info( void ) { 
00119   return &rotate_m1s_pi; 
00120 }
00121 
00122 static void rotate_about(void)
00123 {
00124   const gchar *authors[] = { rotate_pi.authors, NULL};
00125   gtk_widget_show(gnome_about_new ( rotate_pi.name,
00126                                     VERSION,
00127                                     N_("(C) 2000 the Free Software Foundation"),
00128                                     about_text,
00129                                     authors,
00130                                     NULL, NULL, NULL
00131                                     ));
00132 }
00133 
00134 static void rotate_configuration( void ){
00135   rotate_pi.app->ValueRequest("Enter Value", "angle", 
00136                               "Default rotation angle, if set to Zero I will ask later!",
00137                               rotate_pi.app->xsm->ArcUnit, 
00138                               -360., 360., ".2f", &PhiDefault);
00139 }
00140 
00141 int max (int a, int b) { return a>b ? a:b; }
00142 
00143 static gboolean rotate_run(Scan *Src, Scan *Dest)
00144 {
00145   MOUSERECT msr;
00146   double phi = PhiLast;
00147   double cphi,sphi;
00148   int col, line, nx2, ny2;
00149   double drcol, drline;
00150   int xl, yo;
00151   PI_DEBUG (DBG_L2, "Rotate Scan");
00152 
00153   if(fabs(PhiDefault) > 1e-10)
00154     phi = PhiDefault;
00155   else
00156     rotate_pi.app->ValueRequest("Enter Value", "angle", 
00157                                 "I need the rotation angle.",
00158                                 rotate_pi.app->xsm->ArcUnit, 
00159                                 -360., 360., ".2f", &phi);
00160   PhiLast = phi;
00161 
00162   phi *= M_PI/180.;
00163   // Drehmatrix:
00164   cphi = cos(phi);
00165   sphi = sin(phi);
00166 
00167   MkMausSelect(Src->Pkt2d, &msr, Dest->mem2d->GetNx(), Dest->mem2d->GetNy());
00168           
00169   if( msr.xSize  < 1 || msr.ySize < 1){ // use selection area only?
00170           nx2 =  Src->data.s.nx/2;
00171           ny2 =  Src->data.s.ny/2;
00172           int xy[4][2];
00173           for (int i=0; i<=1; ++i)
00174                   for (int j=0; j<=1; ++j){
00175                           xy[i+2*j][0] = (int)round ((double)(i*Src->data.s.nx-nx2) * cphi + (double)(j*Src->data.s.ny-ny2) * sphi);
00176                           xy[i+2*j][1] = (int)round (-(double)(i*Src->data.s.nx-nx2) * sphi + (double)(i*Src->data.s.ny-ny2) * cphi);
00177                   }
00178           
00179           Dest->data.s.nx = max (abs (xy[0][0] - xy[1][0]), abs (xy[2][0] - xy[3][0]));
00180           Dest->data.s.ny = max (abs (xy[0][1] - xy[1][1]), abs (xy[2][1] - xy[3][1]));
00181 
00182           Dest->mem2d->Resize(Dest->data.s.nx, Dest->data.s.ny);
00183           xl = yo = 0;
00184 
00185 //        rotate_pi.app->message("Please select a Rectangle!");
00186 //        return MATH_SELECTIONERR;
00187 
00188   } else { // all
00189 
00190           Dest->data.s.nx = msr.xSize;
00191           Dest->data.s.ny = msr.ySize;
00192           Dest->mem2d->Resize(Dest->data.s.nx, Dest->data.s.ny);
00193           Dest->data.s.x0 += (msr.xLeft + msr.xSize/2 - Src->data.s.nx/2)*Src->data.s.dx;
00194           Dest->data.s.y0 += msr.yTop*Src->data.s.dy;
00195           xl = msr.xLeft;
00196           yo = msr.yTop;
00197 
00198   }
00199 
00200   // Anpassen an nächstmöglichen Wert  
00201   Dest->data.s.rx = Dest->data.s.nx*Dest->data.s.dx;
00202   Dest->data.s.ry = Dest->data.s.ny*Dest->data.s.dy;
00203 
00204   nx2 =  Dest->data.s.nx/2;
00205   ny2 =  Dest->data.s.ny/2;
00206   for(col = 0; col < Dest->data.s.nx; col++)
00207     for(line = 0; line < Dest->data.s.ny; line++){
00208       drcol  = (double)(xl + nx2) + (double)(col - nx2)*cphi + (double)(line - ny2)*sphi;
00209       drline = (double)(yo + ny2) - (double)(col - nx2)*sphi + (double)(line - ny2)*cphi;
00210       if((drcol+1) >=  Src->data.s.nx-1)
00211         drcol= Src->data.s.nx-2;
00212       if(drcol <  0) 
00213         drcol=0.;
00214       if((drline+1) >=  Src->data.s.ny) 
00215         drline= Src->data.s.ny-2;
00216       if(drline <  0) 
00217         drline=0.;
00218       Dest->mem2d->PutDataPkt(Src->mem2d->GetDataPktInterpol(drcol, drline), col, line);
00219     }
00220   return MATH_OK;
00221 }

Generated on Sat Apr 1 09:04:24 2006 for GXSM by  doxygen 1.4.6