summaryrefslogtreecommitdiff
path: root/src/graph.c
blob: 9dc778b26be65e07515ec8d5419a9ac66d222654 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdlib.h>

#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif

#include "graph.h"

/****************************
 * Graph memory
 ***************************/

// Free the memory for a graph and substructures
void grFree(grGraph *g)
{
  if (g)
  {
    if (g->nodes)
      free(g->nodes);
    if (g->edges)
      free(g->edges);
    free(g);
  }
}


// Allocate memory for a new graph, return NULL on any error
grGraph* grAlloc(int numnodes, int numedges)
{
  grGraph *g;

  g = malloc(sizeof(grGraph));
  if (!g)
    return NULL;

  g->nodes = malloc(sizeof(grNode[numnodes]));
  g->edges = malloc(sizeof(grEdge[numedges]));
  if (!g->nodes || !g->edges)
    goto ERR;

  g->numnodes = numnodes;
  g->numedges = numedges;

  return g;

  ERR:
  grFree(g);
  return NULL;
}



/****************************
 * Graph generation
 ***************************/

// Randomize a graph
void grGenRandom(grGraph *g)
{
  int i;
  int ns = g->numnodes;
  int es = g->numedges;

  for (i = 0; i < ns; i++)
  {
    grNode *n = &g->nodes[i];

    n->x = (float)rand() / (RAND_MAX/4);
    n->y = (float)rand() / (RAND_MAX/4);
    n->z = (float)rand() / (RAND_MAX/4);
    n->colour = 0.0;
  }

  for (i = 0; i < es; i++)
  {
    grEdge *e = &g->edges[i];

    e->n1 = rand() / (RAND_MAX/ns);
    e->n2 = rand() / (RAND_MAX/ns);
  }
}



/****************************
 * Graph drawing functions
 ***************************/

// Draw the graph on the current OpenGL context
void graphDrawGL(grGraph *g)
{
  int i;
  int ns = g->numnodes;
  int es = g->numedges;

  // Draw edges
  glColor4f(0.0, 0.0, 1.0, 0.5);
  for (i = 0; i < es; i++)
  {
    grNode *n1 = &g->nodes[g->edges[i].n1];
    grNode *n2 = &g->nodes[g->edges[i].n2];

    glBegin(GL_LINE_STRIP);
      glVertex3f(n1->x, n1->y, n1->z);
      glVertex3f(n2->x, n2->y, n2->z);
    glEnd();
  }

  // Draw nodes
  glPointSize(5.0);
  glBegin(GL_POINTS);
    for (i = 0; i < ns; i++)
    {
      grNode *n = &g->nodes[i];
      //glLoadName(i);    // Load point number into depth buffer for selection
      glColor4f(n->colour, 1.0, 0.3, 0.7);
      glVertex3f(n->x, n->y, n->z);
    }
  glEnd();
}