visualizations

Programmatic visualizations
git clone git://git.laack.co/visualizations.git
Log | Files | Refs | README

graph.cpp (2970B)


      1 #include "graph.hpp"
      2 #include "vertex.hpp"
      3 #include "utils.hpp"
      4 #include <cstddef>
      5 #include <raylib.h>
      6 #include <iostream>
      7 
      8 Graph::Graph(std::size_t edgeCount, std::size_t vertCount, float xMax, float yMax) {
      9     for(std::size_t i = 0; i < vertCount; ++i) {
     10         Vector2 rnd = randomPosition(xMax, yMax);
     11         Vertex v {rnd,5};
     12         this->vertices.push_back(v);
     13     }
     14     for(std::size_t i = 0; i < edgeCount; ++i) {
     15         std::size_t idx1 = 0;
     16         std::size_t idx2 = 0;
     17         // no self-edges
     18         while (idx1 == idx2) {
     19             idx1 = std::rand() % vertCount;
     20             idx2 = std::rand() % vertCount;
     21         }
     22         
     23         Edge e {idx1, idx2, distanceSquared(vertices[idx1].position, vertices[idx2].position)};
     24         this->edges[idx1].push_back(e);
     25         this->edges[idx2].push_back(e);
     26     }
     27 }
     28 
     29 std::string Graph::toString() {
     30 
     31     std::string result = "edges: {";
     32 
     33     for(auto pair: this->edges) {
     34         auto key = pair.first;
     35         for(auto edge: edges[key]) {
     36             result += edge.toString();
     37         }
     38     }
     39     
     40     result += "}";
     41 
     42     result += "\nvertices: {";
     43 
     44     for(auto vertex: this->vertices) {
     45         result += vertex.toString();
     46     }
     47 
     48     result += "}";
     49     return result;
     50 }
     51 
     52 
     53 void Graph::render() {
     54     // yes, this will double draw because we track 0 -> 1 and 1 -> 0
     55     
     56     std::vector<Edge> visited {};
     57     for(auto pair: this->edges) {
     58         auto edges = this->edges[pair.first];
     59         for(auto edge: edges) {
     60             std::size_t idx1 = edge.v1Index;
     61             std::size_t idx2 = edge.v2Index;
     62             auto v1 = vertices[idx1].position;
     63             auto v2 = vertices[idx2].position;
     64             if(edge.traversed) {
     65                 visited.push_back(edge);
     66             } else {
     67                 DrawLineEx(v1, v2, 1,DARKERGRAY);
     68             }
     69         }
     70     }
     71     
     72     for(auto vertex: this->vertices) {
     73         vertex.render();
     74     }
     75 
     76     // ensure we draw visited over unvisited for better looks
     77     for(auto edge: visited) {
     78         std::size_t idx1 = edge.v1Index;
     79         std::size_t idx2 = edge.v2Index;
     80         auto v1 = vertices[idx1].position;
     81         auto v2 = vertices[idx2].position;
     82         DrawLineEx(v1, v2, 1, WHITE);
     83     }
     84 }
     85 
     86 void Graph::traverseVertexIdx(std::size_t idx) {
     87     this->vertices[idx].visited = true;
     88 }
     89 
     90 std::vector<Edge> Graph::getEdgesOfVertexIdx(std::size_t idx) {
     91     return this->edges[idx];
     92 }
     93 
     94 void Graph::setEdgeTraversed(Edge e) {
     95 
     96     std::size_t source = e.v1Index;
     97     std::size_t destination = e.v2Index;
     98 
     99     if(source == destination) { 
    100         return;
    101     }
    102 
    103     auto& cEdges = edges[source];
    104 
    105     for(auto& edge : cEdges) {
    106         if(edge.v2Index == destination || edge.v1Index == destination) {
    107             edge.traversed = true;
    108         }
    109     }
    110 
    111     auto& oEdges = edges[destination];
    112 
    113     for(auto& edge : oEdges) {
    114         if(edge.v2Index == source || edge.v1Index == source) {
    115             edge.traversed = true;
    116         }
    117     }
    118 
    119 }