Monday, October 31, 2011

The Primary and Secondary Diagonal of a Matrix in ANSI C

Let's consider a matrix with 4 rows and 4 columns:
The primary diagonal is formed by the elements a00, a11, a22, a33 (red). The row-column condition is row=column.

The secondary diagonal is formed by the elements a03, a12, a21, 30 (blue). The row-column condition is row=numberOfRows - column -1.

We shall define and implement two functions: one for printing the primary diagonal and one for printing the secondary diagonal:
/*
 * Description:
 *  Prints the primary diagonal of a square matrix
 * Parameters:
 *  mat - a pointer to the the matrix
 *  rows - the number of rows
 *  columns - the number of columns
 * Returns:
 *  Nothing
 */
void PrintPrimaryDiagonal(int mat[][COLUMNS], int rows, int columns)
{
   int i;
   /*Checks if the matrix is square*/
   if(rows==columns)
   {
      /*Prints only the elements who are on the primary diagonal*/
      for(i=0; i<rows; i++)
      {
         printf("%d ",mat[i][i]);
      }
   }
   else
   {
      puts("Matrix is not square");
   }
}
/*
 * Description:
 *  Prints the secondary diagonal of a square matrix
 * Parameters:
 *  mat - a pointer to the the matrix
 *  rows - the number of rows
 *  columns - the number of columns
 * Returns:
 *  Nothing
 */
void PrintSecondaryDiagonal(int mat[][COLUMNS], int rows, int columns)
{
   int i;
   /*Checks if the matrix is square*/
   if(rows==columns)
   {
      /*Prints only the elements who are on the secondary diagonal*/
      for(i=0; i<columns; i++)
      {
         printf("%d ",mat[i][rows-i-1]);
      }
   }
   else
   {
      puts("Matrix is not square");
   }
}
Here's an example on how to use this functions:
#include<stdio.h>

#define ROWS 4
#define COLUMNS 4

void PrintPrimaryDiagonal(int mat[][COLUMNS], int rows, int columns);
void PrintSecondaryDiagonal(int mat[][COLUMNS], int rows, int columns);

int main(void)
{
   int matrix[ROWS][COLUMNS] = { {1,2,3,4}, {4,5,6,8}, {9,7,2,1}, {3,2,5,9} };
   puts("The primary diagonal is: ");
   PrintPrimaryDiagonal(matrix, ROWS,COLUMNS);
   puts("\nThe secondary diagonal is: ");
   PrintSecondaryDiagonal(matrix,ROWS,COLUMNS);
   return 0;
}
/*Output
The primary diagonal is:
1 5 2 9
The secondary diagonal is:
4 6 7 3
 */

Finding the Minimum and Maximum Element of an Array in ANSI C

If we want to determine the minimum element we will need a variable to retain it. This variable will be compared to all of the array's elements. If one element is less than our temporary minimum, he will become the new minimum and all the other remaining elements will be compared to this new minimum.
/*
 * Description:
 *  Returns the smallest element from the array
 * Parameters:
 * array - a pointer to an integer array
 * size - the size of the array
 * Returns:
 *  The smallest element of the array
 */
int GetMin(int *array, int size)
{
   int i;
   int min = array[0];
   for(i=0;i<size;i++)
   {
      if(min<array[i])
      {
         min = array[i];
      }
   }
   return min;
}
The same logic applies when we want to determine the maximum element of the array:
/*
 * Description:
 *  Returns the largest element from the array
 * Parameters:
 * array - a pointer to an integer array
 * size - the size of the array
 * Returns:
 *  The largest element of the array
 */
int GetMax(int *array, int size)
{
   int i;
   int max = array[0];
   for(i=0;i<size;i++)
   {
      if(max>array[i])
      {
         max = array[i];
      }
   }
   return max;
}
If we would want to return the index of the minimum element, respectively the maximum element, we would need an extra variable to hold the index. The implementations are:
/*
 * Description:
 *  Returns the index of the smallest element from the array
 * Parameters:
 * array - a pointer to an integer array
 * size - the size of the array
 * Returns:
 *  The index of the smallest element of the array
 */
int GetMinElementIndex(int *array, int size)
{
   int i;
   int min = array[0];
   int minIndex = 0;
   for(i=0;i<size;i++)
   {
      if(min<array[i])
      {
         min = array[i];
         minIndex = i;
      }
   }
   return minIndex;
}
/*
 * Description:
 *  Returns the index of the largest element from the array
 * Parameters:
 * array - a pointer to an integer array
 * size - the size of the array
 * Returns:
 *  The index of the largest element of the array
 */
int GetMaxElementIndex(int *array, int size)
{
   int i;
   int max = array[0];
   int maxIndex = 0;
   for(i=0;i<size;i++)
   {
      if(max>array[i])
      {
         max = array[i];
         maxIndex = i;
      }
   }
   return maxIndex;
}
Example:
#include<stdio.h>

int GetMin(int array[], int size);
int GetMax(int array[], int size);
int GetMinElementIndex(int array[], int size);
int GetMaxElementIndex(int array[], int size);

int main(void)
{
   /*We shall declare an array and populate it with 10 elements*/
   int array[10] = {1,2,3,4,-5,6,-1,2,-3};
   /*Searching for the minimum element*/
   int minElement = GetMin(array,10);
   /*Searching for the maximum element*/
   int maxElement = GetMax(array,10);
   /*Searching for the index of the minimum element*/
   int minElementIndex = GetMinElementIndex(array,10);
   /*Searching for the index of the maximum element*/
   int maxElementIndex = GetMaxElementIndex(array,10);
   /*Printing the results*/
   printf("Minimum element = %d at the index %d\n"
          "Maximum element = %d at the index %d\n",
           minElement,minElementIndex, maxElement,maxElementIndex);
   return 0;
}
/*Output
Minimum element = 6 at the index 5
Maximum element = -5 at the index 4
 */

Solving Gcc Math.h Linking Problem in Eclipse

If you use Eclipse/gcc and have functions that need the math.h library, you may find out that the linker can't find functions like sqrt or pow and signal it like this:

undefined reference to `pow'    Matrix.c    /TzUtils/Sources    line 152    C/C++ Problem
undefined reference to `pow'    Matrix.c    /TzUtils/Sources    line 204    C/C++ Problem

This thing happens because the library which contains math.h is not linked by default. To link it you will need to add the extra flag -Im.

In Eclipse this can be done by:
  1. Right click on your project in Project Explorer and select Properties.
  2. Go to C\C++ Build -> Settings -> Tool Settings -> Gcc Linker -> Libraries and click on green plus button to add a new library. When the dialog pops up, write m, and Eclipse will automatically add the -Im flag.



Saturday, October 29, 2011

Formatting Numbers with the DecimalFormat class in Java

As you may have read in the article on Locale Number Formats in Java, there are various standard packages that provide you classes and methods for number formatting.

Another class that it's quite useful for this purpose, it's the DecimalFormat class from the java.text package:
 import java.text.DecimalFormat;
The constructor of this class takes as parameter a string which represents a regex (regular expression) that will be used for formatting the number. The special symbols which can be used are:
  • 0 - a digit will be added to the string. If a digit does not exist in that place, 0 will be added
  • # - if a digit exists in that place, it will be added to the string
  • . - signifies the decimal separator
  • , - signifies the group separator
  • E - the string will format the number according to the e notation (scientific notation
  • % - if placed at the end of the regex, the result will be multiplied with 100 and '%' character will be appended to the end of the string
  • /uxxxx - the character with the Unicode xxxx will be appended to the formatted string
  • 'x' - used for special characters 
Examples:
        double nr1 = 3892.2344, nr2 = 24.832;
        DecimalFormat format1 = new DecimalFormat("00.00");
        System.out.println(format1.format(nr1) + " " + format1.format(nr2));
        //Output: 3892.23 24.83
        DecimalFormat format2 = new DecimalFormat("#000.00##");
        System.out.println(format2.format(nr2) + " " + format2.format(nr2));
        //Output: 024.832 024.832
        DecimalFormat format3 = new DecimalFormat("$0.00");
        System.out.println(format3.format(nr1) + " " + format3.format(nr2));
        //Output: $3892.23 $24.83
        DecimalFormat format4 = new DecimalFormat("00.E0");
        System.out.println(format4.format(nr1) + " " + format4.format(nr2));
        //Output: 39.E2 25.E0
        DecimalFormat format5 = new DecimalFormat("00.00%");
        System.out.println(format5.format(nr1) + " " + format5.format(nr2));
        //Output: 389223.44% 2483.20%
        DecimalFormat format6 = new DecimalFormat("0,0");
        System.out.println(format6.format(nr1) + " " + format6.format(nr2));
        //Output: 3,8,9,2 2,5
        DecimalFormat format7 = new DecimalFormat("\u0045 00.00");
        System.out.println(format7.format(nr1) + " " + format7.format(nr2));
        //Output: E 3892.23 E 24.83
        DecimalFormat format8 = new DecimalFormat("'E' 00.00");
        System.out.println(format8.format(nr1) + " " + format8.format(nr2));
        //Output: E 3892.23 E 24.83
One must note that unlike the NumberFormat, the DecimalFormat will not truncate the integer part and will output a number as is, even if the pattern specifies fewer digits.

Also, you can add any character you want to the format (like I added the dollar sign for format3), as long is not one of the special characters listed above. If you really need to add a character that defined as special, you can specify its Unicode(see format7) or you can put it in inside single quotes ' ' (see format8).

Also one must note that DecimalFormat is a subclass of NumberFormat, so the Locale-related methods are still available.

If your pattern does not respect the defined rules (let's say is like "E.00.00,##" - which is wrong for so many reasons), an IllegalArgumentException will be thrown.

Friday, October 28, 2011

Loading and Saving an Image in VB .NET

First we shall consider a form that contains two buttons: one button for opening an image(BUTOpen) and one button for saving an image (BUTSave) and a PictureBox control for showing the opened image. The form should look like this:
This form should also have an OnLoad event to initialize a bitmap object (which should hold your image):
Public Class ImgForm

    Private myBitmap As Bitmap

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        myBitmap = New Bitmap(PictureBox1.Height, PictureBox1.Width)
    End Sub

End Class
1.Loading an image

To load an image you will need to specify its filename. In most of the cases (especially when you need your user to specify which image to load), it's recommended to use the .NET OpenFileDialog class. This dialog allows the user to browse his computer in search for the image he wants to load. Also, you can specify filters, so the dialog will not show irrelevant files. All this can be put in a click event for the button BUTOpen.
   Private Sub BUTOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BUTOpen.Click
        Dim open As New OpenFileDialog
        open.Filter = "JPG files (*.jpg)|*.jpg|Bitmaps (*.bmp)|*.bmp|Gif(*.gif)|*.gif"
        If (open.ShowDialog = DialogResult.OK) Then
            myBitmap = System.Drawing.Image.FromFile(open.FileName)
            PictureBox1.Image = myBitmap
        End If
    End Sub
2.Saving an image

After you've ended modifying your image (see Drawing Lines, Shapes and Text in VB.NET), you may want to save it on your hard-disk. To do that you just need to specify the path where your image should be saved. Like I said before, if you want the user to select the location it's recommended to use a dialog. In this case, your best choice would be the inbuilt SaveFileDialog class (which is, in fact, very similar to the OpenFileDialog.). All this can be put in a click event for the button BUTSave.
    Private Sub BUTSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BUTSave.Click
        Dim save As New SaveFileDialog
        save.Filter = "JPG files (*.jpg)|*.jpg|Bitmaps (*.bmp)|*.bmp|Gif(*.gif)|*.gif"
        If (save.ShowDialog = DialogResult.OK) Then
            myBitmap.Save(save.FileName)
        End If
    End Sub

Thursday, October 27, 2011

Locale Number Formats in Java

Java has an in-built class in the java.text package that allows you to output numbers according to your computer's locale. 
import java.text.NumberFormat;
import java.util.Locale;
The NumberFormat class allows you to easily output real numbers, integers, percents and currency according to your default computer locale or a specified locale.

Real numbers example:
        double nr = 19.333;
        NumberFormat localeFormat 
                        = NumberFormat.getInstance();
        NumberFormat germanFormat 
                        = NumberFormat.getNumberInstance(Locale.GERMAN);
        NumberFormat usFormat 
                        = NumberFormat.getNumberInstance(Locale.US);
        System.out.println( "Number formats: ");
        System.out.println( "German format: " + germanFormat.format(nr) 
                           + "\n" 
                           +"US format:    " + usFormat.format(nr)
                           + "\n"
                           +"Locale format " + localeFormat.format(nr));

        /*==Output==
            Number formats: 
            German format: 19,333
            US format:    19.333
            Locale format 19.333
        */ 
As you can see in the output comment, the german format uses the ',' character instead of the '.' used in the US for displaying the floating point. 

Currency example:
        double nr = 19.333; 

        NumberFormat localeCurrencyFormat 
                        = NumberFormat.getCurrencyInstance();
        NumberFormat ukCurrencyFormat  
                        = NumberFormat.getCurrencyInstance(Locale.UK);
        NumberFormat japanCurrencyFormat
                        = NumberFormat.getCurrencyInstance(Locale.JAPAN);

        System.out.println(  "Currency formats: ");
        System.out.println(  "UK currency format: " 
                              + ukCurrencyFormat.format(nr) 
                              + "\n" 
                              + "Japan currency format: " 
                              + japanCurrencyFormat.format(nr)
                              + "\n"
                              +"Locale currency format " 
                              + localeCurrencyFormat.format(nr));
        /*==Output==
         Currency formats: 
         UK currency format: £19.33
         Japan currency format: ¥19
         Locale currency format $19.33
         */
For the percent and integer number format, there isn't much difference between locals (as far as I know and tried), but these methods may prove in some cases useful:

Percent and integer example:
        double nr2=392.326;
        int nr1 = 44;
        NumberFormat localePercentFormat 
                    = NumberFormat.getPercentInstance();
        NumberFormat localeIntegerFormat
                    = NumberFormat.getIntegerInstance();
        System.out.println("Percent and integer format : "  
                           + localePercentFormat.format(nr1) + " "
                           + localePercentFormat.format(nr2)
                           + "\n"
                           +"Integer format : " 
                           + localeIntegerFormat.format(nr1) + " "
                           + localeIntegerFormat.format(nr2));
        /*==Output== 
         Percent format : 4,400% 39,233%
         Integer format : 44 392
        */
A NumberFormat object also allows you to set the minimum number of digits after and before the floating point by using the methods:
  • setMaximumFractionDigits(int digits);
    • Sets the maximum number of digits after the floating point. If your number has more digits after the floating point than specified, he will be truncated.
  • setMinimumFractionDigits(int digits);
    • Sets the minimum number of digits before the floating point. If your number has less digits after the floating than specified, extra zeroes will be added to the left.
  • setMaximumIntegerDigits(int digits);
    • Sets the maximum number of digits before the floating point. If your number has more digits after the floating point than specified, he will be truncated.
  • setMinimumIntegerDigits(int digits);
    • Sets the minimum number of digits before the floating point. If your number has less digits after the floating than specified, extra zeroes will be added to the right
Minimum and maximum digits example:
         double nr1 = 44.2;
        double nr2 = 4392.326;
        NumberFormat localeNumberFormat 
                    = NumberFormat.getNumberInstance();
        localeNumberFormat.setMaximumFractionDigits(4);
        localeNumberFormat.setMinimumFractionDigits(2);
        localeNumberFormat.setMaximumIntegerDigits(3);
        localeNumberFormat.setMinimumIntegerDigits(3);
        System.out.println("Number formats: ");
        System.out.println("Percent format : "  
                           + localeNumberFormat.format(nr1) + " "
                           + localeNumberFormat.format(nr2)
                           + "\n"
                           +"Integer format : " 
                           + localeNumberFormat.format(nr1) + " "
                           + localeNumberFormat.format(nr2));
        /*==Output==    
            Number formats: 
            Percent format : 044.20 392.326
            Integer format : 044.20 392.326
        */

Useful Methods of the String Class in Java

We shall consider a string called stringTest which contains the data "The bird is the word":
String stringTest = "The bird is the word";
The string can be represented as (the upper row represent the index of the character and the lower row contains the characters):

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
T
h
e

b
i
r
d

i
s

t
h
e

w
o
r
d

1.Getting a character at a certain specified position
The function charAt(int index) returns the character at a certain index. One must note that the characters in a string are counted from 0 to length-1, not from 1 to length.
char c2 = stringTest.charAt(2); 
//c2='e'
You can also return the char as an int using codePointAt(int index). The returned integer represents the character's Unicode.
int i2 = stringTest.codePointAt(2); 
//i2=84
2.Comparing strings
To check if two strings represent the same thing you need to use the equals(String str) (uppercase and lowercase letters are not equivalent) or equalsIgnoreCase(String str) (ignores if letters are uppercase or lowercase). Using == is not correct, because == is used to compare references (addresses situated in the program's memory.
boolean be = stringTest.equals("THE BIRD IS THE WORD"); 
//be is false
boolean bc = stringTest.equalsIgnoreCase("THE BIRD IS THE WORD"); 
//bc is false
To compare strings (check if one string is "greater" or "lower" than other string), one must use the compareTo(String str) or the compareToIgnoreCase(String str). The difference between this methods is the same as in equals and equalsIgnoreCase. In both methods strings are compared lexicographically.
int ce = stringTest.compareTo("THE BIRD IS THE WORD");
//ce = 32
int cc = stringTest.compareToIgnoreCase("THE BIRD IS THE WORD");
//ce = 0  
You can also check out if a certain region of an string is the same as a certain region of another string using the methods regionMatches(int primaryStringOffset,String secondaryString, int substringOffset, int lengthOfRegion) or regionMatches(boolean ignoreCase, int primaryStringOffset,String secondaryString, int substringOffset, int lengthOfRegion). 

In the example below our primary string is stringTest ("The bird is the word") and our secondaryString is "bird is the word" (respectively "BIRD is the word"). The method will take the primary string substring starting at index 4 and ending at index 4+4 and the secondary string substring starting at index 0 and ending at index 0+4. The taken substrings will be compared lexicographically. If the substrings are identical the method will return true. Otherwise the method will return false.
boolean brm1 = stringTest.regionMatches(4, "bird is the word", 0, 4);
//true
boolean brm2 = stringTest.regionMatches(true, 4, "BIRD is the word", 0, 4);
//true
3.Concatenating strings
To concatenate a string with another string or another object (who has a toString() method defined) you can use the + operator.
String myString = "The bird" + " is the word in " + 2011;
Alternatively, you could use concat(String str)
String myString = "The bird is the ";
myString = myString.concat("the word in ");
myString = myString.concat(""+2011);
The easiest way to concatenate with an object that is not a string, is to add to that object an empty string (as in code example above).
4.Searching in a string
The String class has various methods for checking if a string contains a certain substring.
Searching if a string contains a substring
boolean bt = stringTest.contains("bird");
//true
Searching if the string starts with a certain substring (prefix)
boolean s2 = stringTest.startsWith("bird");
//true
Searching if the string ends with a certain substring (suffix)
boolean s1 = stringTest.endsWith("word");
//true
Also, by using the String class, you can determine the first occurrence or the last occurrence of a certain substring (optionally you can also specify a starting index for the search). These methods will return the starting index of the substring.
int s3 = stringTest.indexOf("bird",0);
//4
int s4 = stringTest.lastIndexOf("word", 23);
//16
5.Other operations
Checking if a string is empty (has the length equal to 0).
boolean b = stringTest.isEmpty(); 
//false
Getting the length of a string.
int l = stringTest.length(); 
//20
Replace all occurrences of a certain specified substring
String st1 = stringTest.replaceAll("The bird", "Homer Simpson");
//Homer Simpson is the word
Replacing the first occurrence of a substring
String stringTest2 = "Bird, Bird, Bird is the word";
String st2 = stringTest.replaceFirst("Bird", "Homer Simpson");
//Homer Simpson, Bird, Bird is the word"
Dividing a string in multiple substrings. The dividing is determined by a regex (a substring). The method returns an array of String.
String stArray[] = stringTest.split(" ");
//The
//bird
//is
//the
//word
Getting a string of a substring by specifying the first and last index
String st3 = stringTest.substring(0, 8);
//The bird
Transform the string to uppercase/lowercase
String st4 = stringTest.toLowerCase();
//the bird is the word
String st5 = stringTest.toUpperCase();
//THE BIRD IS THE WORD
Eliminating all whitespace from begining and end.
String stringTest3="         The bird is the word           ";
String st6 = stringTest3.trim();
//The bird is the word

LATER EDITS:
29.12.2011 : Added description for the regionMatches(...) method. Corected some mistakes.

Saturday, October 22, 2011

Drawing Lines, Shapes and Text in VB. NET

.NET has inbuilt methods for drawing graphics for your program. In order to use them you will need to instantiate a Graphics object. This object can be used do draw shapes and lines anywhere in your form, but in most cases you will prefer to use a PictureBox control as your "drawing pad". Also, in order to initialize your graphics, you will need to use a Bitmap object.

After creating your form and adding the PictureBox, you need to create an OnLoad event (which will trigger when the form is created) and add the following instructions:
    'The Form is called Form1 and the PictureBox is called PictureBox1
    Private myGraphics As Graphics
    Private myBitmap As Bitmap

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        myBitmap = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        myGraphics = Graphics.FromImage(myBitmap)
    End Sub
Drawing a Line
To draw a line you need to specify a pen and two points that belong to that line. You can specify the points using the Point/PointF class or by providing the coordinates as Integers/Singles. After you made a graphical change, you will need to update the PictureBox's image (this is a most do for all graphical changes).
Example:
        myGraphics.DrawLine(New Pen(Color.Black),
                            New Point(10, 20),
                            New Point(15, 30))
        PictureBox1.Image = myBitmap
Drawing a Rectangle
To draw a rectangle you will need to specify a Pen, the coordinates of the upper-leftmost vertex, the width and the height of your Rectangle.
Example:
        myGraphics.DrawRectangle(New Pen(Color.Black), 10, 20, 30, 50)
        PictureBox1.Image = myBitmap
Drawing an Arc
To draw an arc you will need to specify a Pen, a Rectangle area to contain the arc, the start angle and the end angle (which are specified in degrees))
Example:
        myGraphics.DrawArc(New Pen(Color.Black),
                           New Rectangle(10, 20, 30, 50), 23.5, 90.5)
        PictureBox1.Image = myBitmap
Drawing a Bezier Spline
To draw a Bezier spline you will need to specify a Pen, a starting point, two control points and an ending point. The points can be specified either by using the Point/PointF class or by inputting the coordinates for each point specifically as Integers/Singles.
Example:
        myGraphics.DrawBezier(New Pen(Color.Black),
                              New Point(20, 30), New Point(50, 80),
                              New Point(12, 30), New Point(40, 30))
Drawing an Ellipse 
To draw an ellipse you will need to specify a Pen and a rectangle area which will contain your ellipse.
Example:
       myGraphics.DrawEllipse(New Pen(Color.Black), 
       New Rectangle(100, 100, 100, 100))
       PictureBox1.Image = myBitmap
Drawing a Pie Slice
To draw a pie slice (a section from an ellipse) you will need to specify a Pen, a rectangle area to contain the pie (the entire pie), the start angle and the end angle of the section (in degrees).
Example:
       myGraphics.DrawPie(New Pen(Color.Red), 
       New Rectangle(100, 100, 100, 100), 
       -32.0, -48)
       PictureBox1.Image = myBitmap
Drawing a Polygon
To draw a polygon you will need to specify a Pen and a point vector that symbolize the polygon's vertices.
Example:
        Dim pointArray(0 To 3) As Point
        pointArray(0) = New Point(20, 30)
        pointArray(1) = New Point(40, 50)
        pointArray(2) = New Point(80, 90)
        pointArray(3) = New Point(40, 80)
        myGraphics.DrawPolygon(New Pen(Color.BlueViolet), pointArray)
Drawing Curves/Shapes
To draw a curve/shape you will need to specify a Pen and a point vector who will contain a number of points who belong to the curve. The method is based on an interpolation algorithm which tries to approximate the missing points coordinates that stand between the points you specify (the accuracy of the drawing depends on how many points you offer).
Example:
        Dim pointArray(0 To 3) As Point
        pointArray(0) = New Point(20, 30)
        pointArray(1) = New Point(40, 50)
        pointArray(2) = New Point(80, 90)
        pointArray(3) = New Point(40, 80)
        'Drawing a closed curve(shape)
        myGraphics.DrawClosedCurve(New Pen(Color.Blue), pointArray)
        'Drawing an open curve(does not interpolate the first and last point)
        myGraphics.DrawCurve(New Pen(Color.Red), pointArray)
        PictureBox1.Image = myBitmap
Drawing Text
To draw text you will need to specify the text which will be written as a String, the Font which will be used to render the text, a Brush and the point at which the drawing will start.
Example
       myGraphics.DrawString("TEXT TO BE WRITTEN", 
                             New Font("Times New Roman", 13),
                             New SolidBrush(Color.Red), New Point(80, 80))
       PictureBox1.Image = myBitmap

Tuesday, October 18, 2011

Minesweeper Clone in Java AWT

I created recently a Minesweeper clone in Java AWT as a project for one of my classes. The graphics are not great since I didn't bother to use icons or images for buttons, but the game is functional.

The screen shot bellow was taken under Linux:

Generating Random Numbers in Java

To generate random numbers in Java, you will need to call the Math.Random() method from the java.lang package (a package which is available by default, so you don't need to import it in your program).

The Math.Random() method generates a floating-point number (a double) who is in the range [0,1), where 0 represents the lower bound and 1 represents the upper bound.
double randomNumber = Math.Random();
If you want to increase the range of random values, you simply need to multiply the result of the method with the value of the upper bound you want. This way, the value produced by the method will be in the range [0,b), where 0 represents the lower bound and b represents the upper bound.
double b = 16.0;
double randomNumber = Math.Random() * b;
//randomNumber will be in the range [0,16).
If you want to increase the lower bound, you will need to add to the result generated by the method the lower bound value of your range  (that will also increase your upper bound value). This way, the value produced by the method will be in the range [a, a+1), where a represents the lower bound and a+1 represents the upper bound.
double a = 3.0;
double randomNumber = Math.Random() + a;
//randomNumber will be in the range [3,4).
If you want to produce values that are in a specific range [a,b],where a represents the lower bound and b represents the upper bound, you will need to multiply the value generated by the method with (b-a) and add a to the final result.
double a = 3.0, b=16.0;
double randomNumber = (Math.Random() *(b-a)) + a;
//randomNumber will be in the range [3,16).
If you want to obtain negative values, you will just need to switch the sign of your bound variables:
double a=3, b=16;
double rand1 = Math.Random() - a;
//rand1 will be in the range [-3, -2)
double rand2 = Math.random * (-b);
//rand2 will be in the range (-16,0];
double rand3 = (Math.Random * (a-b) -a);
//rand3 will be in the range (-16,-3]
If you want to obtain random integers, you simply typecast the result:
double a = 3.0, b=16.0;
int randomNumber = (int) ( (Math.Random() *(b-a)) + a);
//randomNumber will be in the set {3,4,...,15}

Working with Timers in Java

The Java Timer class is very important and useful when you have to create a real-time application. To create a timer you need specify a task that will be performed when the time conditions are met.

To set the time conditions and the task (which can be implemented using a nested class) you will need to call the schedule or the scheduleAtFixedRate method. You also can set an delay for the timer. The signatures for this methods are:
  • schedule(TimerTask task, Date time)
    • specifies the task and the date of execution for your task. If the date has passed, the task will be executed imediately
  • schedule(TimerTask task, Date firstTime, long period)
    • specifies the task, the date of first execution (also, if the date passed, the task will be executed imediately). The task will be executed repeatedly according to the period (which is specified in milliseconds).
  •  schedule(TimerTask task, long delay)
    • specifies the task and the delay in milliseconds until the task is executed. The task will fire only once.
  •  schedule(TimerTask task, long delay, long period)
    • specifies the task and the delay in milliseconds until the task is executed for the first time. The task will be executed repeatedly according to the period (specified as well in milliseconds).
  •  scheduleAtFixedRate(TimerTask task, Date firstTime, long period)  
    • has the same logic as schedule(TimerTask task, Date firstTime, long period), except it is optimized for tasks that need to respect the time conditions in the long run.
  •  scheduleAtFixedRate(TimerTask task, long delay, long period)
    • has the same logic as schedule(TimerTask task, long delay, long period), except it is optimized for tasks that need to respect the time conditions in the long run.
The main difference between the recurring schedule and scheduleAtFixedRate is that schedule is better for shorter  tasks like repainting a component, changing the text of a label, etc, while scheduleAtFixedRate is when you deal with absolute time (which if different from your application time)

This means that sometimes the execution of your application will be delayed by the garbage collector or some other background activity. The schedule method will not care about this delays and will continue doing the job at its own pace (this is the application time), while the scheduleAtFixedRate will reduce its period to compensate for the "external" delays, so that the absolute timing will be preserved.

So, practically, if you have a task that repeats itself every second for 10 seconds and you will use schedule, the entire execution time may be 12 or 15 seconds according to the external delays. If you use scheduleAtFixedTime, the program execution will always take 10 seconds, even if that means that the task will be repeated 3 times in second to compensate the external delays.

Bellow, I've wrote an example on how to use the Timer class to count 10 seconds and print to console the number of seconds that passed every second.
import java.util.Timer;
import java.util.TimerTask;

public class SecondsCounter 
{
    private static final int SECOND = 1000;
    private int counter, seconds;
    private Timer t1;

    private class CountSecondsTimerTask extends TimerTask
    {
        public void run()
        {
            System.out.println(counter);
            if(counter==seconds)
                SecondsCounter.this.t1.cancel(); //Kill the timer
            counter++;
        }
    }
 
    public SecondsCounter(int seconds)
    {
        this.seconds = seconds;
        this.counter = 0;
        t1 = new Timer(); //Creates new timer
        t1.schedule(new CountSecondsTimerTask(), 0, SECOND); //Schedule timer
    }
}

Mouse Events in Java AWT

Let's consider the class we had in the article on how to close a frame in Java AWT. To use a mouse event we need to define another adapter class that will extend the MouseAdapter class. The MouseAdapter subclass will also be nested in the "main" class, since it's easier this way to access the members and methods of the "main" class (just like the CloseWindowAdapter class in the previous example).
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestFrame1 extends Frame
{
    //This controls should be declared as internal variables
    //in order to be accessed by the nested classes
    private Button but;
    private Label lbl;
    
    private class CloseWindowAdapter extends WindowAdapter 
    {        
        public void windowClosing(WindowEvent we)
        {
            TestFrame1.this.setVisible(false);
            TestFrame1.this.dispose();
            System.exit(0);
        }
    }
    
    private class TestMouseAdapter extends MouseAdapter
    {
        public void mouseClicked(MouseEvent e) 
        {    
            //Checks if it's right click
            if(e.isMetaDown()==true)
                lbl.setText("RIGHT CLICK");
            //If it's not right-click, then it's left click
            else
                lbl.setText("LEFT CLICK");
        }
    }
    
    public TestFrame1()
    {
        super("Test frame");
        this.addWindowListener(new CloseWindowAdapter());
        this.setLayout(new FlowLayout());
        //Creating a button
        but = new Button("Trigger click event");
        //Adding the a mouse listener for the button
        but.addMouseListener(new TestMouseAdapter());
        //Creating a label to show what event will be triggered
        lbl = new Label("Nothing happened yet");
        //Adding the controls to the frame
        this.add(lbl);
        this.add(but);
        //Packing the frame
        this.pack();
    }
    
}
In the example above, the frame contains two controls : a button and a label. If you would right click the button, the label's text would become "RIGHT-CLICK". If you would left click the button, the label's text would become "LEFT-CLICK". The MouseEvent object can also provide several other checks:
 //Returns true if the ALT key was pressed at the time of the click
 e.isAltDown();
 //Returns true if the ALT GR key was pressed at the time of the click
 e.isAltGraphDown();
 //Returns true if the CTRL key was pressed at the time of the click
 e.isControlDown();
 //Returns true if the SHIFT key was pressed at the time of the click
 e.isShiftDown();
 //Returns a reference to the control who triggered the event
 e.getSource();
 //Returns a Point object containing the x,y coordinates 
 //relative to the source component
 e.getPoint();
The TestMouseAdapter subclass implements only the mouseClicked event trigger. The MouseAdapter ancestor class would had allowed the implementation of several other event triggers:
  • mouseEntered - occurs when the mouse cursor enters the component
  • mouseExited - occurs when the mouse cursor leaves the component
  • mousePressed - occurs when a mouse button is pressed on the component
  • mouseReleased - occurs when a mouse button is no longer pressed on the component 
The mouseClicked event trigger which we had used occurs when the component was clicked (pressed and then released).

Closing a Frame in Java AWT

To close a frame in AWT, you need to define a WindowAdapter object that will call the methods you want when the close button will be clicked. If it often beneficial to declare this new class as a nested type of the frame, since it could access the frame's methods and members.

To practically close the window, you must first make it invisible to the user and then free all the resources it occupies.
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class MyFrame extends Frame 
{
    public class CloseWindowEvent extends WindowAdapter 
    {        
        public void windowClosing(WindowEvent we)
        {
            //Make the frame invisible
            MyFrame.this.setVisible(false);
            //Free all resources
            MyFrame.this.dispose();
            //If you also want to close the program,uncomment bellow
            //System.exit(0);
        }
    }
    
    public MyFrame(String title)
    {
        super(title);
        this.add(new Label("Click X to Close"));
        //Adds the listener to the class
        this.addWindowListener(new CloseWindowEvent());
        this.pack();
    }
}

Text File I/O in Java

Reading from a Text File

To read information from a text file you will need to instantiate an object from the BufferedReader class. You will also need an InputStreamReader object and a FileInputStream, but those can be instantiated as anonymous objects.

In order to use this objects, you must import them from the java.io package.
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
To "connect" to the text file, you will need to:
BufferedReader fin = new BufferedReader(new InputStreamReader
                                       (new FileInputStream("file.txt")));
At creation the BufferedReader class throws an IOException if the string (which contains the file's path) who serves as an argument for the anonymous FileInputStream object is invalid. So, you will need to place the statement above in a try-catch block.

Once created, the BufferedReader object (which I called fin) will be able to retrieve data from the text file. The easiest way to retrieve data is by reading the text file line by line:
String line;
String pathToFile = "file.txt"
BufferedReader fin = null; 
try
 {
    fin= new BufferedReader(new InputStreamReader
                            (new FileInputStream(pathToFile)));
    do
    {
      line = fin.readLine();
      if(line==null)        //Checks if you reached end of file
        break;               //Exits the loop if end of file reached
      //TO DO CODE
    }while(line!=null);
   fin.close();             //Close the stream
  }
catch(IOException e)
{
  System.out.println(e.getMessage() +"\nProgram will be aborted");
  System.exit(0);
}
It is very important to close the stream after you no longer need it. An opened stream that is no longer used can cause your program to have an erratic behavior sometimes.

The line which you read may contain numbers or other data types which you may want to load into your specific variables. To do that you will need to use StringTokenizer class. First, the class must be imported in your program:
import java.util.StringTokenizer;
To use the StringTokenizer, you will need to instantiate an object of this type. The constructor takes as arguments the string which you want to work with and a string which contains the delimiters. The delimiters represent the characters you use to separate your fields from one another in your text.
StringTokenizer strtok = new StringTokenizer(line," ");
Let's asume that you have a text file with the following structure: name age sex

Example:
Joe 32 M

If you want to assign the data from your text file to you program's variables, you can do it like this:
string name = strtok.nextToken().toString();
int age = Integer.parseInt(strtok.nextToken().toString()),
char sex = strtok.nextToken().toString().charAt(0);

Writing to a text file
To write data to a text file, you will need to instantiate an object of the PrintStream class. You will also need a FileOutputStream object to specify the file in which you want to write. If the file does not exist, it will be created by default. It is also required to place the entire operation in a try-catch block.

You will need to import the following classes:
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.IOException
To "connect" to the text file:
PrintStream fout = new PrintStream(new FileOutputStream("file.txt"));
Once if you have access to the text file, you can simply write to it by using the PrintStream object:
fout.print("This is on line 1\n");
fout.print("This is on line 2\n");

Also, do not forget to close the output stream when you're done writing into your file.
fout.close();

Text File I/O with Strings that Contain Spaces in Java

Let's suppose that we the following class:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.StringTokenizer;

public class Person 
{
    private String name;
    private int age;
    
    public Person(String name, int age)
    {
        this.name = name;
        this.age = age;
    }
    
    public String getName()
    {
        return name;
    }
    
    public int getAge()
    {
        return age;
    }
    
    public void writeToFile(String path) throws Exception
    {
        PrintStream fout = new PrintStream(new FileOutputStream(path));
        fout.println(name + " " + age); //Problem 1
        fout.close();
    }
    
    public void readFromFile(String path) throws Exception
    {
        BufferedReader fin= new BufferedReader(new InputStreamReader
                (new FileInputStream(path)));
        String line = fin.readLine();
        StringTokenizer strtok = new StringTokenizer(line," ");//Problem 2
        this.name = strtok.nextToken().toString();
        this.age = Integer.parseInt(strtok.nextToken().toString());
        fin.close();  
    }
    
    public String toString()
    {
        return name + " " + age;
    }
}
We want to write to a text file the name and the age of the person and then we want to read it again (if you don't know how to do that check out the Text File I/O article).

The problem is that if your Person has a name like "John Doe" of age 23, when you will read the text file, you will trigger a NumberFormat exception. Why this happens? This happens because your text file looks like this: John Doe 23. The StringTokenizer produces then 3 tokens "John", "Doe" and "23" instead the 2 tokens you expect "John Doe" "23".

First solution:
To solve this issue, you will need to replace " " from the parameters of the String Tokenizer with other regex like ";" (the delimiter must be a character that is almost never used in your String. Since most names don't contain ";", this choice is pretty good).
public void readFromFile(String path) throws IOException
    {
        BufferedReader fin= new BufferedReader(new InputStreamReader
                (new FileInputStream(path)));
        String line = fin.readLine();
        StringTokenizer strtok = new StringTokenizer(line,";");//OK
        this.name = strtok.nextToken().toString();
        this.age = Integer.parseInt(strtok.nextToken().toString());
        fin.close();
    }
You will also need to modify the writeToFile method to comply with the readFromFile method:
public void writeToFile(String path) throws IOException
    {
        PrintStream fout = new PrintStream(new FileOutputStream(path));
        fout.println(name + ";" + age +";"); //OK
        fout.close();
    }
This solution is good for simple cases, but you may not want it when you will deal with classes that are more complex.

Second solution:
The second solution consists in replacing at writing/reading time the " " characters with another less common character that is almost never found in the string.
In order to do that we will create first, a "file-friendly" overloaded version of the toString method:
public String toString(boolean isFileFriendly)
    {
        if(isFileFriendly == true)
        {
            String fileFriendlyName = name;
            fileFriendlyName = name.replaceAll(" ",";");
            return fileFriendlyName + " " + age;
        }
        else
            return name + " " + age;
    }
The next stop is the writeToFile method which now will need to call the "file-friendly" toString:
public void writeToFile(String path) throws IOException
    {
        PrintStream fout = new PrintStream(new FileOutputStream(path));
        fout.println(this.toString(true); //Calling "file-friendly" toString
        fout.close();

    }
Another similar modification to the "file-friendly" toString will be needed in the readFromFile method:
public void readFromFile(String path) throws IOException
    {
        BufferedReader fin= new BufferedReader(new InputStreamReader
                (new FileInputStream(path)));
        String line = fin.readLine();
        StringTokenizer strtok = new StringTokenizer(line," ");
        //The new token will contain the file friendly name
        //not the name you want
        String fileFriendlyName = strtok.nextToken().toString(); 
        //Transforming the file friendly name into the name you
        //will want to use later in your program
        this.name = fileFriendlyName.replaceAll(";"," "); 
        this.age = Integer.parseInt(strtok.nextToken().toString());
        fin.close();
    }

Checking when an Object is Destroyed in Java

As you may know, Java has no destructors like C++ or C#. Still, there is a method that allows you to check when an object is destroyed (or "collected") by the Garbage Collector (Java's mechanism to free up the memory that is no longer used by your program).

To check this, your class needs to contain a finalize method. The finalize method also needs to call the finalize method of its superclass (all Java classes inherit the Object class by default if there is no other class specified). Your code needs (or rather say it's recommended) to be included in the try block.
protected void finalize() throws Throwable 
{
        try
        {
            //TO DO CODE
        }
        finally
        {
            super.finalize();
        }
}
This method is useful if you want to check out the exact moment when a certain object is destroyed or if you want to keep track of how many object of a certain class exist in the program's memory.

If you want to signal when an object is destroyed:
protected void finalize() throws Throwable 
{
        try
        {
            System.out.println("Object destroyed of type" 
                             + this.getClass().toString());
        }
        finally
        {
            super.finalize();
        }
}
If your class has an toString method implemented the method could look like (you could see this way the specific object who was destroyed):
protected void finalize() throws Throwable 
{
        try
        {
            System.out.println("Object destroyed : " + this.toString());
        }
        finally
        {
            super.finalize();
        }
}
If your application is not console, you will probably need to replace the println method with a more "visual" method (which depends of you GUI framework, or the control in which you want to display the information).

If you want to keep track on how many object of a certain class exist in the program's memory:
public class MemoryTest 
{
      //Static counter variable
      private static int count = 0;
      //The object's id
      private int myId;
      //Constructor
      public MemoryTest() 
      {
        myId = count;
        count++;
        System.out.println("Object created" + myID);
      }
      //Finalize method implementation
      protected void finalize() throws Throwable 
      {
        try
        {
            System.out.println("Object destroyed " + myId);
        }
        finally
        {
            super.finalize();
        }
     }
}
According to the Java reference, an object is collected by the Garbage Collector when he is no longer referenced in the program. So, theoretically, he will be destroyed. Still, this rule does not always apply, because the Garbage Collector has a tendency to free up memory only when the program's memory is full.

The Transpose, Adjugate and Inverse of a Matrix in NMat

In order to understand this article, you should read the following articles first:

1.The Transpose of a Matrix

The transpose function takes as argument a m x n matrix and returns a n x m matrix having the same values (the rows and columns are interchanged).
The transpose formula
Example:
Transpose example
Observation: A matrix doesn't need to be square in order to have a transpose.

The function's definition is:
/*
 * Description:
 *  Computes the transpose matrix of a given matrix
 * Parameters:
 *  mat   - a pointer to the original matrix
 * Returns:
 *  A pointer to the transpose matrix of the original matrix.
 * Preconditions:
 *  @mat must not be NULL
 */
NMatrix* NMatrix_Transpose(const NMatrix* mat);
The implementation of the function is:
NMatrix* NMatrix_Transpose(const NMatrix* mat)
{
   integer i = 0, j = 0;
   NMatrix* transpose = NULL;
   transpose = NMatrix_Create(mat->columns,mat->rows);
   for(i=0;i<transpose->rows;i++)
   {
      for(j=0;j<transpose->columns;j++)
      {
         transpose->data[i][j] = mat->data[j][i];
      }
   }
   return transpose;
}
2.The Adjugate Matrix of a Matrix

The adjugate matrix can be obtained analytically by replacing every element with the determinant of the minor according to the element's row and column. The sign of the new elements will be determined according to the sum of the indexes (if the sum if even, the sign will be +, otherwise the signwill be -).

Example:
For this example, we shall consider a 3x3 matrix named A
A's adjutant matrix
The function's definition is:
/*
 * Description:
 *  Computes the adjugate matrix of a given matrix
 * Parameters:
 *  mat   - a pointer to the original matrix
 * Returns:
 *  A pointer to the adjugate matrix of the original matrix.
 * Preconditions:
 *  @mat must not be NULL
 */
NMatrix* NMatrix_Adjugate(const NMatrix* mat);
The implementation of the function is:
NMatrix* NMatrix_Adjugate(const NMatrix* mat)
{
   integer i = 0, j = 0, dim = 0;
   real det = 0.0;
   NMatrix* minor = NULL;
   NMatrix* adjugate = NULL;
   if(mat->columns == mat->rows)
   {
       dim = mat->columns;
       adjugate = NMatrix_Create(dim,dim);
       for(j=0;j<dim;j++)
       {
          for(i=0;i<dim;i++)
          {
             minor = NMatrix_Minor(mat,i,j,dim-1);
             det = NMatrix_Determinant(minor,dim-1);
             adjugate->data[i][j] = pow(-1.0f,i+j+2.0f) * det;
          }
      }
   }
   return adjugate;
}
3.The Inverse Matrix of a Matrix

The inverse matrix is obtained through a simple formula:
A - the matrix who is going to be inversed
|A| - the determinant of A
C - the cofactor matrix, which by transposition becomes the adjutant matrix.

Example:

The inverse cannot be computed if the matrix is not square of if the matrix's determinant it 0.

The function's definition is:
/*
 * Description:
 *  Computes the inverse matrix of a given matrix
 * Parameters:
 *  mat   - a pointer to the original matrix
 * Returns:
 *  A pointer to the inverse matrix of the original matrix.
 * Preconditions:
 *  @mat must not be NULL
 *  @mat must not be singular (det(@mat)!=0)
 */
NMatrix* NMatrix_Inverse(const NMatrix* mat);
The implementation of the function is:
NMatrix* NMatrix_Inverse(const NMatrix* mat)
{
    NMatrix* inv = NULL;
    real det = 0.0f;
    real coeficent = 0.0f;
    if(mat->rows==mat->columns)
    {
        det = NMatrix_Determinant(mat,mat->rows);
        if(det != 0.0f)
        {
            inv = NMatrix_Create(mat->rows,mat->columns);
            coeficent = 1.0f/NMatrix_Determinant(mat,mat->rows);
            inv = NMatrix_Adjugate(mat);
            inv = NMatrix_MultiplyWithScalar(inv,coeficent);
        }
    }
    return inv;
}
4.Example
#include<stdio.h>
#include"NMatrix.h"

void PrintMatrix(NMatrix *mat)
{
   integer i = 0, j = 0;
   for (i = 0; i < mat->rows; i++)
   {
      for (j = 0; j < mat->columns; j++)
      {
         printf("%f ", mat->data[i][j]);
      }
      putchar('\n');
   }
   putchar('\n');
}

int main(int argc, char *argv[])
{
   integer i = 0, j = 0;
   NMatrix *mat = NULL;
   NMatrix *res = NULL;
   /*Creates and initializes the matrix*/
   mat = NMatrix_Create(3, 3);
   for (i = 0; i < 3; i++)
   {
      for (j = 0; j < 3; j++)
      {
         mat->data[i][j] = (real) (i + j);
      }
   }
   mat->data[0][0] = 32;

   puts("Original matrix: ");
   PrintMatrix(mat);

   res = NMatrix_Transpose(mat);
   puts("Transpose matrix: ");
   PrintMatrix(res);
   res = NMatrix_Destroy(res);

   res = NMatrix_Adjugate(mat);
   puts("Adjugate matrix: ");
   PrintMatrix(res);
   res = NMatrix_Destroy(res);

   res = NMatrix_Inverse(mat);
   puts("Inverse matrix: ");
   PrintMatrix(res);
   res = NMatrix_Destroy(res);
   return 0;
}
/*:
Original matrix:
32.000000 1.000000 2.000000
1.000000 2.000000 3.000000
2.000000 3.000000 4.000000

Transpose matrix:
32.000000 1.000000 2.000000
1.000000 2.000000 3.000000
2.000000 3.000000 4.000000

Adjugate matrix:
-1.000000 2.000000 -1.000000
2.000000 124.000000 -94.000000
-1.000000 -94.000000 63.000000

Inverse matrix:
0.031250 -0.062500 0.031250
-0.062500 -3.875000 2.937500
0.031250 2.937500 -1.968750
 */
Related Posts Plugin for WordPress, Blogger...