Visualizzazione post con etichetta C. Mostra tutti i post
Visualizzazione post con etichetta C. Mostra tutti i post

venerdì 5 ottobre 2012

Numeri complessi in C/C++ con GSL e Complex

In questo esempio un paio di metodi in C e C++ per trattare i numeri primi

Fonte : http://www.relisoft.com/science/physics/images/ucircle.gif


Per il caso in C e' stata usata la libreria GNU Scientific Library (GSL) che offre, oltre a decine di altre funzioni, anche gli operatori ed i tipi per i numeri complessi. Per certi versi GSL puo' essere considerata la risposta alle Numerical Recipies in C

In C++ la gestione dei numeri complessi e' gia' inclusa nel linguaggio con un metodo piu' leggibile poiche' utilizza overloading degli operatori (nell'esempio e' stata usato in modo implicito l'overloading dell'operatore + somma)

L'esempio deve essere compilato come
g++ -Wall -O3 complessi.c -o complessi -lgsl 
-----------------------------------------------------------
#include <cstdlib>
#include <iostream>
// GSL
#include <gsl/gsl_complex.h>
#include <gsl/gsl_complex_math.h>
// C++
#include <complex>
using namespace std;

using namespace std;

int main(int argc, char *argv[])
{
    //------------ GSL
    cout << "GSL" << endl;
    gsl_complex z,w,u;
    GSL_SET_COMPLEX(&z,3,4);
    cout << "Z : Reale " << GSL_REAL (z) << ":Immaginario " << GSL_IMAG (z) << endl;
    GSL_SET_COMPLEX(&w,4,5);
    cout << "W : Reale " << GSL_REAL (w) << ":Immaginario " << GSL_IMAG (w) << endl;
    u = gsl_complex_add(z,w);
    cout << "Z+W : Reale " << GSL_REAL (u) << ":Immaginario " << GSL_IMAG (u) << endl;

   
    //------------ C++
    cout << endl << "C++" <<endl;
    complex<double> c1(3.0,4.0);
    complex<double> c2(4.0,5.0);
    complex<double> c3= c1 + c2;
    cout << "Reale : "<<real(c3) << ":Immaginario " << imag(c3) << endl;
   
    system("PAUSE");
    return EXIT_SUCCESS;
}

Pi Greco con OpenMP e GMP

Per testare il calcolo parallelo e l'Hyperthreading avevo la necessita' di un algoritmo parallelizzabile e con una convergenza piuttosto lenta per poter apprezzare le differenze di tempo di calcolo nella versione parallela e non parallela.

Scartato il calcolo di Pi Greco mediante la formula di Gauss (gia' utilizzata in un precedente post) perche' ricorsiva e quindi non parallelizzabile e scartato l'insieme di Mandelbrot perche' comunque un minimo complesso , ho provato a determinare il valore di Pi Greco mediante lo sviluppo in serie di Taylor mediante la formula


La sommatoria converge con estrema lentezza al valore di Pi Greco

Standard (tempo di esecuzione 0.049s)
-----------------------------------------------------

#include <cmath>
#include <iostream>

using namespace std;

int main()
{

float pi_s = 0.0;

for (int n=0; n<100000;++n)
{
pi_s = pi_s + (pow(-1,n)/(2*n+1));
}
cout << "Normale " << pi_s*4 << endl <<endl;

return 0;
}
-----------------------------------------------------


OMP (tempo di esecuzione 0.05s)
-----------------------------------------------------

#include <cmath>
#include <iostream>
#include <omp.h>

using namespace std;

int main()
{

float pi_s = 0.0;
#rpragma omp parallel
{
#pragma omp for reduction(+:pi_s) nowait
for (int n=0; n<100000;++n)
{
pi_s = pi_s + (pow(-1,n)/(2*n+1));
}
}
cout << "Normale " << pi_s*4 << endl <<endl;

return 0;
}

-----------------------------------------------------


GMP (tempo di esecuzione 0.1s)
-----------------------------------------------------

#include <cmath>
#include <iostream>
#include <gmp.h>

using namespace std;

int main()
{
mpf_t pi;
mpf_t transi;
mpf_t print;


int sopra;
int sotto;
//float pi_s = 0.0;

mpf_init_set_ui(pi,0);
mpf_init_set_ui(transi,1);
mpf_init_set_ui(print,0);

for (int n=0; n<100000000;++n)
{
sopra = pow(-1,n);
sotto = (2*n)+1;
mpf_set_si(transi,sopra);
mpf_div_ui(transi,transi,sotto);
mpf_add(pi,pi,transi);
mpf_mul_ui(print,pi,4);

//Calcolo eseguito senza GMP
//pi_s = pi_s + (pow(-1,n)/(2*n+1)); 
//cout << "Normale " << pi_s*4 << endl <<endl;
}
gmp_printf("Pi %.Ff\n",print);

return 0;
}



-----------------------------------------------------

L'integrazione di OMP e GMP non e' banale perche' se si uniscono i due esempi sopra riportati il compilatore riporta che la variabile pi has invalid type for ' reduction'

venerdì 28 settembre 2012

Intel C Compiler vs GCC in Mandelbrot

Ho provato a verificare la differenza tra Gcc ed il compilatore Intel C++ (icc) per quanto riguarda la velocita' e l'ottimizzazione dei calcoli
Per fare cio' e' stato impiegato il programma per generare l'insieme di Mandelbrot gia' presentato in un precedente post usando gli stessi switch di compilazione all'interno del file make



Makefile
------------------------------------------------------
main: mand_sdl.c
    /opt/intel/bin/icc -Wall -O3 mand_sdl.c -o mand_sdl_icc -lSDL
    gcc -Wall -O3 mand_sdl.c -o mand_sdl_gcc -lSDL

------------------------------------------------------

Il programma e' il seguente
 mand_sdl.c
------------------------------------------------------
 #include "SDL/SDL.h"
#include <stdio.h>

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_DEPTH 8

float re_min = -2.0;
float im_min = -1.2;

float re_max = 1.0;
float im_max = 1.2;
int iterazioni = 255;


float a,b;
float x,y,x_new,y_new;

int test;

int k,j,i;

int keypress = 0;


int main() {

SDL_Surface *screen;
Uint8       *p;

float re_factor = (re_max-re_min);
float im_factor = (im_max-im_min);
   
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, SDL_SWSURFACE);

for (i=0;i<SCREEN_HEIGHT;i++)
    {
    for (j=0;j<SCREEN_WIDTH;j++)
        {
        a = re_min+(j*re_factor/SCREEN_WIDTH);  
        b = im_min+(i*im_factor/SCREEN_HEIGHT);
      
        x = 0;
        y = 0;
        test = 0;
      
        for (k=0;k<iterazioni;k++)
            {
            x_new = (x*x)-(y*y)+a;
            y_new = (2*x*y)+b;
            if (((x_new*x_new)+(y_new*y_new))>4)
                {
                test = k;
                p = (Uint8 *)screen->pixels + i * screen->pitch + j * screen->format->BytesPerPixel;
                *p=(k%255);
                break;
                }
            x = x_new;
            y = y_new;
            }
          
        }

    }
SDL_Flip(screen);

printf("Finito\n\r");

SDL_Quit();

return(0);

}


------------------------------------------------------
Per calcolare il tempo di esecuzione e' stato usato il comando time che misura il tempo tra l'inizio e la fine dell'esecuzione

time  mand_sdl_gcc
time mand_sdl_icc

i risultati sono decisamente schiaccianti. Intel vince in velocita'

Intel
Totale 0.974
User   0.624
Sys    0.024

Gcc
Totale 1.325
User   0.948
Sys    0.020


Link al progetto

lunedì 24 settembre 2012

Autotools per creare installazioni

Per prima cosa e' stato aggiunto un file make cosi' definito

Makefile
-------------------------------------


all:  
g++ -Wall -O3 -lgmp -o pi main.cpp

clean:
rm -f main *.o

-------------------------------------
dopo di cio' si lancia il comando autoscan che genera il file configure.scan
dato che non si devono fare modifiche a mano si puo' procedere rinominandolo

mv configure.scan configure.ac

a questo punto si puo' lanciare il comando autoconf che genera il file configure
si rinomina quindi 

mv Makefile Makefile.in

lanciando il comando ./configure si avra' che il programma viene compilato ma viene anche segnalato che manca il file config.h.in (il file config.h serve a realizzare degli script di compilazione esportabili su piu' piattaforme) 

su lancia quindi il comando autoheader che crea il file config.h.in (config.h e' generato da ./configure)

per mantenere traccia della presenza del file config.h si deve inserirlo nell'header (se si intede usare autotools e' bene metterlo dall'inizio altrimenti si deve reiniziare tutta la procedura a partire da autoscan)
----------------------------------
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <gmp.h>
#include  "config.h"
using namespace std;

int main()
{
mpf_t a;
----------------------------------

al termine si puo' compilare il tutto con ./configure

Qualche tempo fa KDevelop includeva la possibilita' di usare autotools mentre al momento in cui sto scrivendo usa solo CMake. CodeBlocks  a causa del fatto di essere multipiattaforma non ha mai sviluppato l'utilizzo di autotools. Al momento l'unica IDE evoluta che faccia uso di autotools in modo automatico e' Anjuta

mercoledì 19 settembre 2012

Sqrt e compilazione di math.h

Una cosa curiosa...dopo circa 20 anni mi sono ritrovato a scrivere un programma per la ricerca di numeri primi piu' che altro per valutare l'IDE di Geany e Dev-cpp

Il programma che riporto in calce include la libreria math.h e si compila senza troppi problemi in Dev-cpp mentre portato su Linux e compilato  con

gcc -Wall  -o num_primi num_primi.c

riporta che la funzione sqrt non ha riferimenti
se invece si compila come

g++ -Wall  -o num_primi num_primi.c

curioso no???

la soluzione e' che C++ non ha necessita' di includere la funzione radice quadrata come libreria esterna mentre C si' per cui la giusta stringa di compilazione e'

gcc -Wall -lm  -o num_primi num_primi.c
Geany

Configurazione di compilazione di Geany


-----------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define MAX 100000

int indice;
int t,s;
int matrice[MAX];

int calcola(int numero)
{
int i,c;

      c = 0;
      for (i=1;i<=indice;i++)
      {
          if (((numero%matrice[i]) == 0) || (sqrt(matrice[i]) >
numero)) //se il modulo e' zero e' un divisore allora esce subito
             {
             c = 1;
             break;
             }
      }
if (c==0)
         {
             printf("%i\n\r",numero);
             return 1;
             }
             else
             return 0;
}

int main(int argc, char *argv[])
{
  matrice[0] = 1;
  matrice[1] = 2;
  indice = 1;
  for (t=3;t<=MAX;t++)
      {
      if (t%2!=0) // calcola solo se e' un numero dispari
         {
          s = calcola(t); //calcola se e' primo
          if (s==1) //se e' primo inseriscilo nella matrice
                   {
                    indice++;
                    matrice[indice] = t;
                    }
          }
      }
  return 0;
}

mercoledì 12 settembre 2012

Esempio Mandelbrot in C/Ncurses

In questo caso l'insieme di Mandelbrot e' stato restituito su un display a caratteri 80x25 usando la libreria ncurses

Il progetto puo' essere scaricato a questo link
----------------------------------------------

#include <ncurses.h>

#define SCREEN_WIDTH 80
#define SCREEN_HEIGHT 25


float re_min = -2.0;
float im_min = -1.2;

float re_max = 1.0;
float im_max = 1.2;
int iterazioni = 255;


float a,b;
float x,y,x_new,y_new;

int k,j,i;

int keypress = 0;


int main() {


initscr();
start_color();

init_pair(0,COLOR_RED,COLOR_BLACK);
init_pair(1,COLOR_RED,COLOR_RED);
init_pair(2,COLOR_RED,COLOR_GREEN);
init_pair(3,COLOR_RED,COLOR_YELLOW);
init_pair(4,COLOR_RED,COLOR_BLUE);
init_pair(5,COLOR_RED,COLOR_MAGENTA);
init_pair(6,COLOR_RED,COLOR_CYAN);
init_pair(7,COLOR_RED,COLOR_WHITE);

float re_factor = (re_max-re_min);
float im_factor = (im_max-im_min);
     

for (i=0;i<SCREEN_HEIGHT;i++)
{
for (j=0;j<SCREEN_WIDTH;j++)
{
a = re_min+(j*re_factor/SCREEN_WIDTH);
b = im_min+(i*im_factor/SCREEN_HEIGHT);

x = 0;
y = 0;

for (k=0;k<iterazioni;k++)
{
x_new = (x*x)-(y*y)+a;
y_new = (2*x*y)+b;
if (((x_new*x_new)+(y_new*y_new))>4)
{
switch (k%8)
{
case 0:
attron(COLOR_PAIR(0));
break;
case 1:
attron(COLOR_PAIR(1));
break;
case 2:
attron(COLOR_PAIR(2));
break;
case 3:
attron(COLOR_PAIR(3));
break;
case 4:
attron(COLOR_PAIR(4));
break;
case 5:
attron(COLOR_PAIR(5));
break;
case 6:
attron(COLOR_PAIR(6));
break;
case 7:
attron(COLOR_PAIR(7));
break;

}


mvprintw(i,j," ");
break;
}
x = x_new;
y = y_new;
}
       
}

}
refresh();
getch();
endwin();

return(0);
}


----------------------------------------------

Era un po' di tempo che non vedevo Mandelbrot in modalita' testo...piu' o meno dal 1991 quando un virus per DOS visualizzava l'immagine sottostante  (nel dettaglio era Tequila Virus)

Il virus era scritto in Assembler e ricordo che lo debuggai per estrarre la parte di codice relativa a Mandelbrot

Esempio insieme di Mandelbrot in C/SDL

Un esempio di creazione dell'insieme di Mandelbrot impiegando la libreria SDL per la parte grafica


--------------------------------------------

#include "SDL/SDL.h"
#include <stdio.h>

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_DEPTH 8

float re_min = -2.0;
float im_min = -1.2;

float re_max = 1.0;
float im_max = 1.2;
int iterazioni = 255;


float a,b;
float x,y,x_new,y_new;

int test;

int k,j,i;

int keypress = 0;


int main() {

SDL_Surface *screen;
Uint8       *p;
SDL_Event event;

float re_factor = (re_max-re_min);
float im_factor = (im_max-im_min);
     
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, SDL_SWSURFACE);

for (i=0;i<SCREEN_HEIGHT;i++)
{
for (j=0;j<SCREEN_WIDTH;j++)
{
a = re_min+(j*re_factor/SCREEN_WIDTH);
b = im_min+(i*im_factor/SCREEN_HEIGHT);

x = 0;
y = 0;
test = 0;

for (k=0;k<iterazioni;k++)
{
x_new = (x*x)-(y*y)+a;
y_new = (2*x*y)+b;
if (((x_new*x_new)+(y_new*y_new))>4)
{
test = k;
p = (Uint8 *)screen->pixels + i * screen->pitch + j * screen->format->BytesPerPixel;
*p=(k%255);
break;
}
x = x_new;
y = y_new;
}
       
}

}
SDL_Flip(screen);

printf("Finito\n\r");

while (!keypress)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
keypress = 1;
}
}
}
SDL_Quit();

return(0);

}
--------------------------------------------

il progetto puo' essere scaricato a questo indirizzo link

sabato 8 settembre 2012

Esempio GUI con Gtk/Glade(GtkBuilder) in C

Un ennesimo esempio con l'impiego delle GTK associate al Gui Designer denominato Glade


La caratteristica differente rispetto alle altre librerie viste finora e' la gestione in GTK delle proprieta' dello slider. Per inserire valore massimo, valore minimo e passo dello slider si deve associare un Adjustement,
Si deve quindi cliccare sulla proprieta' del wigdet e creare un nuovo adjustement, a questo punto scorrendo l'albero dei widget compare negli Oggetti un nuovo ramo; cliccando su questo e' possibile modificare le proprieta' dello slider

Schermata di Glade

Schermata di Glade . Gestione degli Adjustement
Glade permette la generazione di due formati file (che di fatto sono entrambi xml) ovvero LibGlade e LibGtkBuilder, nell'esempio di seguito e' stato usato il secondo sistema che di fatto e' quello piu' supportato da GTK2

main.c
---------------------------------------------------------

#include <gtk/gtk.h>
 GtkBuilder *gtkBuilder;
 GtkWidget *mainwin;
 GtkProgressBar *progress;
 GtkLabel *label;
 GtkHScale *scala;

void on_window1_delete_event()
{
  gtk_main_quit();
}

void on_hscale1_value_changed(GtkWidget* widget,gpointer user_data) {
   gdouble current_value = gtk_range_get_value(GTK_RANGE(scala));

 char buffer [14] = { '\0' };
 sprintf ( buffer, "%.0f", current_value);
 gtk_label_set_text(label,buffer);
 gtk_progress_bar_set_fraction(progress,current_value/100);
}


int main (int argc, char **argv) {

 gtk_set_locale();
 /* Initialize the widget set */
 gtk_init (&argc, &argv);
 /* Create the main window */
 gtkBuilder= gtk_builder_new();
 gtk_builder_add_from_file(gtkBuilder,"progressbar.xml",NULL);
 gtk_builder_connect_signals ( gtkBuilder, NULL );

 mainwin= GTK_WIDGET(gtk_builder_get_object(gtkBuilder,"window1"));
 label= GTK_WIDGET(gtk_builder_get_object(gtkBuilder,"label1"));
 progress= GTK_WIDGET(gtk_builder_get_object(gtkBuilder,"progressbar1"));
 scala= GTK_WIDGET(gtk_builder_get_object(gtkBuilder,"hscale1"));

 g_signal_connect (mainwin, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);

 g_object_unref ( G_OBJECT(gtkBuilder) );
 /* Show the application window */
 gtk_widget_show_all ( mainwin );
 /* Enter the main event loop, and wait for user interaction */
 gtk_main ();
 /* The user lost interest */
 return 0;
}

---------------------------------------------------------
progressbar.xml
---------------------------------------------------------

<?xml version="1.0"?>
<interface>
  <requires lib="gtk+" version="2.16"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkWindow" id="window1">
    <property name="title" translatable="yes">Progress Bar</property>
    <property name="default_width">200</property>
    <property name="default_height">90</property>
    <signal name="delete_event" handler="on_window1_delete_event"/>
    <child>
      <object class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkHScale" id="hscale1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="adjustment">adjustment1</property>
            <property name="lower_stepper_sensitivity">off</property>
            <property name="upper_stepper_sensitivity">off</property>
            <property name="digits">0</property>
            <property name="draw_value">False</property>
            <property name="value_pos">left</property>
            <signal name="value_changed" handler="on_hscale1_value_changed"/>
          </object>
          <packing>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="label1">
            <property name="visible">True</property>
            <property name="label" translatable="yes">0
</property>
          </object>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkProgressBar" id="progressbar1">
            <property name="visible">True</property>
          </object>
          <packing>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
  <object class="GtkAdjustment" id="adjustment1">
    <property name="upper">110</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
    <property name="page_size">10</property>
  </object>
</interface>

---------------------------------------------------------
Makefile
--------------------------------------------------------

LIBS=$(shell pkg-config --cflags --libs gtk+-2.0)
CFLAGS=-Wall -g -export-dynamic
hello: main.c
gcc -o progress_bar main.c $(LIBS) $(CFLAGS)

--------------------------------------------------------
A questo link i file di esempio

Esempio GUI con Gtk/Anjuta in C

Per la generazione di questo esempio e' stato impiegato Anjuta, una Ide che integra al suo interno Glade per la generazione dell'interfaccia.


Nella creazione di un progetto GTK vengono gia' creati i file necessari compreso un file.ui per il codice xml dell'interfaccia grafica ed i file main e callbacks per il codice da eseguite

Glade all'interno di Anjuta
Nota bene: la versione di Glade inserita in Anjuta ha un errore nella gestione dei segnali (almeno nella versione pacchettizzata in Debian stable 6). In pratica il menu a tendina associato ai widget non mostra gli eventi associati ma una lista di valori bianchi (la versione di Glade che si scarica in modo separato invece funziona in modo corretto)..si deve conoscere ed inserire a mano il nome dell'evento da gestire

Al link seguente il progetto completo per la generazione dell'esempio link

Altrimenti il codice puo' essere riscritto separando la parte della gestione degli eventi (callbacks.c) cosi' come Anjuta suggerisce implicitamente
main.c
----------------------------------------------------------------

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * main.c
 * Copyright (C) Luca Innocenti 2012 <lucainnoc@gmail.com>
 * 
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include <config.h>
#include <gtk/gtk.h>
#include "callbacks.h"
#define UI_FILE "src/gtkglade.ui"


GtkWidget* create_window (void)
{
GtkBuilder *builder;
GError* error = NULL;

builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, UI_FILE, &error))
{
g_warning ("Couldn't load builder file: %s", error->message);
g_error_free (error);
}

gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
progress = GTK_WIDGET (gtk_builder_get_object (builder, "progressbar1"));
label = GTK_WIDGET (gtk_builder_get_object (builder, "label1"));
scala = GTK_WIDGET (gtk_builder_get_object (builder, "hscale1"));

g_object_unref (builder);
return window;
}

int main (int argc, char *argv[])
{
  GtkWidget *window;
gtk_set_locale ();
gtk_init (&argc, &argv);
window = create_window ();
gtk_widget_show (window);
gtk_main ();
return 0;
}


----------------------------------------------------------------
callbacks.c
----------------------------------------------------------------

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * callbacks.c
 * Copyright (C) Luca Innocenti 2012 <lucainnoc@gmail.com>
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include "callbacks.h"

void on_hscale1_value_changed(GtkWidget* widget,gpointer user_data) {
   gdouble current_value = gtk_range_get_value(GTK_RANGE(scala));

 char buffer [14] = { '\0' };
 sprintf ( buffer, "%.0f", current_value);
 gtk_label_set_text(label,buffer); 
 gtk_progress_bar_set_fraction(progress,current_value/100);
}

void
destroy (GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
}
----------------------------------------------------------------


callbacks.h
----------------------------------------------------------------

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * callbacks.h
 * Copyright (C) Luca Innocenti 2012 <lucainnoc@gmail.com>
 */

#include <gtk/gtk.h>

GtkWidget *window;
GtkProgressBar *progress;
GtkLabel *label;
GtkHScale *scala;

void destroy (GtkWidget *widget, gpointer data);
void on_hscale1_value_changed(GtkWidget* widget,gpointer user_data);

----------------------------------------------------------------
Al link seguente il codice completo del progetto link

mercoledì 5 settembre 2012

Esempio GUI (TUI) con CDK/NCurses in C

Tecnicamente la libreria CDK non fornisce una GUI (Graphic User Interface) bensi' una TUI (Text User Interface)


L'esempio riportato e' preso integralmente dai file di esempio; a differenza dei casi precedenti questo tool mette insieme sia lo slider che la progress bar quindi e' tutto integrato in un solo comando

Per modificare il valore dello slider si usano le frecce cursore alto/basso
----------------------------------------------------------

#include <cdk/cdk.h>

int main (int argc, char **argv)
{
   /* *INDENT-EQLS* */
   CDKSCREEN *cdkscreen = 0;
   CDKSLIDER *widget    = 0;
   WINDOW *cursesWin    = 0;
   const char *title    = "<C></U>ProgressBar";
   const char *label    = "</B>Valore:";
   char temp[256];
   const char *mesg[5];
   int selection;

   CDK_PARAMS params;
   int high;
   int inc;
   int low;

   CDKparseParams (argc, argv, &params, "h:i:l:w:" CDK_MIN_PARAMS);
   high = CDKparamNumber2 (&params, 'h', 100);
   inc = CDKparamNumber2 (&params, 'i', 1);
   low = CDKparamNumber2 (&params, 'l', 1);

   /* Set up CDK. */
   cursesWin = initscr ();
   cdkscreen = initCDKScreen (cursesWin);

   /* Start CDK Colors. */
   initCDKColor ();

   /* Create the widget. */
   widget = newCDKSlider (cdkscreen,
 CDKparamValue (&params, 'X', CENTER),
 CDKparamValue (&params, 'Y', CENTER),
 title, label,
 A_REVERSE | COLOR_PAIR (29) | ' ',
 CDKparamNumber2 (&params, 'w', 50),
 low, low, high,
 inc, (inc * 2),
 CDKparamValue (&params, 'N', TRUE),
 CDKparamValue (&params, 'S', FALSE));

   /* Is the widget null? */
   if (widget == 0)
   {
      /* Exit CDK. */
      destroyCDKScreen (cdkscreen);
      endCDK ();

      printf ("Cannot make the widget. Is the window too small?\n");
      return 1;
   }

   /* Activate the widget. */
   selection = activateCDKSlider (widget, 0);

   /* Check the exit value of the widget. */
   if (widget->exitType == vESCAPE_HIT)
   {
      mesg[0] = "<C>Nessun valore selezionato";
      mesg[1] = "",
      mesg[2] = "<C>Un tasto per continuare.";
      popupLabel (cdkscreen, (CDK_CSTRING2) mesg, 3);
   }
   else if (widget->exitType == vNORMAL)
   {
      sprintf (temp, "<C>E'stato selezionato %d", selection);
      mesg[0] = temp;
      mesg[1] = "",
mesg[2] = "<C>Un tasto per continuare.";
      popupLabel (cdkscreen, (CDK_CSTRING2) mesg, 3);
   }

   /* Clean up. */
   destroyCDKSlider (widget);
   destroyCDKScreen (cdkscreen);
   endCDK ();
   return 0;
}

martedì 4 settembre 2012

Compilare SDL da riga di comando

il programma di esempio di SDL deve essere modificato nella riga di include in quanto  il file .h si trova in una sottodirectory (si devono installare le librerie di sviluppo indicate qui)

per la compilazione si deve poi usare la stringa

gcc -Wall -O3 -lSDL SDLTest.c -o SDLTest
-------------------------------------------------

#include <stdio.h>
#include <SDL/SDL.h>

#define WIDTH 640
#define HEIGHT 480
#define BPP 4
#define DEPTH 32

void setpixel(SDL_Surface *screen, int x, int y, Uint8 r, Uint8 g, Uint8 b)
{
    Uint32 *pixmem32;
    Uint32 colour;  

    colour = SDL_MapRGB( screen->format, r, g, b );
  
    pixmem32 = (Uint32*) screen->pixels  + y + x;
    *pixmem32 = colour;
}


void DrawScreen(SDL_Surface* screen, int h)

    int x, y, ytimesw;
  
    if(SDL_MUSTLOCK(screen)) 
    {
        if(SDL_LockSurface(screen) < 0) return;
    }

    for(y = 0; y < screen->h; y++ ) 
    {
        ytimesw = y*screen->pitch/BPP;
        for( x = 0; x < screen->w; x++ ) 
        {
            setpixel(screen, x, ytimesw, (x*x)/256+3*y+h, (y*y)/256+x+h, h);
        }
    }

    if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
  
    SDL_Flip(screen); 
}


int main(int argc, char* argv[])
{
    SDL_Surface *screen;
    SDL_Event event;
  
    int keypress = 0;
    int h=0; 
  
    if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
   
    if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_FULLSCREEN|SDL_HWSURFACE)))
    {
        SDL_Quit();
        return 1;
    }
  
    while(!keypress) 
    {
         DrawScreen(screen,h++);
         while(SDL_PollEvent(&event)) 
         {      
              switch (event.type) 
              {
                  case SDL_QUIT:
             keypress = 1;
             break;
                  case SDL_KEYDOWN:
                       keypress = 1;
                       break;
              }
         }
    }

    SDL_Quit();
  
    return 0;
}



lunedì 3 settembre 2012

Compilare GTK in Code::Blocks in Debian

Come compilare GTK con Code::Blocks sotto Debian
(attenzione agli apici che sono inversi)

Compiler
-------------------------------------------------
`pkg-config –cflags gtk+-2.0 gmodule-export-2.0`
`pkg-config –cflags libglade-2.0`


Linker
--------------------------------------------------------------
`pkg-config –libs gtk+-2.0 gmodule-export-2.0`
`pkg-config –libs libglade-2.0`


altrimenti a linea di comando
gcc `pkg-config –cflags libglade-2.0 –libs gtk+-2.0` `pkg-config –libs gtk+-2.0 gmodule-export-2.0` main.c

Compilare ncurses e cdk


Esempi di compilazione di sorgenti ncurses e cdk sotto Debian

per entrambe le librerie si possono scaricare i pacchetti gia' compilati (sia libreria che dev)

Nel caso di ncurses
gcc -Wall hello.c -l ncurses -o hello
---------------------------------------------------------------
#include <ncurses.h>

int main()
{
initscr(); /* Start curses mode  */
printw("Hello World !!!"); /* Print Hello World  */
refresh(); /* Print it on to the real screen */
getch(); /* Wait for user input */
endwin(); /* End curses mode  */

return 0;
}

---------------------------------------------------------------

Per compilare CDK si devono unire le librerie ncurses e cdk

gcc -Wall hello_ex.c -lcdk -lncurses -o hello_ex

(nel caso di Debian si deve modificare la riga di include presente nel pacchetto originale degli esempi di CDK per farlo puntare alla directory corretta ovvero #include <cdk.h> diventa #include <cdk/cdk.h>
---------------------------------------------------------------

#include <cdk/cdk.h>

int main (int argc, char **argv)
{
   CDKSCREEN *cdkscreen;
   CDKLABEL *demo;
   WINDOW *cursesWin;
   const char *mesg[4];

   CDK_PARAMS params;

   CDKparseParams (argc, argv, &params, CDK_MIN_PARAMS);

   /* Set up CDK. */
   cursesWin = initscr ();
   cdkscreen = initCDKScreen (cursesWin);

   /* Start CDK Colors. */
   initCDKColor ();

   /* Set the labels up. */
   mesg[0] = "</5><#UL><#HL(30)><#UR>";
   mesg[1] = "</5><#VL(10)>Hello World!<#VL(10)>";
   mesg[2] = "</5><#LL><#HL(30)><#LR>";

   /* Declare the labels. */
   demo = newCDKLabel (cdkscreen,
      CDKparamValue (&params, 'X', CENTER),
      CDKparamValue (&params, 'Y', CENTER),
      (CDK_CSTRING2) mesg, 3,
      CDKparamValue (&params, 'N', TRUE),
      CDKparamValue (&params, 'S', TRUE));

   setCDKLabelBackgroundAttrib (demo, COLOR_PAIR (2));


   /* Draw the CDK screen. */
   refreshCDKScreen (cdkscreen);
   waitCDKLabel (demo, ' ');

   /* Clean up. */
   destroyCDKLabel (demo);
   destroyCDKScreen (cdkscreen);
   endCDK ();
return(0);
   //ExitProgram (EXIT_SUCCESS);
}
---------------------------------------------------------------

In Code::Blocks gli switch di compilazione si devono inserire come nell'esempio riportato in immagine



Opencv camera calibration in cpp

Oltre che con uno script Python come visto qui la calibrazione della camera si puo' fare anche con il programma in CPP Questo il proce...