ChampDecomposer.cpp

Go to the documentation of this file.
00001 /*
00002  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
00003  * Copyright (C) 2008 - INRIA - Jean-Baptiste Silvy
00004  * desc : Strategy decomposing only champ object 
00005  * 
00006  * This file must be used under the terms of the CeCILL.
00007  * This source file is licensed as described in the file COPYING, which
00008  * you should have received as part of this distribution.  The terms
00009  * are also available at    
00010  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
00011  *
00012  */
00013 
00014 #include "ChampDecomposer.hxx"
00015 
00016 extern "C"
00017 {
00018 #include "GetProperty.h"
00019 #include "BasicAlgos.h"
00020 #include "math_graphics.h"
00021 }
00022 
00023 namespace sciGraphics
00024 {
00025 /*---------------------------------------------------------------------------------*/
00026 ChampDecomposer::ChampDecomposer(DrawableSegs * segs)
00027   : DecomposeSegsStrategy(segs) 
00028 {
00029 
00030 }
00031 /*---------------------------------------------------------------------------------*/
00032 ChampDecomposer::~ChampDecomposer(void)
00033 {
00034 
00035 }
00036 /*---------------------------------------------------------------------------------*/
00037 void ChampDecomposer::getSegsPos(double startXCoords[], double endXCoords[],
00038                                  double startYCoords[], double endYCoords[],
00039                                  double startZCoords[], double endZCoords[])
00040 {
00041   int nbSegs = getNbSegment();
00042   sciPointObj * pSegs = m_pDrawed->getDrawedObject();
00043   sciSegs * ppSegs = pSEGS_FEATURE(pSegs);
00044 
00045   // get data for X and Y values
00046   if (ppSegs->typeofchamp == 0)
00047   {
00048     getChampPos(startXCoords, endXCoords, startYCoords, endYCoords);
00049   }
00050   else
00051   {
00052     getChamp1Pos(startXCoords, endXCoords, startYCoords, endYCoords);
00053   }
00054 
00055   // champ is not yet usable in 3d, so use a default value for Z
00056   char logFlags[3];
00057   double defaultZvalue;
00058   sciGetLogFlags(sciGetParentSubwin(pSegs), logFlags);
00059   if (logFlags[2] == 'l')
00060   {
00061     defaultZvalue = 1.0;
00062   }
00063   else
00064   {
00065     defaultZvalue = 0.0;
00066   }
00067 
00068   for (int i = 0; i < nbSegs; i++)
00069   {
00070     startZCoords[i] = defaultZvalue;
00071     endZCoords[i] = defaultZvalue; 
00072   }
00073 
00074   // apply log scale if needed
00075   m_pDrawed->pointScale(startXCoords, startYCoords, startZCoords, nbSegs);
00076   m_pDrawed->pointScale(endXCoords, endYCoords, endZCoords, nbSegs);
00077 
00078 
00079 }
00080 /*---------------------------------------------------------------------------------*/
00081 int ChampDecomposer::getNbSegment(void)
00082 {
00083   sciSegs * ppSegs = pSEGS_FEATURE(m_pDrawed->getDrawedObject());
00084   return ppSegs->Nbr1 * ppSegs->Nbr2;
00085 }
00086 /*---------------------------------------------------------------------------------*/
00087 bool ChampDecomposer::isColored(void)
00088 {
00089   // for now
00090   return true;
00091 }
00092 /*---------------------------------------------------------------------------------*/
00093 void ChampDecomposer::getSegsColors(int colors[])
00094 {
00095   sciPointObj * pSegs = m_pDrawed->getDrawedObject();
00096   sciSegs * ppSegs = pSEGS_FEATURE(pSegs);
00097 
00098   // get data for X and Y values
00099   if (ppSegs->typeofchamp == 0)
00100   {
00101     getChampColors(colors);
00102   }
00103   else
00104   {
00105     getChamp1Colors(colors);
00106   }
00107 }
00108 /*---------------------------------------------------------------------------------*/
00109 void ChampDecomposer::getDefaultChampPos(double startXCoords[], double endXCoords[],
00110                                          double startYCoords[], double endYCoords[])
00111 {
00112   sciPointObj * pSegs = m_pDrawed->getDrawedObject();
00113   sciSegs * ppSegs = pSEGS_FEATURE(pSegs);
00114   int curMatrixIndex = 0;
00115 
00116   for (int i = 0; i < ppSegs->Nbr1; i++)
00117   {
00118     for (int j = 0; j < ppSegs->Nbr2; j++)
00119     {
00120       curMatrixIndex = i + ppSegs->Nbr1 * j;
00121       startXCoords[curMatrixIndex] = ppSegs->vx[i];
00122       endXCoords[curMatrixIndex] = ppSegs->vx[i] + ppSegs->vfx[curMatrixIndex];
00123       startYCoords[curMatrixIndex] = ppSegs->vy[j];
00124       endYCoords[curMatrixIndex] = ppSegs->vy[j] + ppSegs->vfy[curMatrixIndex];
00125     }
00126   }
00127 }
00128 /*---------------------------------------------------------------------------------*/
00129 void ChampDecomposer::getChampPos(double startXCoords[], double endXCoords[],
00130                                   double startYCoords[], double endYCoords[])
00131 {
00132   getDefaultChampPos(startXCoords, endXCoords, startYCoords, endYCoords);
00133 
00134   // find the length of the longest vector
00135   double curMaxLength = getMaxLength();
00136   double maxLength = computeMaxUsableLength();
00137 
00138   int nbSegs = getNbSegment();
00139   
00140   // modify the length proportionally so
00141   // that the longest vector get the max usable length
00142   for (int i = 0; i < nbSegs; i++)
00143   {
00144     double curVect[2] = {endXCoords[i] - startXCoords[i], endYCoords[i] - startYCoords[i]};
00145     endXCoords[i] = startXCoords[i] + curVect[0] * maxLength / curMaxLength;
00146     endYCoords[i] = startYCoords[i] + curVect[1] * maxLength / curMaxLength;
00147   }
00148 }
00149 /*---------------------------------------------------------------------------------*/
00150 void ChampDecomposer::getChamp1Pos(double startXCoords[], double endXCoords[],
00151                                    double startYCoords[], double endYCoords[])
00152 {
00153   // same as getChampPos, but we modify the segs length
00154   // so that each segment has the same length as the longest vector
00155   getDefaultChampPos(startXCoords, endXCoords, startYCoords, endYCoords);
00156 
00157   // find the length of the longest vector
00158   double maxLength = computeMaxUsableLength();
00159 
00160   int nbSegs = getNbSegment();
00161   for (int i = 0; i < nbSegs; i++)
00162   {
00163     double curVect[2] = {endXCoords[i] - startXCoords[i], endYCoords[i] - startYCoords[i]};
00164     double curNorm = NORM_2D(curVect);
00165     endXCoords[i] = startXCoords[i] + curVect[0] * maxLength / curNorm;
00166     endYCoords[i] = startYCoords[i] + curVect[1] * maxLength / curNorm;
00167   }
00168 
00169 }
00170 /*---------------------------------------------------------------------------------*/
00171 double ChampDecomposer::getMaxLength(void)
00172 {
00173   int nbSegs = getNbSegment();
00174   sciPointObj * pSegs = m_pDrawed->getDrawedObject();
00175   sciSegs * ppSegs = pSEGS_FEATURE(pSegs);
00176   double maxLength = 0.0;
00177   for (int i = 0; i < nbSegs; i++)
00178   {
00179     double curLength = ppSegs->vfx[i] * ppSegs->vfx[i] + ppSegs->vfy[i] * ppSegs->vfy[i];
00180     if (curLength > maxLength)
00181     {
00182       maxLength = curLength;
00183     }
00184   }
00185   return sqrt(maxLength);
00186 }
00187 /*---------------------------------------------------------------------------------*/
00188 double ChampDecomposer::computeMaxUsableLength(void)
00189 {
00190   sciPointObj * pSegs = m_pDrawed->getDrawedObject();
00191   sciSegs * ppSegs = pSEGS_FEATURE(pSegs);
00192   
00193   // find the minimum distance between two consecutive abscissas.
00194   double minLengthX;
00195   if (ppSegs->Nbr1 < 2)
00196   {
00197     minLengthX = 1.0;
00198   }
00199   else
00200   {
00201     minLengthX = Abs(ppSegs->vx[1] - ppSegs->vx[0]);
00202     for (int i = 1; i < ppSegs->Nbr1 - 1; i++)
00203     {
00204       double curLength = Abs(ppSegs->vx[i + 1] - ppSegs->vx[i]);
00205       if (curLength < minLengthX)
00206       {
00207         minLengthX = curLength;
00208       }
00209     }
00210   }
00211   
00212   
00213   // find the minimum distance between two consecutive ordinates.
00214   double minLengthY;
00215 
00216   if (ppSegs->Nbr2 < 2)
00217   {
00218     minLengthY = 1.0;
00219   }
00220   else
00221   {
00222     minLengthY = Abs(ppSegs->vy[1] - ppSegs->vy[0]);
00223     for (int i = 1; i < ppSegs->Nbr2 - 1; i++)
00224     {
00225       double curLength = Abs(ppSegs->vy[i + 1] - ppSegs->vy[i]);
00226       if (curLength < minLengthY)
00227       {
00228         minLengthY = curLength;
00229       }
00230     }
00231   }
00232 
00233   // get the minimum between the two
00234   return Min(minLengthX, minLengthY);
00235 
00236 }
00237 /*---------------------------------------------------------------------------------*/
00238 void ChampDecomposer::getChampColors(int colors[])
00239 {
00240   int nbSegs = getNbSegment();
00241   for (int i = 0; i < nbSegs; i++)
00242   {
00243     colors[i] = 0;
00244   }
00245 }
00246 /*---------------------------------------------------------------------------------*/
00247 void ChampDecomposer::getChamp1Colors(int colors[])
00248 {
00249   int nbSegs = getNbSegment();
00250   sciPointObj * pSegs = m_pDrawed->getDrawedObject();
00251   sciSegs * ppSegs = pSEGS_FEATURE(pSegs);
00252   int colorMapSize = sciGetNumColors(sciGetParentFigure(pSegs));
00253   double maxLength = getMaxLength();
00254 
00255   // prevent from dividing by 0.
00256   if (maxLength < SMDOUBLE)
00257   {
00258     maxLength = SMDOUBLE;
00259   }
00260 
00261   for (int i = 0; i < nbSegs; i++)
00262   {
00263     double curVectorNorm = sqrt(ppSegs->vfx[i] * ppSegs->vfx[i] + ppSegs->vfy[i] * ppSegs->vfy[i]);
00264     colors[i] = (int) floor(((colorMapSize - 1) * curVectorNorm / maxLength ) + 0.5);
00265   }
00266 
00267 }
00268 /*---------------------------------------------------------------------------------*/
00269 }

Generated on Tue Sep 9 17:48:29 2008 for Scilab [trunk] by  doxygen 1.5.5