[ANSI C] Rysowanie grafu w GTK

0

Witam,

mam problem z narysowaniem grafu. Przygodę z GTK dopiero zacząłem i nie mam pomysłu jak się za to zabrać. Graf ma być zwykłą siatką punktów równo oddalonych od siebie w pionie i poziomie (tak jak przecięcia linii w zeszycie w kratkę). Z kazdego punktu można iść w 8 stron. Do góry, górny prawy skos, w prawo itd. Struktura punktu zawiera 8 zmiennych boolowskich, jeżeli któraś z nich przyjmuje wartość true to można iść w tym kierunku. Jeżeli z punktu A można dojść do punktu B oraz z punktu B można dojść do A, to pomiędzy nimi powinna być narysowana krawędź. Bardzo proszę o pomoc i ewentualne sugestie do struktur i funkcji. Z góry dziękuję.

0

Nie znajdzie się nikt na forum, kto ogarnia GTK? Nie wierzę, że to zadanie jest zbyt trudne dla forumowiczów :). Proszę tylko o wskazówki, a nie gotowe rozwiązanie.

1

Narysuj i daj link jak by to miało wyglądać :)

Musisz skorzystać z kontrolki obszaru rysunkowego GtkDrawingArea i rysować na niej funkcjami z biblioteki Cairo.
To może Ci pomoże http://zetcode.com/gfx/cairo

Tu http://cpp0x.pl/forum/temat/?id=8423 masz przykład jak rysować wykres na kontrocle GtkDrawingArea.

0

Na forum jest wielu użytkowników którzy nie mieli by z tym problemu, ale na twoje nieszczęście nie ma tutaj takich którzy zrobią dla Ciebie gotowca.

2

Poniżej masz wstęp do rysowania grafów. Twoje zadnie to zaimplementować strukturę z jakiej będzie korzystał graf, oraz algorytm obliczjący współrzędne w którym miejscu należy narysować okrąg:

/* Kompilacja: gcc graf.c -o graf `pkg-config --cflags --libs gtk+-2.0` */

#include <gtk/gtk.h>

#define MIN_X 20
#define MIN_Y 20
#define PROMIEN 5

static gboolean rysuj(GtkWidget *widget, cairo_t *cr, gpointer user_data)
{
  GtkAllocation allocation;
  gint szer, wys, x, y;
  guint i;

  cr = gdk_cairo_create(gtk_widget_get_window(widget));

  gtk_widget_get_allocation (widget, &allocation); // Pobiera dane o kontrolce: X, Y, szerokosc, wysokosc
  szer = allocation.width;
  wys = allocation.height;
  x =  allocation.x;
  y = allocation.y;

  /* Rysowanie linii pionowych */
  cairo_set_source_rgb( cr, 0.8, 0.8, 0.8 ); // Ustawia kolor "szary"
  for ( i = x + MIN_X; i < szer; i += MIN_X )
  {

    cairo_move_to ( cr, i, y); // Ustawia pióro na wsp. x,y
    cairo_line_to ( cr, i, wys ); // Rysuje linie
  }
  cairo_stroke ( cr ); // Wyswietla na kontrolce

  /* Rysowanie linii poziomych */
  for ( i = y + MIN_Y; i < wys; i += MIN_Y )
  {
    cairo_move_to ( cr, x, i);
    cairo_line_to ( cr, szer, i );


  }
  cairo_stroke ( cr ); // Wyswietla na kontrolce

  /* Rysowanie "grafu" :) */
  cairo_set_source_rgb( cr, 1.0, 0.0, 0.0 ); // Ustawia kolor czerwony
  cairo_arc( cr, x + MIN_X, y + MIN_Y, PROMIEN, 0, 2 * G_PI ); // Rysuje okrag
  cairo_stroke ( cr ); // Wyswietla na kontrolce

  cairo_destroy(cr);

  return FALSE;
}


int main (int argc, char *argv[])
{
  GtkWidget *okno, *kontener_vbox, *obszar_rysunkowy;

  gtk_init (&argc, &argv);

  okno = g_object_new ( GTK_TYPE_WINDOW, "window-position", GTK_WIN_POS_CENTER, "title", "Graf", NULL );
  g_signal_connect ( okno, "destroy", G_CALLBACK (gtk_main_quit), NULL );

  kontener_vbox = g_object_new( GTK_TYPE_VBOX, "spacing", 5, NULL );
  gtk_container_add( GTK_CONTAINER( okno ), kontener_vbox );

  obszar_rysunkowy = gtk_drawing_area_new ();
  gtk_box_pack_start ( GTK_BOX(kontener_vbox), obszar_rysunkowy, TRUE, TRUE, 0 );
  g_signal_connect(obszar_rysunkowy, "expose-event", G_CALLBACK(rysuj), NULL);

  gtk_widget_show_all ( okno );
  gtk_main ();

  return 0;
}

Aktualnie to wynik jest taki:
user image

0
ujemny napisał(a):

Na forum jest wielu użytkowników którzy nie mieli by z tym problemu, ale na twoje nieszczęście nie ma tutaj takich którzy zrobią dla Ciebie gotowca.

Napisałem, że proszę o wskazówki, a nie gotowca ;). Jak ktoś mógłby mi napisać gotowca, skoro nie udostępniłem swojego kodu? Ma to wyglądać mniej więcej tak: http://www.cauchy.pl/gry/gry_na_kartce_papieru/pilkarzyki_na_kartce_papieru/pilkarzyki_fajne_gry_na_kartce_papieru_9.gif
Taką grę piszę, mam tylko problem z trybem graficznym.

Badmaneq,
Dzięki wielkie, o takie wskazówki mi chodziło. Poczytam sobie i spróbuje to ogarnąć ;).

0

Trza było mówić, że piszesz piłkarzyki a nie jakieś zagmatwania z grafami i innymi pierdołami. Mi się nawet nie chciało za bardzo czytać o co ci chodzi jak zobaczyłem twój opis problemu.

0

No w sumie tak byłoby prościej ;) Czyli to co podał mi Badmaneq wystarczy do zrobienia interfejsu? Resztę kodu mam prawie gotową.

Edit.
Mam problem z używaniem Cairo. GTK mam poprawnie wgrany, mimo to codeblocks mi marudzi, że nie mam tej biblioteki (błędy typu 'undefined reference').
Dodałem
-ID:\gtk\include\gdk-pixbuf-2.0
-ID:\gtk\include\cairo
a PATH mam do katalogu D:\gtk\bin

1

Nie podałeś 'undefined reference' do czego !
Ale zapewne musisz zrobić tak: Project -> build options, następnie zakładka Linker settings, a wniej Add i dodaj odpowiednio:
D:\gtk\lib\cairo.lib
D:\gtk\lib\gdk-win32-2.0.lib

Pomślałem trochę nad sposobem reprezantacji i doszedłem do wniosku, że i owszem może być struktura 8xbool, lecz uważam, że prościej użyć grafu, a do jego reprezentacji na początek tablicy nxn, później jak zatrybisz o co biega to listy.
Polecam książkę "Algorytmy struktury danych i techniki programowania" autor Piotr Wróblewski lub choćby tą strone http://www.algorytm.org/klasyczne/grafy-i-ich-reprezentacje.html

0

Błąd dotyczył każdej funkcji z Cairo, więc nie wypisywałem wszystkich nazw. Pomogło, dzięki wielkie Badmaneq. 8 booli to był mój pierwszy pomysł, myślałem potem o zrobieniu tego na listach sąsiedztwa, ale nie chciało mi się robić wszystkiego od nowa. O sposobach reprezentacji grafu trochę wiem, gorzej z rysowaniem ich :P.

1 użytkowników online, w tym zalogowanych: 0, gości: 1