Utils.cs

Go to the documentation of this file.
00001 /*
00002 NPlot - A charting library for .NET
00003 
00004 Utils.cs
00005 Copyright (C) 2003-2004
00006 Matt Howlett 
00007 
00008 Redistribution and use of NPlot or parts there-of in source and
00009 binary forms, with or without modification, are permitted provided
00010 that the following conditions are met:
00011 
00012 1. Re-distributions in source form must retain at the head of each
00013    source file the above copyright notice, this list of conditions
00014    and the following disclaimer.
00015 
00016 2. Any product ("the product") that makes use NPlot or parts 
00017    there-of must either:
00018   
00019     (a) allow any user of the product to obtain a complete machine-
00020         readable copy of the corresponding source code for the 
00021         product and the version of NPlot used for a charge no more
00022         than your cost of physically performing source distribution,
00023         on a medium customarily used for software interchange, or:
00024 
00025     (b) reproduce the following text in the documentation, about 
00026         box or other materials intended to be read by human users
00027         of the product that is provided to every human user of the
00028         product: 
00029    
00030               "This product includes software developed as 
00031               part of the NPlot library project available 
00032               from: http://www.nplot.com/" 
00033 
00034         The words "This product" may optionally be replace with 
00035         the actual name of the product.
00036 
00037 ------------------------------------------------------------------------
00038 
00039 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00040 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00041 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00042 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00043 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00044 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00045 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00046 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00047 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00048 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00049 
00050 */
00051 
00052 using System;
00053 using System.Drawing;
00054 using System.Drawing.Drawing2D;
00055 using System.Data;
00056 using System.Collections;
00057 
00058 namespace NPlot
00059 {
00063         internal class Utils
00064         {
00065 
00070                 public const double Epsilon = double.Epsilon * 1000.0;
00071                 
00072 
00079                 public static bool DoubleEqual( double a, double b )
00080                 {
00081                         if ( System.Math.Abs(a-b) < Epsilon )
00082                         {
00083                                 return true;
00084                         }
00085                         return false;
00086                 }
00087 
00088 
00094                 public static void Swap( ref double a, ref double b )
00095                 {
00096                         double c = a;
00097                         a = b;
00098                         b = c;
00099                 }
00100 
00101 
00108                 public static float Distance( PointF a, PointF b )
00109                 { 
00110                         return (float)System.Math.Sqrt( (a.X - b.X)*(a.X - b.X) + (a.Y - b.Y)*(a.Y - b.Y) );
00111                 }
00112 
00113 
00120                 public static int Distance( Point a, Point b )
00121                 {
00122                         return (int)System.Math.Sqrt( (a.X - b.X)*(a.X - b.X) + (a.Y - b.Y)*(a.Y - b.Y) );
00123                 }
00124 
00125 
00135                 public static double ToDouble( object o )
00136                 {
00137                         if (o is DateTime)
00138                         {
00139                                 return (double)(((DateTime)o).Ticks);
00140                         }
00141 
00142                         else if (o is IConvertible)
00143                         {
00144                                 return System.Convert.ToDouble(o);
00145                         }
00146 
00147                         throw new NPlotException( "Invalid datatype" );
00148                 }
00149 
00150 
00160                 public static bool ArrayMinMax( IList a, out double min, out double max )
00161                 {
00162                         if ( a == null || a.Count == 0 )
00163                         {
00164                                 min = 0.0;
00165                                 max = 0.0;
00166                                 return false;
00167                         }
00168 
00169                         min = Utils.ToDouble(a[0]);
00170                         max = Utils.ToDouble(a[0]);
00171                         
00172                         foreach ( object o in a )
00173                         {
00174 
00175                                 double e = Utils.ToDouble(o);
00176 
00177                                 if ( (min.Equals (double.NaN)) && (!e.Equals (double.NaN)) )
00178                                 {
00179                                         // if min/max are double.NaN and the current value not, then
00180                                         // set them to the current value.
00181                                         min = e;
00182                                         max = e;
00183                                 }
00184                                 if (!double.IsNaN(e))
00185                                 {
00186                                         if (e < min)
00187                                         {
00188                                                 min = e;
00189                                         }
00190                                         if (e > max)
00191                                         {
00192                                                 max = e;
00193                                         }
00194                                 }
00195                         }
00196                         
00197                         if (min.Equals (double.NaN))
00198                         {
00199                                 // if min == double.NaN, then max is also double.NaN
00200                                 min = 0.0;
00201                                 max = 0.0;
00202                                 return false;
00203                         }
00204 
00205                         return true;
00206                 }
00207 
00208 
00217                 public static bool RowArrayMinMax( DataRowCollection rows, 
00218                         out double min, out double max, string columnName )
00219                 {
00220                         // double[] is a reference type and can be null, if it is then I reckon the best
00221                         // values for min and max are also null. double is a value type so can't be set
00222                         //      to null. So min an max return object, and we understand that if it is not null
00223                         // it is a boxed double (same trick I use lots elsewhere in the lib). The 
00224                         // wonderful comment I didn't write at the top should explain everything.
00225                         if ( rows == null || rows.Count == 0 )
00226                         {
00227                                 min = 0.0;
00228                                 max = 0.0;
00229                                 return false;
00230                         }
00231 
00232                         min = Utils.ToDouble( (rows[0])[columnName] );
00233                         max = Utils.ToDouble( (rows[0])[columnName] );
00234 
00235                         foreach ( DataRow r in rows ) 
00236                         {
00237                                 double e = Utils.ToDouble( r[columnName] );
00238 
00239                                 if ( (min.Equals (double.NaN)) && (!e.Equals (double.NaN)) )
00240                                 {
00241                                         // if min/max are double.NaN and the current value not, then
00242                                         // set them to the current value.
00243                                         min = e;
00244                                         max = e;
00245                                 }
00246 
00247                                 if (!double.IsNaN(e))
00248                                 {
00249                                         if (e < min)
00250                                         {
00251                                                 min = e;
00252                                         }
00253                                         if (e > max)
00254                                         {
00255                                                 max = e;
00256                                         }
00257                                 }
00258                         }
00259                         if (min.Equals (double.NaN))
00260                         {
00261                                 // if min == double.NaN, then max is also double.NaN
00262                                 min = 0.0;
00263                                 max = 0.0;
00264                                 return false;
00265                         }
00266 
00267                         return true;
00268 
00269                 }
00270 
00271 
00280                 public static bool DataViewArrayMinMax( DataView data, 
00281                         out double min, out double max, string columnName )
00282                 {
00283                         // double[] is a reference type and can be null, if it is then I reckon the best
00284                         // values for min and max are also null. double is a value type so can't be set
00285                         //      to null. So min an max return object, and we understand that if it is not null
00286                         // it is a boxed double (same trick I use lots elsewhere in the lib). The 
00287                         // wonderful comment I didn't write at the top should explain everything.
00288                         if ( data == null || data.Count == 0 )
00289                         {
00290                                 min = 0.0;
00291                                 max = 0.0;
00292                                 return false;
00293                         }
00294 
00295                         min = Utils.ToDouble( (data[0])[columnName] );
00296                         max = Utils.ToDouble( (data[0])[columnName] );
00297 
00298                         for (int i=0; i<data.Count; ++i)
00299                         {
00300 
00301                                 double e = Utils.ToDouble( data[i][columnName] );
00302 
00303                                 if (e < min)
00304                                 {
00305                                         min = e;
00306                                 }
00307                         
00308                                 if (e > max) 
00309                                 {
00310                                         max = e;
00311                                 }
00312                         }
00313 
00314                         return true;
00315 
00316                 }
00317 
00318 
00325                 public static PointF UnitVector( PointF a, PointF b )
00326                 {
00327                         PointF dir = new PointF( b.X - a.X, b.Y - a.Y );
00328                         double dirNorm = System.Math.Sqrt( dir.X*dir.X + dir.Y*dir.Y );
00329                         if ( dirNorm > 0.0f )
00330                         {
00331                                 dir = new PointF( 
00332                                         (float)((1.0f/dirNorm)*dir.X), 
00333                                         (float)((1.0f/dirNorm)*dir.Y) ); // normalised axis direction vector
00334                         }
00335                         return dir;
00336                 }
00337 
00344                 public static Font ScaleFont( Font initial, double scale )
00345                 {
00346                         FontStyle fs = initial.Style;
00347                         GraphicsUnit gu = initial.Unit;
00348                         double sz = initial.Size;
00349                         sz = sz * scale ;
00350                         string nm = initial.Name;
00351                         return new Font( nm, (float)sz, fs, gu );
00352                 }
00353 
00354 
00361                 public static System.Drawing.Bitmap TiledImage( System.Drawing.Bitmap image, Size size )
00362                 {
00363                         System.Drawing.Bitmap final = new System.Drawing.Bitmap( size.Width, size.Height );
00364                         
00365                         for (int i=0; i<(size.Width / image.Width)+1; ++i)
00366                         {
00367                                 for (int j=0; j<(size.Height / image.Height)+1; ++j)
00368                                 {
00369                                         Graphics.FromImage( final ).DrawImage( image, i*image.Width, j*image.Height );
00370                                 }
00371                         }
00372 
00373                         return final;
00374                 }
00375 
00376         }
00377 
00378 
00379 }

Generated on Sat Nov 5 01:04:06 2005 for NPlot by  doxygen 1.4.5