Retrait des doublons et appariement des squelettes

This commit is contained in:
terry-dango 2015-02-06 14:32:24 +01:00
parent cef4a611d9
commit b862eaf766
10 changed files with 1485 additions and 20 deletions

View File

@ -5,7 +5,7 @@
#include "VectorFunctions.hpp"
#include "FreeFlyCamera.hpp"
FreeFlyCamera::FreeFlyCamera() : speed(0.1), sensitivity(0.001), theta(0), phi(0)
FreeFlyCamera::FreeFlyCamera() : speed(10), sensitivity(0.001), theta(0), phi(0)
{
vectorsFromAngles();
}

View File

@ -2,11 +2,11 @@ SOURCES = Box.cpp Skeleton.cpp FreeFlyCamera.cpp main.cpp
OBJECTS = $(SOURCES:.cpp=.o)
TARGET = main
LIBS = -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio -lGL -lGLU -lglut
LIBS = -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio -lGL -lGLU
CXX = g++
%.o: %.cpp
$(CXX) -std=c++14 -o $@ -c $< -Wall
$(CXX) -std=c++14 -o $@ -c $< -Wall
all: $(OBJECTS)
$(CXX) -std=c++14 -o $(TARGET) $(OBJECTS) $(LIBS) -Wall

View File

@ -2,6 +2,7 @@
#include <fstream>
#include <algorithm>
#include <GL/gl.h>
#include "opencv2/features2d/features2d.hpp"
#include "Skeleton.hpp"
#include "Box.hpp"
@ -12,6 +13,11 @@ Skeleton::Skeleton() : m_vertices{}, m_edges{}, m_neighbourgs_counters{}, m_junc
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief loadFromFile : read a file at format skl and extract vertices and edges
///
/// \param path String containing the path to the file at format skl
////////////////////////////////////////////////////////////////////////////////////////////////////
void Skeleton::loadFromFile(std::string const& path)
{
std::ifstream file{path};
@ -33,9 +39,9 @@ void Skeleton::loadFromFile(std::string const& path)
case 'v':
float x;
float y;
float r;
stream >> x >> y >> r;
m_vertices.push_back(Vertex{x,y,r});
float z;
stream >> x >> y >> z;
m_vertices.push_back(Vertex{x,y,z});
break;
case 'e':
@ -51,6 +57,15 @@ void Skeleton::loadFromFile(std::string const& path)
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief loadFromVectors : create edges from a vector of vertices index
///
/// For example, with the vector path = [1, 5, 8, 9, 12], the created edges are (1,5), (5,8), (8,9)
/// and (9,12)
///
/// \param vertices Vector of vertices
/// \param path Vector of vertices index
////////////////////////////////////////////////////////////////////////////////////////////////////
void Skeleton::loadFromVectors(std::vector<Vertex> const& vertices, std::vector<unsigned int> const& path)
{
m_vertices = vertices;
@ -60,6 +75,23 @@ void Skeleton::loadFromVectors(std::vector<Vertex> const& vertices, std::vector<
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief countNeighbourgs : count the number of neighbors of each vertex
///
/// Compute a vector of counters which has the same size as the number of vertices.
/// The k-th element of the vector is the number of neighbors of the k-th vertex.
///
/// For example, with the following skeleton :
///
///
/// 3 6
/// | |
/// 1-2-4-5-8-9
/// |
/// 7
///
/// It would compute : m_neighbors_counters = [1,3,1,2,4,1,1,2,1]
////////////////////////////////////////////////////////////////////////////////////////////////////
void Skeleton::countNeighbourgs()
{
m_neighbourgs_counters.reserve(m_vertices.size());
@ -75,6 +107,10 @@ void Skeleton::countNeighbourgs()
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief draw : draw the skeleton with OpenGL
////////////////////////////////////////////////////////////////////////////////////////////////////
void Skeleton::draw() const
{
@ -84,6 +120,9 @@ void Skeleton::draw() const
glDisableClientState(GL_VERTEX_ARRAY);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief computeJunctions : compute the junctions
////////////////////////////////////////////////////////////////////////////////////////////////////
void Skeleton::computeJunctions()
{
countNeighbourgs();
@ -112,10 +151,14 @@ void Skeleton::computeJunctions()
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief split : split the whole skeletons into branches of skeletons
////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<Skeleton> Skeleton::split()
{
std::vector<Skeleton> branches;
std::vector<std::vector<bool>> connections;
std::vector<std::vector<unsigned int>> paths;
if (m_junctions.size() == 0)
computeJunctions();
@ -152,7 +195,6 @@ std::vector<Skeleton> Skeleton::split()
path.push_back(pathNumber);
auto j = 0u;
unsigned int k;
// auto counter = 0u;
do
{
@ -161,18 +203,44 @@ std::vector<Skeleton> Skeleton::split()
k = path[path.size()-1];
} while (m_neighbourgs_counters[k] == 2);
branches.push_back(Skeleton{});
branches[branches.size()-1].loadFromVectors(m_vertices, path);
branches[branches.size()-1].m_bounding_box = m_bounding_box;
numberOfBranchesFound++;
bool toBeAdded = true;
for (unsigned int j = 0; j < paths.size(); j++)
{
auto const& branche_path = paths[j];
auto const& sizeBranche = branche_path.size();
bool samePathOfSize2 = (path.size() == 2 && path.size() == sizeBranche && (path[0] == branche_path[1] && path[1] == branche_path[0]));
bool samePath = (path.size() > 2 && path.size() == sizeBranche && (path[0] == branche_path[sizeBranche-1] && path[path.size()-1] == branche_path[0] && path[1] == branche_path[sizeBranche-2]));
if (samePathOfSize2||samePath)
{
toBeAdded = false;
}
}
if (toBeAdded)
{
paths.push_back(path);
branches.push_back(Skeleton{});
branches[branches.size()-1].loadFromVectors(m_vertices, path);
branches[branches.size()-1].m_bounding_box = m_bounding_box;
numberOfBranchesFound++;
}
}
}
}
std::cout << std::endl;
std::cout << "Nombre de branches de squelettes trouvées : " << branches.size() << std::endl;
return branches;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief addNextPoint : add a point to a branche
///
/// \param connections Inferior triangular matrix (j<i) wit 0 in (i,j) if the i-th vertex is
/// connected to the j-th vertex
/// \param path Branche of skeleton to be added a point
////////////////////////////////////////////////////////////////////////////////////////////////////
void Skeleton::addNextPoint(std::vector<std::vector<bool>> const& connections, std::vector<unsigned int>& path) const
{
auto lastPoint = path[path.size()-1];
@ -194,6 +262,14 @@ void Skeleton::addNextPoint(std::vector<std::vector<bool>> const& connections, s
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief findOnes : return a vector containing the column containing a 1 in a triangular matrix
/// given a certain line
///
/// \param connections Inferior triangular matrix containing 1 in (i,j) if the vertex i is connected
/// to the vertex j
/// \param lineNumber Index i of the line of connections where the algorithm looks for 1
////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<unsigned int> Skeleton::findOnes(std::vector<std::vector<bool>> const& connections, unsigned int lineNumber) const
{
std::vector<unsigned int> onesPosition;
@ -214,6 +290,9 @@ std::vector<unsigned int> Skeleton::findOnes(std::vector<std::vector<bool>> cons
return onesPosition;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief computeBoundingBox : computes the bounding box of the skeleton
////////////////////////////////////////////////////////////////////////////////////////////////////
void Skeleton::computeBoundingBox()
{
m_bounding_box.m_x_min = m_vertices[0].x;
@ -229,17 +308,195 @@ void Skeleton::computeBoundingBox()
m_bounding_box.m_y_max = std::max(m_bounding_box.m_y_max,vertex.y);
}
std::cout << "Affichage de la bounding box : " << std::endl;
std::cout << "[" << m_bounding_box.m_x_min << "," << m_bounding_box.m_x_max << "] "
<< "[" << m_bounding_box.m_y_min << "," << m_bounding_box.m_y_max << "]"
<< std::endl;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief branchesMatching : match branches of two skeletons together
///
/// On considère que les deux squelettes que l'on cherche à apparier ont le même nombre de points
/// We use the copy parameters to avoid side effects
///
/// \param keypoints
/// \param branches1
/// \param branches2
////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<std::pair<unsigned int,unsigned int>> branchesMatching(std::vector<std::pair<cv::KeyPoint,cv::KeyPoint>> keypoints, std::vector<Skeleton> branches1, std::vector<Skeleton> branches2)
{
std::vector<std::pair<unsigned int,unsigned int>> matchingBranches;
// We verify that skeletons both have as many branches
if (branches1.size() != branches2.size())
{
std::cout << "Le premier squelette dispose de " << branches1.size() << " branches, tandis que le second en dispose de " << branches2.size() << "." << std::endl;
}
// We divide the x and y coordinates of each vertex by the z-coordinate for both skeletons
for (unsigned int i = 0; i < branches1.size() ; i++)
{
for (unsigned int j = 0; j < branches1[i].m_vertices.size(); j++)
{
branches1[i].m_vertices[j].x /= branches1[i].m_vertices[j].z;
branches1[i].m_vertices[j].y /= branches1[i].m_vertices[j].z;
}
}
for (unsigned int i = 0; i < branches2.size() ; i++)
{
for (unsigned int j = 0; j < branches2[i].m_vertices.size(); j++)
{
branches2[i].m_vertices[j].x /= branches2[i].m_vertices[j].z;
branches2[i].m_vertices[j].y /= branches2[i].m_vertices[j].z;
}
}
std::vector<unsigned int> correspondingBranches1;
std::vector<unsigned int> correspondingBranches2;
// Matching between key points of the first image and branches of the first skeleton
for (unsigned int i = 0; i < keypoints.size(); i++)
{
auto const& keypoint = keypoints[i].first;
unsigned int nearest_branche_index;
nearest_branche_index = searchNearestBrancheIndex(keypoint, branches1);
correspondingBranches1.push_back(nearest_branche_index);
}
// Matching between key points of the second image and branches of the second skeleton
for (unsigned int i = 0; i < keypoints.size(); i++)
{
auto const& keypoint = keypoints[i].second;
unsigned int nearest_branche_index;
nearest_branche_index = searchNearestBrancheIndex(keypoint, branches2);
correspondingBranches2.push_back(nearest_branche_index);
}
// Initialisation of a 2D matching matrix couting the number of times that each branche of the first skeleton is associated to another branche of the second skeleton as their respective associated keypoints are paired
unsigned int matchingMatrix[branches1.size()][branches2.size()];
for (auto i = 0u; i < 6; i++)
{
for (auto j = 0u; j < 6; j++)
matchingMatrix[i][j] = 0;
}
for (unsigned int i = 0; i < correspondingBranches1.size() ; i++)
{
std::cout << "Le morceau du premier squelette d'indice " << correspondingBranches1[i] << " semble correspondre au morceau du second squelette d'indice " << correspondingBranches2[i] << "." << std::endl;
matchingMatrix[correspondingBranches1[i]][correspondingBranches2[i]]++;
}
std::cout << "--------Matrix is--------------" << std::endl;
for (auto i = 0u; i < 6; i++)
{
for (auto j = 0u; j < 6; j++)
std::cout << matchingMatrix[i][j] << " ";
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << "----------------------------------" << std::endl;
for (unsigned int i = 0; i < branches1.size(); i++)
{
unsigned int maximumMatchingScore = 0;
unsigned int maximumMatchingScoreIndex = 0;
for (unsigned int j = 0; j < branches1.size(); j++)
{
if (matchingMatrix[i][j] > maximumMatchingScore)
{
maximumMatchingScore = matchingMatrix[i][j];
maximumMatchingScoreIndex = j;
}
}
std::pair<unsigned int, unsigned int> pairOfBranches(i,maximumMatchingScoreIndex);
matchingBranches.push_back(pairOfBranches);
}
return matchingBranches;
}
unsigned int searchNearestBrancheIndex(cv::KeyPoint const& keypoint, std::vector<Skeleton> branches)
{
unsigned int nearest_branche_index = 0;
float shortest_distance;
for (unsigned int j = 0 ; j < branches.size() ; j++)
{
auto const& branche = branches[j];
for (unsigned int k = 0 ; k < branche.m_edges.size() ; k++)
{
auto const& edge = branche.m_edges[k];
// We compute the coordinates of the projection of the keypoint on each edge
float d_keypoint_edge;
float xK = keypoint.pt.x;
float yK = keypoint.pt.y;
float xv1 = branche.m_vertices[edge.v1].x;
float yv1 = branche.m_vertices[edge.v1].y;
float xv2 = branche.m_vertices[edge.v2].x;
float yv2 = branche.m_vertices[edge.v2].y;
float xv1v2 = xv2 - xv1;
float yv1v2 = yv2 - yv1;
float a = yv1v2;
float b = -xv1v2;
float c = -a*xv1 - b*yv1;
float na1 = xv1v2;
float nb1 = yv1v2;
float nc1 = -na1*xv1 - nb1*yv1;
float nc2 = -na1*xv2 - nb1*yv2;
float yH1 = (na1/(na1*na1+nb1*nb1))*(na1*yK-nb1*nc1/na1-nb1*xK);
float xH1 = -(nb1*yH1+nc1)/na1;
float yH2 = (na1/(na1*na1+nb1*nb1))*(na1*yK-nb1*nc2/na1-nb1*xK);
float xH2 = -(nb1*yH2+nc2)/na1;
float d_v1_v2 = std::sqrt((xv1-xv2)*(xv1-xv2)+(yv1-yv2)*(yv1-yv2));
float d_K_H1 = std::sqrt((xK-xH1)*(xK-xH1)+(yK-yH1)*(yK-yH1));
float d_K_H2 = std::sqrt((xK-xH2)*(xK-xH2)+(yK-yH2)*(yK-yH2));
if (d_K_H1 + d_K_H2 <= d_v1_v2)
{
float yH = (a/(a*a+b*b))*(a*yK-b*c/a-b*xK);
float xH = -(b*yH+c)/a;
float d_K_H = std::sqrt((xK-xH)*(xK-xH)+(yK-yH)*(yK-yH));
d_keypoint_edge = d_K_H;
}
else
{
float d_K_v1 = std::sqrt((xK-xv1)*(xK-xv1)+(yK-yv1)*(yK-yv1));
float d_K_v2 = std::sqrt((xK-xv2)*(xK-xv2)+(yK-yv2)*(yK-yv2));
d_keypoint_edge = std::min(d_K_v1,d_K_v2);
}
if (j+k == 0)
{
shortest_distance = d_keypoint_edge;
}
if (d_keypoint_edge < shortest_distance)
{
shortest_distance = d_keypoint_edge;
nearest_branche_index = j;
}
}
}
return nearest_branche_index;
}
std::ostream& operator<<(std::ostream& out, Skeleton const& s)
{
for (auto const& vertex : s.m_vertices)
{
out << "v " << vertex.x << " " << vertex.y << " " << vertex.r << "\n";
out << "v " << vertex.x << " " << vertex.y << " " << vertex.z << "\n";
}
out << "\n";

View File

@ -4,6 +4,7 @@
#include <string>
#include <vector>
#include <sstream>
#include "opencv2/features2d/features2d.hpp"
#include "Box.hpp"
class Vertex
@ -11,7 +12,7 @@ class Vertex
public:
float x;
float y;
float r;
float z;
};
class Edge
@ -41,11 +42,12 @@ class Skeleton
std::vector<Skeleton> split();
friend std::ostream& operator<<(std::ostream& out, Skeleton const& s);
void computeBoundingBox();
friend std::vector<std::pair<unsigned int,unsigned int>> branchesMatching(std::vector<std::pair<cv::KeyPoint,cv::KeyPoint>> keypoints, std::vector<Skeleton> branches1, std::vector<Skeleton> branches2);
private:
void addNextPoint(std::vector<std::vector<bool>> const& connections, std::vector<unsigned int>& path) const;
std::vector<unsigned int> findOnes(std::vector<std::vector<bool>> const& connections, unsigned int lineNumber) const;
friend unsigned int searchNearestBrancheIndex(cv::KeyPoint const& keypoint, std::vector<Skeleton> branches);
std::vector<Vertex> m_vertices;
std::vector<Edge> m_edges;
std::vector<unsigned int> m_neighbourgs_counters;

View File

@ -0,0 +1,52 @@
v 30 2 10
v 25 0 9
v 20 2 8
v 17 5 9
v 16 9 7
v 16 13 8
v 17 16 7
v 21 15 6
v 25 14 6
v 29 13 6
v 33 12 5
v 13 7 6
v 10 5 6
v 7 8 5
v 4 11 4
v 2 15 3
v 17 20 8
v 17 24 9
v 18 28 8
v 21 30 7
v 25 32 6
v 29 33 5
v 33 34 4
v 14 30 7
v 10 33 6
v 6 35 5
e 1 2
e 2 3
e 3 4
e 4 5
e 5 6
e 6 7
e 7 8
e 8 9
e 9 10
e 10 11
e 7 12
e 12 13
e 13 14
e 14 15
e 15 16
e 7 17
e 17 18
e 18 19
e 19 20
e 20 21
e 21 22
e 22 23
e 19 24
e 24 25
e 25 26

View File

@ -0,0 +1,33 @@
std::vector<std::pair<cv::KeyPoint,cv::KeyPoint>> keypoints1 = {
// Pairs of keypoints supposed to be matched with branche[0]
{cv::KeyPoint{cv::Point{100,400},0}, cv::KeyPoint{cv::Point{400,400},0}},
{cv::KeyPoint{cv::Point{200,200},0}, cv::KeyPoint{cv::Point{400,300},0}},
{cv::KeyPoint{cv::Point{400,400},0}, cv::KeyPoint{cv::Point{500,300},0}},
{cv::KeyPoint{cv::Point{300,600},0}, cv::KeyPoint{cv::Point{500,600},0}},
{cv::KeyPoint{cv::Point{100,400},0}, cv::KeyPoint{cv::Point{500,300},0}},
// Pairs of keypoints supposed to be matched with branches[1]
{cv::KeyPoint{cv::Point{700,300},0}, cv::KeyPoint{cv::Point{650,400},0}},
{cv::KeyPoint{cv::Point{900,200},0}, cv::KeyPoint{cv::Point{700,200},0}},
{cv::KeyPoint{cv::Point{1100,400},0}, cv::KeyPoint{cv::Point{900,300},0}},
{cv::KeyPoint{cv::Point{1000,600},0}, cv::KeyPoint{cv::Point{800,500},0}},
{cv::KeyPoint{cv::Point{800,600},0}, cv::KeyPoint{cv::Point{700,600},0}},
// Pairs of keypoints supposed to be matched with branches[2]
{cv::KeyPoint{cv::Point{400,800},0}, cv::KeyPoint{cv::Point{500,800},0}},
{cv::KeyPoint{cv::Point{600,700},0}, cv::KeyPoint{cv::Point{700,700},0}},
{cv::KeyPoint{cv::Point{700,900},0}, cv::KeyPoint{cv::Point{750,900},0}},
// Pairs of keypoints supposed to be matched with branches[3]
{cv::KeyPoint{cv::Point{300,1000},0}, cv::KeyPoint{cv::Point{400,1000},0}},
{cv::KeyPoint{cv::Point{100,1100},0}, cv::KeyPoint{cv::Point{300,1100},0}},
{cv::KeyPoint{cv::Point{300,1200},0}, cv::KeyPoint{cv::Point{500,1100},0}},
// Pairs of keypoints supposed to be matched with branches[4]
{cv::KeyPoint{cv::Point{1000,1100},0}, cv::KeyPoint{cv::Point{900,1100},0}},
{cv::KeyPoint{cv::Point{1100,1300},0}, cv::KeyPoint{cv::Point{1000,1300},0}},
{cv::KeyPoint{cv::Point{900,1400},0}, cv::KeyPoint{cv::Point{900,1400},0}},
// {cv::KeyPoint{cv::Point{800,1200},0}, cv::KeyPoint{cv::Point{800,1200},0}},
{cv::KeyPoint{cv::Point{800,1200},0}, cv::KeyPoint{cv::Point{670,1200},0}},
// Pairs of keypoints supposed to be matched with branches[5]
{cv::KeyPoint{cv::Point{500,1100},0}, cv::KeyPoint{cv::Point{600,1100},0}},
{cv::KeyPoint{cv::Point{400,1300},0}, cv::KeyPoint{cv::Point{500,1300},0}},
{cv::KeyPoint{cv::Point{600,1400},0}, cv::KeyPoint{cv::Point{700,1400},0}},
{cv::KeyPoint{cv::Point{400,1500},0}, cv::KeyPoint{cv::Point{500,1500},0}}
};

View File

@ -15,7 +15,7 @@
constexpr auto WIDTH = 1920;
constexpr auto HEIGHT = 1080;
void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& s, std::vector<std::array<float,3>> const& colors);
void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& s, std::vector<Skeleton> const& s2, std::vector<std::pair<unsigned int, unsigned int>> const& matching, std::vector<std::array<float,3>> const& colors);
int main(int argc, char *argv[])
{
@ -40,7 +40,7 @@ int main(int argc, char *argv[])
//Initialisation du mode 3D
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70,(double)WIDTH/HEIGHT,0.2,1000);
gluPerspective(70,(double)WIDTH/HEIGHT,0.2,10000);
// Initialisation de Z-Buffer
glEnable(GL_DEPTH_TEST);
@ -61,10 +61,28 @@ int main(int argc, char *argv[])
glFlush();
// Init mesh
Skeleton s;
Skeleton s, s2;
s.loadFromFile(std::string{argv[1]});
s.computeJunctions();
std::vector<std::pair<unsigned int, unsigned int>> matching;
std::vector<Skeleton> split = s.split();
std::vector<Skeleton> split2;
#include "init.cxx"
if (argc > 2)
{
s2.loadFromFile(std::string{argv[2]});
s2.computeJunctions();
split2 = s2.split();
std::swap(split2[1], split2[2]);
matching = branchesMatching(keypoints1, split, split2);
std::cout << "-------------------------------------------" << std::endl;
for (auto const& pair : matching)
std::cout << pair.first << " -> " << pair.second << std::endl;
}
std::vector<std::array<float,3>> colors;
@ -121,7 +139,7 @@ int main(int argc, char *argv[])
sf::Mouse::setPosition(sf::Vector2i{WIDTH/2, HEIGHT/2});
// Dessin de la scene
drawScene(camera, split, colors);
drawScene(camera, split, split2, matching, colors);
glScalef(0.01, 0.01, 1);
if (captureRequired)
@ -139,7 +157,7 @@ int main(int argc, char *argv[])
return 0;
}
void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& split, std::vector<std::array<float,3>> const& colors)
void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& split, std::vector<Skeleton> const& split2, std::vector<std::pair<unsigned int, unsigned int>> const& matching, std::vector<std::array<float,3>> const& colors)
{
// Initialisation
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -149,11 +167,23 @@ void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& split,
// Position Camera gluLookAt(positionCamera, positionCible, vecteurVertical)
camera.look();
for (auto i = 0u; i < split.size(); i++)
for (auto i = 0u; i < matching.size(); i++)
{
// Find random color
glColor3f(colors[i][0], colors[i][1], colors[i][2]);
split[i].draw();
glPushMatrix();
glTranslatef(1000,0,0);
split2[i].draw();
glPopMatrix();
glPushMatrix();
glTranslatef(0,-1500,0);
split[matching[i].first].draw();
glPushMatrix();
glTranslatef(1000,0,0);
split2[matching[i].second].draw();
glPopMatrix();
glPopMatrix();
}
// MAJ de l'écran

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
v 200 300 1
v 300 400 1
v 300 500 1
v 500 600 1
v 600 500 1
v 800 400 1
v 900 300 1
v 500 800 1
v 600 900 1
v 600 1000 1
v 400 1000 1
v 200 1100 1
v 800 1100 1
v 900 1300 1
v 500 1200 1
v 500 1300 1
v 400 1400 1
e 1 2
e 2 3
e 3 4
e 4 5
e 5 6
e 6 7
e 4 8
e 8 9
e 9 10
e 10 11
e 11 12
e 10 13
e 13 14
e 10 15
e 15 16
e 16 17

View File

@ -0,0 +1,36 @@
v 450 325 1
v 500 400 1
v 500 500 1
v 600 600 1
v 650 500 1
v 750 400 1
v 800 275 1
v 600 800 1
v 675 900 1
v 675 1000 1
v 500 1000 1
v 400 1100 1
v 800 1100 1
v 875 1250 1
v 625 1200 1
v 625 1300 1
v 550 1450 1
v 540 1470 1
e 4 5
e 5 6
e 6 7
e 8 4
e 8 9
e 9 10
e 1 2
e 2 3
e 3 4
e 10 11
e 11 12
e 10 13
e 13 14
e 15 10
e 15 16
e 17 16
e 17 18