Avatar billede jalle76 Nybegynder
28. januar 2006 - 10:55 Der er 4 kommentarer

Træ af forskellige objekter af forskellige klasser i C++

Jeg har brug for at lave et træ af forskellige objekter af forskellige klasser. Mere specifikt skal knuderne i træet repræsentere aabb'er (axis aligned bounding boxes) og bladene skal repræsentere trekanter eller pentaedere. Jeg skal kunne gennemløbe træet og lave intersection test på de forskellige objekter. Dvs. jeg skal kunne lave følgende intersection test:

aabb vs. aabb
aabb vs. trekant
aabb vs. pentagram
trekant vs. pentagram

Selve testen for intersection af de enkelte geometriske objekter har jeg styr på. Det er mere den strukturelle opbygning af klasserne i C++ der skal udgøre træet jeg er interesseret i. Det jeg har nu er noget i stil med

Class TNode {
  TNode *l, *r;
  Geometry &g;
}

Class Geometry {
  ...
}

Class GAABB : public Geometry {
  bool Intersects(GTriangle t) {...}
  bool Intersects(GPentahedron p) {...}
  ...
}

Class GTriangle : public Geometry {
  bool Intersects(GAABB) { ... }
  ...
}

Er jeg på rette spor?

Jeg stødte på "Composite pattern" ved en google-søgning. Vil det kunne bruges? Og i så fald, hvordan?

Mvh.
Jacob
Avatar billede bertelbrander Novice
28. januar 2006 - 14:12 #1
Man kunne lave noget i stil med følgende:

#include <map>
#include <iostream>

class D1;
class D2;

class Base
{
public:
  bool Intersects(D1* d1, D1* d11)
  {
      std::cout << "Intersects  D1 D1" << std::endl;
      return true;
  }
  bool Intersects(D1* d1, D2* d2)
  {
      std::cout << "Intersects  D1 D2" << std::endl;
      return true;
  }
  bool Intersects(D2* d2, D1* d1)
  {
      std::cout << "Intersects  D2 D1" << std::endl;
      return true;
  }
  bool Intersects(D2* d2, D2* d22)
  {
      std::cout << "Intersects  D2 D2" << std::endl;
      return true;
  }
  virtual bool Intersects(Base* b) = 0;
  virtual bool Intersects(D1* d1) = 0;
  virtual bool Intersects(D2* d2) = 0;
};


class D1 : public Base
{
public:
  virtual bool Intersects(Base *b)
  {
      return b->Intersects(this);
  }

  virtual bool Intersects(D1 *d1)
  {
      return Base::Intersects(this, d1);
  }
  virtual bool Intersects(D2 *d2)
  {
      return Base::Intersects(this, d2);
  }
};

class D2 : public Base
{
public:
  virtual bool Intersects(Base *b)
  {
      return b->Intersects(this);
  }
  virtual bool Intersects(D1 *d1)
  {
      return Base::Intersects(this, d1);
  }
  virtual bool Intersects(D2 *d2)
  {
      return Base::Intersects(this, d2);
  }
};

std::map<int, Base*>MyMap;

int main()
{
  D1 d11, d12;
  D2 d21, d22;
  MyMap[0] = &d11;
  MyMap[1] = &d12;
  MyMap[2] = &d21;
  MyMap[3] = &d22;

  MyMap[0]->Intersects(MyMap[1]);
  MyMap[0]->Intersects(MyMap[2]);
}
Avatar billede bertelbrander Novice
29. januar 2006 - 00:58 #2
Et noget mere komplet eksempel:

#include <iostream>
class D1;
class D2;
class TreeNodeClass;

class Base
{
public:
  bool Intersects(D1* d1, D1* d11)
  {
      std::cout << "Intersects D1 D1" << std::endl;
      return true;
  }
  bool Intersects(D1* d1, D2* d2)
  {
      std::cout << "Intersects D1 D2" << std::endl;
      return true;
  }
  bool Intersects(D2* d2, D1* d1)
  {
      std::cout << "Intersects D2 D1" << std::endl;
      return true;
  }
  bool Intersects(D2* d2, D2* d22)
  {
      std::cout << "Intersects D2 D2" << std::endl;
      return true;
  }
  bool Intersects(D1* d1, TreeNodeClass* Tree)
  {
      std::cout << "Intersects D1 Tree" << std::endl;
      return true;
  }
  bool Intersects(D2* d2, TreeNodeClass* Tree)
  {
      std::cout << "Intersects D1 Tree" << std::endl;
      return true;
  }

  virtual bool Intersects(Base* b) = 0;
  virtual bool Intersects(D1* d1) = 0;
  virtual bool Intersects(D2* d2) = 0;
  virtual bool Intersects(TreeNodeClass* Tree) = 0;
};

class TreeNodeClass
{
public:
  TreeNodeClass(TreeNodeClass* aLeftNode, TreeNodeClass* aRightNode, Base* aLeftLeaf, Base* aRightLeaf) :
      LeftNode(aLeftNode), RightNode(aRightNode), LeftLeaf(aLeftLeaf), RightLeaf(aRightLeaf)
  {
  }

  TreeNodeClass* LeftNode;
  TreeNodeClass* RightNode;
  Base* LeftLeaf;
  Base* RightLeaf;
};

class D1 : public Base
{
public:
  virtual bool Intersects(Base *b)
  {
      return b->Intersects(this);
  }
  virtual bool Intersects(D1 *d1)
  {
      return Base::Intersects(this, d1);
  }
  virtual bool Intersects(D2 *d2)
  {
      return Base::Intersects(this, d2);
  }
  virtual bool Intersects(TreeNodeClass* Tree)
  {
      return Base::Intersects(this, Tree);
  }
};

class D2 : public Base
{
public:
  virtual bool Intersects(Base *b)
  {
      return b->Intersects(this);
  }
  virtual bool Intersects(D1 *d1)
  {
      return Base::Intersects(this, d1);
  }
  virtual bool Intersects(D2 *d2)
  {
      return Base::Intersects(this, d2);
  }
  virtual bool Intersects(TreeNodeClass* Tree)
  {
      return Base::Intersects(this, Tree);
  }
};

void Walk(TreeNodeClass* Tree)
{
  if(Tree->RightLeaf && Tree->LeftLeaf)
  {
      Tree->RightLeaf->Intersects(Tree->LeftLeaf);
  }
  if(Tree->RightLeaf)
  {
      Tree->RightLeaf->Intersects(Tree);
  }
  if(Tree->LeftLeaf)
  {
      Tree->LeftLeaf->Intersects(Tree);
  }
  if(Tree->LeftNode)
  {
      Walk(Tree->LeftNode);
  }
  if(Tree->RightNode)
  {
      Walk(Tree->RightNode);
  }
}

int main()
{
  D1 d11, d12, d13, d14;
  D2 d21, d22, d23, d24;

  TreeNodeClass t4(0, 0, &d14, &d24);
  TreeNodeClass t3(&t4, 0, &d23, &d13);
  TreeNodeClass t2(0, 0, &d12, &d22);
  TreeNodeClass t1(&t2, &t3, &d11, &d12);

  Walk(&t1);
}
Avatar billede jalle76 Nybegynder
01. marts 2006 - 20:47 #3
Bertelbrander kan du ikke afgive et svar, så du kan få pointsene?
Avatar billede bertelbrander Novice
01. marts 2006 - 21:38 #4
Nej, jeg samler ikke på point.

Fandt du noget du kunne bruge?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester