Arc de cercle

Il s'agit dans cet exemple de créer trois points O, A et B qu'on peut déplacer à l'aide de la souris puis de tracer l'arc de centre O, de rayon OA et d'angle AOB.

arc.png

arcc.cpp

/**
 * arcc.cpp
 *
 * trace trois points libres A, O, B puis l'arc de cercle de centre O de rayon OA et d'angle AOB.
 */

#include "geo2D/geo2D.h"

#define W 800
#define H 600
#define W0 400
#define H0 300

class Donnees {

public:
    GdkCursor *fleche;
    GdkCursor *hand;
    bool presse;

    repere *R;
    point_libre *A;
    point_libre *O;
    point_libre *B;
    arc_cercle *AOB;
};

static void paint (GtkWidget *widget, GdkEventExpose *event, Donnees *D) {

    cairo_t *cr;
    cr = gdk_cairo_create (widget -> window);
    cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size (cr, 12.0);

    cairo_set_source_rgb (cr, 1,1,1);
    cairo_paint (cr);
    cairo_stroke (cr);

    cairo_set_source_rgb (cr, 1, 0, 0);
    cairo_set_line_width (cr, 1.0);
    D->R->trace (cr);

    cairo_set_source_rgb (cr, 0, 0, 1);
    cairo_set_line_width (cr, 1.0);
    D->AOB->trace (cr);
    D->A->trace (cr);
    D->O->trace (cr);
    (*(*D).B).trace (cr);       // autre écriture possible
    cairo_stroke (cr);
    cairo_destroy (cr);
}

static void event_press (GtkWidget *widget, GdkEventButton *event, Donnees *D) {
    int X = event -> x;
    int Y = event -> y;
    D->presse = D->A->select (X, Y) || D->O->select (X, Y) || D->B->select (X, Y);
}


static void event_motion (GtkWidget *widget, GdkEventMotion *event, Donnees *D) {
    int X = event -> x;
    int Y = event -> y;
	if (D->presse) {
        D->A->bouge (X, Y);
	    D->O->bouge (X, Y);
	    D->B->bouge (X, Y);
        D->AOB->arc_cercle_pt_pt_pt (D->A, D->O, D->B);
    	gtk_widget_queue_draw (widget);
    } else {
        bool proche = D->A->zone (X, Y) || D->O->zone (X, Y) ||D->B->zone (X, Y);
        gdk_window_set_cursor (widget -> window, (proche) ? D->hand : D->fleche);
    }
}

static void event_release (GtkWidget *widget, GdkEventButton *bev, Donnees *D) {
    D->A->stop ();
    D->O->stop ();
    D->B->stop ();
    D->presse = FALSE;
}

int main (int argc, char *argv []) {
    GtkWidget * fenetre;
    Donnees *D;
    repere *R;
    point_libre *A, *O, *B;
    arc_cercle *AOB;

    D = new Donnees;
//    D = (Donnees *) malloc (sizeof (Donnees));

    R = new repere (W0, H0, W, H, 100.0, 100.0, 1.0, 1.0);
    A = new point_libre (1.0, 0.0, "A", R);
    O = new point_libre (0.0, 0.0, "O", R);
    B = new point_libre (0.0, 1.0, "B", R);
    AOB = new arc_cercle (A, O, B, "AOB", R);
//    AOB->sens_trigo = TRUE;

    D->R = R;
    D->A = A;
    D->O = O;
    D->B = B;
    D->AOB = AOB;

    gtk_init (&argc, &argv);

    D->fleche = gdk_cursor_new (GDK_LEFT_PTR);
    D->hand = gdk_cursor_new (GDK_HAND1);

    fenetre = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    g_signal_connect (fenetre, "expose-event", G_CALLBACK (paint), D);
    g_signal_connect (fenetre, "destroy", G_CALLBACK (gtk_main_quit), NULL);

    gtk_widget_add_events (fenetre, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
    g_signal_connect (G_OBJECT (fenetre), "button_press_event", G_CALLBACK (event_press), D);
    g_signal_connect (G_OBJECT (fenetre), "button_release_event", G_CALLBACK (event_release), D);
    g_signal_connect (G_OBJECT (fenetre), "motion_notify_event", G_CALLBACK (event_motion), D);

    gtk_window_set_position (GTK_WINDOW (fenetre), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size (GTK_WINDOW (fenetre), W, H);
    gtk_widget_set_app_paintable (fenetre, TRUE);
    gtk_widget_show_all (fenetre);

    gtk_main ();

    return 0;
}