Showing posts with label Maths. Show all posts
Showing posts with label Maths. Show all posts

Sunday, 14 August 2016

Raspberry Pi 3 Cluster Test

The following article describes a simple test that was executed on a 4 node (1 controller + 3 workers), Raspberry Pi cluster. The purpose is to obtain reproducible measures of MPI performance that can be useful to MPI developers.  If you haven't read my article about building a Raspberry Pi 3 cluster for parallel programming, you can find it here. The test is a matrix multiplication where each node will perform the calculations of a slice of it and send the results back to the main node. The test will play with 2 main variables: a) the size of the matrix and b) the number of nodes to use to perform the calculations. This should give us the time for each calculation and the speedup.

If you haven't seen my cluster yet, here is an image:


Test Description

The test consist of the following: 
The application generates two square (NxN) matrices A and B of a variable size and defined via arguments. Matrix B is by default visible to each node so we save time sending the array to each node. Then Matrix A is generated in the master node and sliced into several chunks and sent to each individual node of the cluster. The slicing is calculated in the master node. Once each individual node of the cluster has finalised with its calculations, they send the results back to the master node to combine the results and present the resultant matrix.

The slicing mechanism works as follows:

For the example above, imagine that we have a square matrix of size 6x6. We have 4 nodes in our cluster but only three of them are available for calculations. Node 0 or master is just there to arrange initial calculations, send the values to each node and then gather the results from each individual node and display results.

The architecture is quite simple but very common in these scenarios. The beauty of it is that we can increase the number of nodes in the cluster without having to change a single line of code in the application.

As we have a 6x6 matrix, we need to split that by the number of nodes available in the system. Notice that the size of the matrix needs to be divisible by the number of nodes available in the cluster. In this case we have 6 rows and 3 nodes, so there will be 2 rows of data for each node.

Execution

You can find all the source code and results on my github project:


In there you will find the source code of matrixmultiplication.py, the shell scripts that I used to run the tests, the logs and excel files that I used to gather all the details from each node.

The first step is to calculate the matrix multiplication using just 1 node and then see what's the speedup by using additional nodes.

The sizes of the matrices for this test are defined below:

  • 12x12
  • 60x60
  • 144x144
  • 216x216

Each matrix will be run against 3 nodes and from 1 to 4 cpus on each node. Every cycle of the application runs 10 times and we use the average value for defining our results.

Here are the results for the calculations above against 1 node:

Time is in seconds and we can see that the bigger the matrix, the longer it takes to be multiplied. Remember that the complexity for a matrix multiplication is O(n3). We can easily how the graphic tends to draw a cubic function. Just increasing the size of the matrix by 50% we increased the calculation time by 300%.

Here you can see the calculation that the application performs:
Let's see what happens when we run the same matrices against our cluster:

Matrix multiplication against 3 nodes (1 CPU each):

As expected we've reduced one third the execution time for our calculations.

Let's see what happens when we introduce more CPUs:

Matrix multiplication against 3 nodes (2 CPU each):

Matrix multiplication against 3 nodes (3 CPU each):

Matrix multiplication against 3 nodes (4 CPU each):

Notice that the RPI3 has 4 CPUs and we can control the number of CPU used through the machinefile and MPI. All the cpus are defined as a node in my machinefile and I made sure that each CPU was working while monitoring them. Below is a graph showing all four cpus working on one of my nodes while running the experiment 216x216 on 12 CPUs:


Here you can see an example running 3 CPUs on each PI. Notice how the CPU's reach 100% on each PI.

Here a sample script to grab the cpu usage for linux:
If we group the graphs together we have:

We can see that the highest throughput is achieved by splitting the matrix using as many nodes as possible and return the results back. Notice that time is not linear in this case as we would suppose to go down to 4s of calculations for each node but we go down to 8s instead (calculation of 216x216 against 12 cpus). We need to consider also that there is an overhead when running MPI and this needs to be taken into consideration. In any case the throughput can be seen in the following figure representing the speedup:


Using 4 CPUs per node gives the highest throughput with a speedup of 6.34. Speedup is calculated with the division of the SeqTime/ParaTime. With this configuration we achieve an 85% of time reduction for our calculations, allowing us to perform large calculations under seconds.

There are loads of tests still to perform on the cluster and this is just a simple example as to how to code a simple example into parallel computing. Please see my project on github for more info and reference.

Jordi

Tuesday, 31 January 2012

Projecting 3D points to a 2D screen coordinate system

In this article I will put forward a small function to project 3D points to a 2D coordinate system. I have used VLO framework to display all the points after the calculation of different common functions. The most difficult part is to correctly project 3D points into a 2D perspective. Basically the way to display the points is by using a viewport and setting it up correctly. Once all the points are calculated, we need to apply the transformations matrix to position the viewport and then draw the 3D object projected into a 2D canvas from the viewport perspective. The following function will use rotation matrix to correctly position the points. 

Sample code:
procedure T3DMesh.CalcPoints();
function d3Dto2D (viewport: T3DViewPort; point : T3DPoint; centre : T2DPoint; zoom : double) : T2DPoint;
var
  p : T3DPoint;
  t : T3DPoint;
  d2d : T2DPoint;
begin
  p.x := viewport.x + point.x;
  p.y := viewport.y + point.y;
  p.z := viewport.z + point.z;

  t.x := (x * cos(viewport.roll)) - (z * sin(viewport.roll));
  t.z := (x * sin(viewport.roll)) + (z * cos(viewport.roll));
  t.y := (y * cos(viewport.pitch)) - (t.z * sin(viewport.pitch));
  z := (t.y * cos(viewport.pitch)) - (t.z * sin(viewport.pitch));
  x := (t.x * cos(viewport.yaw)) - (t.y * sin(viewport.yaw));
  y := (t.x * sin(viewport.yaw)) + (t.y * cos(viewport.yaw));
  d2d := nil;
  if z > 0 then
  begin
      d2d := T2DPoint.Create(((x / z) * zoom) + centre.x, ((y / z) * zoom) + centre.y);
  end;
  result := d2d;
end ;

var
  listPoint : TObjectList;
  i: Integer;
  j: Integer;
  x, y, z: Double;
  d2dpoint : T2DPoint;
begin
  listPoint := TObjectList.Create;
  listPoint2 := TObjectList.Create;

  x :=-2.0;
  y := -2.0;
  z := 0.0;
  for i := 0 to 40 do
  begin
    y := -2.0;
    for j := 0 to 40 do
    begin
      z := cos((x * x + y * y) * 2) * exp(-1 * ((x * x) + (y * y)));
      listPoint.Add(T3DPoint.Create(x,y,z));
      y := y + 0.1;
    end;
    x := x + 0.1;
  end;

  for i := 0 to listPoint.count - 1 do
  begin
    d2dpoint := d3Dto2D(viewport, T3DPoint(listPoint[i]), centre, zoom);
    if Assigned(d2dpoint) then
      listPoint2.Add(d2dpoint);
  end;
  listPoint.Free;
end;


Examples:
z = sin(x) * cos (y):

z = cos((x^2+y^2)*2) * exp-(((x^2)+(y^2))):

z = x^2*exp(-x*x)*y^2*exp(-y*y):


With parameters:

Related links:

Monday, 22 August 2011

Building my own Delphi Physics Engine part IX

I'm quite familiar with GDI, the graphics provided under Microsoft and which is widely used in Windows applications. TDPE is now ready to use Direct2D as now it's fully supported by Delphi 2010 and XE. According to MSDN, Direct2D is: a hardware-accelerated, immediate-mode, 2-D graphics API that provides high performance and high quality rendering for 2-D geometry, bitmaps, and text. The Direct2D API is designed to interoperate well with GDI, GDI+, and Direct3D.
As I'm testing this under Windows Vista, I've had to upgrade my windows version to Service Pack 2 and then I've installed the following update (KB971512 - The Windows Graphics, Imaging, and XPS Library contain the latest advancements in modern graphics technologies for gaming, multimedia, imaging and printing applications.). Direct2D is already installed in Windows 7.

We can use the same methods from TCanvas for our TDirect2DCanvas as they derive from the same ancestor TCustomCanvas. But you need to check the documentation for differences in the way they work.

A simple way to use Direct2D is as follows:

uses
    Direct2D, D2D1;

procedure Paint();
begin
    if TDirect2DCanvas.Supported then
    begin
        d2dCanvas := TDirect2DCanvas.Create(Canvas, ClientRect);
        try
            d2dCanvas.RenderTarget.beginDraw;
            d2dCanvas.RenderTarget.Clear(D2D1ColorF(clBlack));
            d2dCanvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
            // drawing goes here
            Paint(d2dCanvas);
            d2dCanvas.RenderTarget.EndDraw;
        finally
            FreeAndNil(d2dCanvas);
        end;
    end;
end;

Here is the result of the Physics Engine using a Direct2D Render and a GDI Render:





You will see the difference when switching from GDI to Direct2D as the performance is quite different. When it comes to Direct2D, my computer is getting quite slower as my graphic card is not powerful at all and we can see that it takes a while to render the image.


GDI uses Pixel graphics but Direct2D can supports vector graphics as well, in which mathematical formulas are used to draw the lines and curves. Vector graphics provides high quality rendering independent of resolution of the device, while the pixelated graphics has dependency with resolution which may results in choppy graphics.

Most of the GDI APIs are not using anti-aliasing and transparency. Ofcrouse there are functions to do so but always there’s programming cost for taking advantage of these features. Also if we apply transparency and anti-aliasing, the computations are done using CPU. Direct2D can take advantage of graphics hardware and delegate the computationally intensive tasks to GPU


Get the latest version here: ThundaxBallDemo v1.584.
Interaction:
'd' will drop a box with a random colour and a constant angular velocity.
'f' will drop a circle with a random colour and a constant angular velocity.
'mouse interaction' mouse is able to grab items.
'q' Enable/Disable GDI or Direct2D rendering.

Note: You need to have installed Direct2D to run the app using Direct2D, otherwise GDI will be used.

Related links:

Wednesday, 10 August 2011

Building my own Delphi Physics Engine part VIII

TDPE is almost ready and it will not take long to release the first stable library!. I am eager to continue working on the project trying to sort out different physic scenarios  to make my dynamic engine even more realistic. Do not hesitate to give it a try as you will find the experience quite interesting. I am still working on the n-edge object and the cutting tool and trying to refactor all the code to cope with a layer architecture. Using this concept, I want to structure my system in a way that every component works using a certain level of abstraction. As you see in the next figure, every object is allocated in the screen while there is another layer which is responsible for the collision detection and another one for the forces interaction. You will notice in the video that there are still little issues to tackle regarding the object interaction as sometimes we can experience overlapping.


In the figure above, you can see that now the items are not rigid and they interact with each other as they were real items. Notice that the square item will go through the round shape of the circle.



Enjoy the video!.

Get the latest executable here: ThundaxBallDemo v1.504.
Interaction:
'd' will drop a box with a random color and a constant angular velocity
'f' will drop a circle with a random color and a constant angular velocity
'mouse interaction' mouse is able to grab items

Related links:

Tuesday, 21 June 2011

Building my own Delphi Physics Engine part VII

After several weeks working on my TDPE I think I managed it to get the desired outcome and now the displayed items show more realistic features. In my previous versions, neither angular velocity nor mass was interacting in terms of moving an object and now, using different mathematical algorithms, the gravity and angular velocity are considered for every item. That means that as soon as a collision is originated, the resultant force will lean back or forward the object and it will be rotating or moving until the forces of the system reach a value close to zero.
This new approach has included a massive refactoring of the existing code to cope with this new behaviour that will deliver spectacular performances. During the following weeks I'm going to  focus on the cutting tool as now I only have to extent the 4-edges collision object to n-edges. Once I have the n-edges collision object then I would be able to generate small chunks of it and each piece would have its own behaviour giving you the feeling that the object has really been broken.


As it's shown in the image, when most or more than a half of the object is out of the base (in blue), the red box should lean forward and fall according to the laws of physics (falling using rotation instead of falling straight how it was before in previous versions).

The following video will show the results of applying the latest algorithms to my Engine:


Enjoy the video!.

Get the latest executable here: ThundaxBallDemo v1.349.
If you want to drop a box, press 'd' and a new red box will fall.

Related links:

Sunday, 1 May 2011

Polygonal approximation to circle

In order to be able to tackle the "cutting tool" for my TDPhysicsEngine, I need to work with polygon approximations instead of a full drawn circle using the Canvas.Ellipse Delphi function. To achieve this in the view layer is as easy as using Canvas.Polygon function to draw a polygon using a list of calculated points. To calculate the points, we need to divide the circle in discrete chunks and then let the function draw the lines between points. The main reason what I'm doing that is to be sure that I can cut up a polygon and then use the resulting pieces as new objects that will behave as independent objects:


The function below will help you to draw the polygon:

procedure GDIRenderer.CircleApproximation(xcenter, ycenter, Radius, Rotate: Double; style: TStyle);
var
    PArrow: array [1 .. points] of TPoint;
    i: integer;
    theta: Double;
    x, y : double;
    beforeBrushColor, beforePenColor: TColor;
    beforePenWidth: integer;
begin
    beforeBrushColor := FCanvas.Brush.color;
    beforePenColor := FCanvas.Pen.color;
    beforePenWidth := FCanvas.Pen.Width;

    FCanvas.Pen.color := style.PenColor;
    FCanvas.Pen.Width := style.penWidth;
    FCanvas.Brush.color := style.BrushColor;

    for i := 1 to points do
    begin
        theta := Pi * ((i-1)/(points/2));
        x := xcenter + (Radius* Cos(theta));
        y := ycenter + (Radius* Sin(theta));
        PArrow[i] := Point(Round(x), Round(y));
    end;
    FCanvas.Polygon(PArrow);

    FCanvas.Brush.color := beforeBrushColor;
    FCanvas.Pen.color := beforePenColor;
    FCanvas.Pen.Width := beforePenWidth;
end;

The big difficulty here is to model this behaviour in the model. I need to work more and think about it because for the moment it's adjusted as a sphere and it's not a good approximation.

Building my own Delphi Physics Engine part VI

I've been quite busy lately and in this article I've focused on the collision container. As you'll see in the following images and video, the spheres will be bouncing around, colliding with one another and with the surfaces inside the container that holds the entire motion of the system. With a simple tweak, the physics engine is able to display the unseen forces when objects are being "kicked". The key feature is that I want to show the resultant vectors that are involved in the collisions and the movement so the observant would have an idea of what's happening inside the model and which forces are being generated.

In the image below, you'll see the resultant force when the sphere has collided with the surface beneath. This leads me to the description of the Elastic collision equations


The following image shows all the vectors involved in the collision:


And the video showing the dynamics:


You can download from here the last version of the application: ThundaxBallsDemo v1.172 that is digitally signed (once the file is downloaded, right click, properties and go to the certificate and install it) to increase security. To add more spheres press 'a' and 's'. To cut one of the bridges press 'z' and play!.

I also have created the new logo for the Engine, let me know if you like it!.

In few months the library would be ready here:


Thanks for reading! and do not hesitate to leave any comment!.

Saturday, 5 February 2011

Building my own Delphi Physics Engine part V

Today I felt inspired (after parts I, II, III and IV) and I tried to do a cloth simulation in the Thundax Physics Engine. There are a lot of things to do, but at least I can start simulating different components very fast without too much implementation. I saw one amazing implementation of the "processing cloth" in JRC313.com. Even though the applet is written in JavaScript, the performance is quite impressive and it's a nice work.

but, How it works?
"Every line in the cloth simulation is technically called a constraint and every point is a point mass (an object with no dimension, just location and mass). All the constraints do is control the distance between each point mass. If two points move too far apart, it will pull them closer. If two points are too close together, it will push them apart. The cloth is really then just a collection of constraints and point masses in a never ending struggle."

using Relaxation in simple linear systems:
In the case of this cloth simulation all I needed to do was try satisfying the constraints as fast as I can. For things like simple rope simulations it may be necessary to satisfy several times (maybe 4 or 5). The more times you satisfy, the more rigid the constraint becomes. This process is known as relaxation and is amazing!. The displacement will then be of the form y(t) = Ae − t / Tcos(μt − δ). The constant T is called the relaxation time of the system and the constant μ is the quasi-frequency. (Wikipedia).

In the following videos you'll be able to check the performance of the simulated cloth. I took advantage of my previous bridge (spring + particles) and I've concatenated a series of bridges to set up a virtual cloth. Now the movement is quite astonishing:


In the second video I'm showing one of the new features for the next release: "the cutting tool". I still need to think about it, but for simple objects it could be simple to cut an object and see its reaction, like in the next video:


You can download the last version of the executable file here: thundax Balls demo v1.52. And maybe in a near future you'll be able to see something similar to the Puzzler for iPhone.


Other interesting video about physics and games is Crayon Physics from Petri Purho:

I hope you enjoy the videos!

Related Links:

Friday, 4 February 2011

Building my own Delphi Physics Engine part IV

I'm still working on my solution, but I can advance you a preview of the smoothness of the application. I have improved the bridge particle and its interaction with external events. I'm working on a TStyle class that will enhance the GDIRender allowing the different particles to have a custom style on the screen and refactor all the classes to improve the scalability and interoperability of the Engine. If you are interested on testing the application, you can get the latest version of it from here: Thundax Ball Demo v1.1. In this version you will notice the improved interaction with the mouse and the circle particles. I have to work out a solution for the other particles, but I'm still designing the whole product and I need to test some of the features that I want to release in the next version. Once the version is ready, I will upload it on Sourceforge just in case you feel the urge to play with it!.
Here you can see the new performance:


Wednesday, 2 February 2011

Building my own Delphi Physics Engine part III

Now I'm working on the interactive part (Controller). Since now I only have developed the model and the view section of the MVC pattern and I'm implementing and testing the controller part. The main problem is that the Engine is quite simple to implement and use until the visual control appears. Now I have to take into account all the events that come from the outside (mouse, keyboard) and add subscribers to the object particles. With the design that I've implemented it is easy to make extensible the model and the view section because the Engine follows the "low cohesion high coupling" principle. My sister challenged me by trying to do something similar to the ruicode project, where its ofxRuiPhysics2d project (Simple 2d physics addon for OF (OpenFrameworks) using the Verlet integrator where it includes particles, collisions and springs) is quite astonishing. Here you can see one of its videos:


And here is my project: Thundax balls demo.exe, a Delphi win32 application that will start a demo with balls, springs and collisions. In the following videos you'll see different performances of my tests. In the first video I'm trying to simulate the environment with all the forces playing at the same time, and in the second video you can see myself using the mouse interacting with the balls and the springs.


I hope you enjoy the videos!.

Related links:

Related frameworks:
It's amazing the large amount of physics Engine that are available on the net. I just google the words "Physics Engine" and here are the results:
Javascript, C, and Java Frameworks:
ActionScript Frameworks:

3D and Realistic Frameworks:

Sunday, 16 January 2011

Depth of field calculator

This year I'm going to start talking about one of my passions: Photography. And for starting, here you can get one of my last applications: Thundax Depth of Field Calculator. With this Delphi win32 front-end application you'll be able to calculate the Depth of field (the portion of a scene that appears sharp in the image) measurements needed in photography. You need to select the CoC (Circles of Confusion) in microns from the sidebar (there is a little sheet with the normal values for different types of cameras), the focal length from the choices, and the lens aperture from the choices. Enter the subject distance in meters from the lens and the calculated values are returned for various other designations of subject distance as well as the near limit of acuity, far limit of acuity, and the total depth of field, all in both meters and feet, accurate and rounded. The calculations are based on the very well known on-line DoF javascript calculator.

In my application you can see the difference of using different apertures (F numbers) while taking the photo. In the example you can see that the distance is the same, but the DoF grows. The aperture is getting smaller and smaller, and the shutter speed is getting longer to compensate. The distance and aperture both play a big role in depth of field. You you want to play with it, for example: for a short depth of field (blurry background) get close and use a lower f-stop. And for a long depth of field (clear all the way through) get farther away and use a higher f-stop. The following example will help you to understand better the DoF:
Picture from: Photo Basics.
The different calculations are the following ones:
procedure TDoF.Calc(Sender: TObject);
var
    focal: integer;
    aperture: double;
    CoC: double;
    Hyperfocal: double;
    distance: double;
    NearF, FarF, doftotal: double;
begin
    distance := StrToFloat(Edit2.Text) * 1000 * 0.3048;
    focal := getFocal(ComboBox1.Text);
    aperture := getAperture(ComboBox2.Text);
    CoC := StrToFloat(Edit1.Text);
    photovalues.Values['Subject distance (inches)'] := FloatToStr(StrToFloat(Edit2.Text) * 12) + ' in';
    photovalues.Values['Subject distance (meters)'] := FloatToStr(StrToFloat(Edit2.Text) * 0.3048) + ' m';
    photovalues.Values['Subject distance (millimeters)'] := FloatToStr(StrToFloat(Edit2.Text) * 0.3048 * 1000) + ' mm';
    Hyperfocal := 0;
    if (aperture * CoC) > 0 then
        Hyperfocal := Sqr(focal) / (aperture * CoC);
    photovalues.Values['Hyperfocal distance for this lens/aperture combination (meters)'] := FloatToStr(Hyperfocal) + ' m';
    photovalues.Values['Hyperfocal rounded distance for this lens/aperture combination (meters)'] := FormatFloat(f, Hyperfocal) + ' m';
    photovalues.Values['Hyperfocal distance for this lens/aperture combination (ft)'] := FloatToStr(Hyperfocal * feet) + ' ft';
    photovalues.Values['Hyperfocal rounded distance for this lens/aperture combination (ft)'] := FormatFloat(f, Round(Hyperfocal * feet)) + ' ft';
    NearF := ((Hyperfocal * 1000 * distance) / ((Hyperfocal * 1000) + (distance - focal))) / 1000;
    photovalues.Values['Near limit of acceptable sharpness (meters)'] := FloatToStr(NearF) + ' m';
    photovalues.Values['Rounded near limit of acceptable sharpness (meters)'] := FormatFloat(f, Round(NearF)) + ' m';
    photovalues.Values['Near limit of acceptable sharpness (ft)'] := FloatToStr(NearF * feet) + ' ft';
    photovalues.Values['Rounded near limit of acceptable sharpness (ft)'] := FormatFloat(f, Round(NearF * feet)) + ' ft';
    FarF := ((Hyperfocal * 1000 * distance) / ((Hyperfocal * 1000) - (distance - focal)) / 1000);
    if FarF < 0 then
    begin
        photovalues.Values['Far limit of acceptable sharpness (meters)'] := 'Infinity';
        photovalues.Values['Rounded far limit of acceptable sharpness (meters)'] := 'Infinity';
        photovalues.Values['Far limit of acceptable sharpness (ft)'] := 'Infinity';
        photovalues.Values['Rounded far limit of acceptable sharpness (ft)'] := 'Infinity';
    end
    else
    begin
        photovalues.Values['Far limit of acceptable sharpness (meters)'] := FloatToStr(FarF) + ' m';
        photovalues.Values['Rounded far limit of acceptable sharpness (meters)'] := FormatFloat(f, Round(FarF)) + ' m';
        photovalues.Values['Far limit of acceptable sharpness (ft)'] := FloatToStr(FarF * feet) + ' ft';
        photovalues.Values['Rounded far limit of acceptable sharpness (ft)'] := FormatFloat(f, Round(FarF * feet)) + ' ft';
    end;
    doftotal := Round(FarF - NearF);
    if doftotal < 0 then
    begin
        photovalues.Values['Total depth of field (meters)'] := 'Infinity';
        photovalues.Values['Total rounded depth of field (meters)'] := 'Infinity';
        photovalues.Values['Total depth of field (ft)'] := 'Infinity';
        photovalues.Values['Total rounded depth of field (ft)'] := 'Infinity';
    end
    else if (doftotal >= 0) and (doftotal < 0.001) then
    begin
        photovalues.Values['Total depth of field (meters)'] := '> 1 mm';
        photovalues.Values['Total rounded depth of field (meters)'] := '> 1 mm';
        photovalues.Values['Total depth of field (ft)'] := '> 0.0393 in';
        photovalues.Values['Total rounded depth of field (ft)'] := '> 0.0393 in';
    end
    else
    begin
        photovalues.Values['Total depth of field (meters)'] := FloatToStr(doftotal) + ' m';
        photovalues.Values['Total rounded depth of field (meters)'] := FormatFloat(f, Round(doftotal)) + ' m';
        photovalues.Values['Total depth of field (ft)'] := FloatToStr(doftotal * feet) + ' ft';
        photovalues.Values['Total rounded depth of field (ft)'] := FormatFloat(f, Round(doftotal * feet)) + ' ft';
    end;
end;

Tell me if it's useful to you and if you need any other calculations.
PS: The program is free for non-commercial use.


Related links:

Monday, 20 December 2010

Piecewise function plotter

I've been working lately on a front-end application to draw and generate the piecewise-defined functions that are mainly used for the input fuzzy sets. This application is developed with Delphi and for generating the outputs it uses the GNUplot and the LateX equation editor. The application is called Thundax Piecewise v1.1 and you can download it from here. This win32 installation package contains the required files to work with the GNUplot. This software is for academical purposes and with it you can define the piecewise-defined functions without wasting your time trying to draw the graphs and the equations.

Using the application:
If you want to get the equations from the previous image, you only need to add the points (x,y) (defined as 4 points per graph), add the equation description, the range and the number of samples:
The description of the parameters:
  • Points per graph: default value = 4. Number of points that are used to define the function:
  • Range-x: Default value [0:30]. Range to be displayed at x-axis.

  • Range-y: Default value [-0.1:1.1]. Range to be displayed at y-axis.
  • Samples: default value = 1. Number of samples for the x-axis. In a range from 1 to 10 with a sample of 1 it will show all the numbers.

Once everything is done, you just need to let the application generate the graph output automatically using GNUPlot (If the function is not plotted, check the script and execute it into the GNUplot command prompt):
And then copy-and paste the output script to Latex editor and get the piecewise function for each one:
The only thing the applications does, is to parse the input data and transform it as scripts for the GNUplot and Latex. The conversion is pretty simple and the scripts examples are like these:
GNUPlot Script example:
cold(x)=(x<=40? 0: cold2(x))
cold2(x)=(x<=40 & x > 40? 1: cold3(x))
cold3(x)=(x<=50 & x > 40? -0.1*x + 5: cold4(x))
cold4(x)=(x<=50 & x > 50? 1: cold5(x))
cold5(x)=(x>50? 0:0)
cool(x)=(x<=40? 0: cool2(x))
cool2(x)=(x<=55 & x > 40? 0.066667*x  -2.666667: cool3(x))
cool3(x)=(x<=55 & x > 55? 1: cool4(x))
cool4(x)=(x<=65 & x > 55? -0.1*x + 6.5: cool5(x))
cool5(x)=(x>65? 0:0)
justright(x)=(x<=60? 0: justright2(x))
justright2(x)=(x<=65 & x > 60? 0.2*x  -12: justright3(x))
justright3(x)=(x<=65 & x > 65? 1: justright4(x))
justright4(x)=(x<=70 & x > 65? -0.2*x + 14: justright5(x))
justright5(x)=(x>70? 0:0)
warm(x)=(x<=65? 0: warm2(x))
warm2(x)=(x<=75 & x > 65? 0.1*x  -6.5: warm3(x))
warm3(x)=(x<=75 & x > 75? 1: warm4(x))
warm4(x)=(x<=85 & x > 75? -0.1*x + 8.5: warm5(x))
warm5(x)=(x>85? 0:0)
hot(x)=(x<=80? 0: hot2(x))
hot2(x)=(x<=90 & x > 80? 0.1*x  -8: hot3(x))
hot3(x)=(x<=90 & x > 90? 1: hot4(x))
hot4(x)=(x<=90 & x > 90? 1: hot5(x))
hot5(x)=(x>90? 0:0)
set yrange[-0.1:1.1]
set xtics 0, 15
set grid
set samples 1001
bind Close "exit gnuplot"
plot [40:90] cold(x) ,cool(x) ,justright(x) ,warm(x) ,hot(x) 

Notice that we use the function bind Close "exit gnuplot" to bind the exit of the application once the user has closed the plotted graph. (And I think this function is available since version 4.4).
Latex Script example:
cold(x)=\begin{Bmatrix}{0}&\mbox{if}& x\leq40\\{1}&\mbox{if}& 40< x \leq40\\{-0.1*x + 5}&\mbox{if}& 40< x \leq50\\{1}&\mbox{if}& 50< x \leq50\\{0}&\mbox{if}& x > 50\end{matrix}\\
cool(x)=\begin{Bmatrix}{0}&\mbox{if}& x\leq40\\{0.066667*x  -2.666667}&\mbox{if}& 40< x \leq55\\{1}&\mbox{if}& 55< x \leq55\\{-0.1*x + 6.5}&\mbox{if}& 55< x \leq65\\{0}&\mbox{if}& x > 65\end{matrix}\\
justright(x)=\begin{Bmatrix}{0}&\mbox{if}& x\leq60\\{0.2*x  -12}&\mbox{if}& 60< x \leq65\\{1}&\mbox{if}& 65< x \leq65\\{-0.2*x + 14}&\mbox{if}& 65< x \leq70\\{0}&\mbox{if}& x > 70\end{matrix}\\
warm(x)=\begin{Bmatrix}{0}&\mbox{if}& x\leq65\\{0.1*x  -6.5}&\mbox{if}& 65< x \leq75\\{1}&\mbox{if}& 75< x \leq75\\{-0.1*x + 8.5}&\mbox{if}& 75< x \leq85\\{0}&\mbox{if}& x > 85\end{matrix}\\
hot(x)=\begin{Bmatrix}{0}&\mbox{if}& x\leq80\\{0.1*x  -8}&\mbox{if}& 80< x \leq90\\{1}&\mbox{if}& 90< x \leq90\\{1}&\mbox{if}& 90< x \leq90\\{0}&\mbox{if}& x > 90\end{matrix}\\

I'm still working on this project and for the next milestone I'll try to add the Weighted average method to calc the area of the graph and the ability to save the data of the project.

Related links:

Friday, 10 December 2010

Building my own Delphi Physics Engine part II

Going on with my DPE (Delphi Physics Engine) I've improved my old version (Building my own Delphi Physics Engine Part I) of the Jansen Mechanism by creating the rest of the legs displaced 120º each one. I've been fixing the damping level of the framework just to be sure that the movements are as realistic as possible. In this version, the movement is quite realistic and we can trace the movement of the leg by plotting the kinetic analysis:

A physics engine is computer software that provides an approximate simulation of certain simple physical systems, such as rigid body dynamics (including collision detection), soft body dynamics, and fluid dynamics, of use in the domains of computer graphics, video games and film. Their main uses are in video games (typically as middleware), in which case the simulations are in real-time. The term is sometimes used more generally to describe any software system for simulating physical phenomena, such as high-performance scientific simulation. Wikipedia.

Here you can see the CGI result with the hanging version of the Jansen mechanism with one leg and with three legs:

And the final version with the development of the Jansen machine. In this version (Thundax Test Forces v2.exe) if you press 'p' the machine will start walking and if you want to change direction, you only need to press the 'z'.

What's next?. Now I'll try to reproduce different physics systems and show how it goes. The Easy Java Simulations tool, offers a wide range of examples that I would like to try.
Enjoy the learning!.

Related Links:

Friday, 3 December 2010

Building my own Delphi Physics Engine part I

 These days I've been working on my own Delphi Physics Engine based on the very well known APE (ActionScript Physics Engine) with some improvements that will help developers to build models very fast. In this beta version I've done the following improvements:
  • Enhance user performance.
  • Drastic reduction of Memory leaks.
  • Improve the interoperability between objects.
  • Improve maths algorithms to collision detection.
  • Use the VLO GDI Render to perform the drawing of the shapes.
In this first insight into the Engine, I'm going to show you a model of the Jansen mechanism, a kinetic sculpture that can move with the help of several pairs of legs.


I've built my own model taking advantage of the physic engine and imagination!.
Here you can see my own model:
The movement is still not very well performed, but it's due to the measures of the different parts of the sculpture. As for the calculation points, I've used the next template:
You can download the demo project from here (Thundax Test Forces). To play with the application, you only need to press 'z' to start the kinetic sculpture, and as for the objects below the sculpture, press 'd' and you'll force a collision between two objects.

The next days I'll be improving the model (you can see the kinetic analysis that is plotted below the sculpture) and adding the extra foot to perform a fully movement.

Enjoy the learning!.

Related links: