Hejsan! Kollisionshantering i 3D är en av de mest tidskrävande delarna av fysikmotorer, så det är inget lätt problem du har get dig i kast med... =) Tack för ditt svar! Innan jag kommer för långt. Är jag på rätt väg: Nu har jag förbättrat klassen och lagt till några kommentarer :) Spontant känns det som att du har för mycket kod (vilket i sin tur gör att man inte riktigt orkar läsa igenom hela i detalj...) Jag ska tänka på det nästa gång jag lägger upp någon kodbit :) Jag är inte alls med på "antagligen att klassen inte klarade av om det var vilt spridda punkter, dvs punkterna behövde ligga på samma y axel." Jag tror att jag förstår dig Niklas och ska när jag har tid ändra det du har påpekat, men då undrar jag bara en liten sak till. Jag kommer ganska säkert använda denna klassen väldigt mycket i framtiden så hur kan jag göra den mer framtidssäker? Göra klassen Surface abstrakt och sedan ärva till en ny klass RectangleSurface och lägga in kollision funktioner för just rectanglar? När jag sedan har lärt mig lite bättre matematik så kan jag ju bara skapa en ny klass som ärver från Surface som kan hantera kollisions detekterings grejor bra. Låter det bra? Men i så fall. Hur ska min AddPoint funktion se ut för att vara så framtidsäker som möjligt? prototypsmässigt då, om den ska ta emot en Point eller en std::vector<Point> med mera? Njae, det du bör göra är att inte låta Surface ha en AddPoint öht.Kollision hantering, hur lösar man detta på effektivast?
Hur löser man enklast kollisions problem i vanlig 2D?. Just nu har jag skapat en klass som ser ut ungefär såhär:
<code>#ifndef H_SURFACE_H
#define H_SURFACE_H
class Object;
class Surface
{
private:
std::vector<Point> points;
public:
Surface() { }
bool Collision(const Point &);
bool Collision(const Surface &);
bool PointExist(const Point &);
bool Add(const Point &);
bool Add(const Point &, const Point &);
void Clear()
{
points.clear();
}
void Rotate(const float &);
float GetLowestXPoint() const;
float GetLowestYPoint() const;
float GetLargestXPoint() const;
float GetLargestYPoint() const;
};
bool Surface::Collision(const Point & a)
{
int size = points.size();
for(int i=0;i<size;i++)
{
if(points[i].GetY() == a.GetY())
{
for(int d = 0;d<size;d++)
{
if(points[i] != points[d] && points[i].GetY() == points[d].GetY())
{
int max = std::max(points[i].GetX(), points[d].GetX());
int min = std::min(points[i].GetX(), points[d].GetX());
if(min <= a.GetX() && a.GetX() <= max)
{
return true;
}
}
}
}
};
return false;
}
bool Surface::Collision(const Surface & a)
{
int size = a.points.size();
for(int i=0;i<size;i++)
{
if(Collision(a.points[i]))
{
return true;
}
}
return false;
}
bool Surface::PointExist(const Point & a)
{
int size = points.size();
for(int i=0;i<size;i++)
{
if(points[i] == a)
{
return true;
}
}
return false;
}
bool Surface::Add(const Point & a)
{
if(PointExist(a))
{
return false;
}
points.push_back(a);
return true;
}
bool Surface::Add(const Point & a, const Point & b)
{
if(a.GetY() != b.GetY())
{
return false;
}
return Add(a) && Add(b);
}
float Surface::GetLowestXPoint() const
{
float min = points[0].GetX();
int size = points.size();
for(int i = 0; i< size; i++)
{
if(points[i].GetX() < min)
{
min = points[i].GetX();
}
}
return min;
}
float Surface::GetLargestXPoint() const
{
float max = points[0].GetX();
int size = points.size();
for(int i = 0; i< size; i++)
{
if(points[i].GetX() > max)
{
max = points[i].GetX();
}
}
return max;
}
float Surface::GetLargestYPoint() const
{
float max = points[0].GetY();
int size = points.size();
for(int i = 0; i< size; i++)
{
if(points[i].GetY() > max)
{
max = points[i].GetY();
}
}
return max;
}
float Surface::GetLowestYPoint() const
{
float min = points[0].GetY();
int size = points.size();
for(int i = 0; i< size; i++)
{
if(points[i].GetY() < min)
{
min = points[i].GetY();
}
}
return min;
}
void Surface::Rotate(const float & a) /* denna funktionen fungerar inte, skulle gärna vilja veta varför */
{
int size = points.size();
Point min(GetLowestXPoint(),GetLowestYPoint());
for(int i=0;i<size;i++)
{
float hypo = sqrt(pow(points[i].GetX()-min.GetX(),2) + pow(points[i].GetY() - min.GetY(),2));
float x = points[i].GetX()-min.GetX() + std::cos(a) * hypo;
float y = points[i].GetY()-min.GetY() + std::sin(a) * hypo;
points[i].Set(x,y);
}
}
#endif
</code>
Sedan gör man bara såhär t.ex för att skapa en fyrkant:
<code>
Surface surface;
surface.Add(Point(0,0), Point(100,0));
surface.Add(Point(0,1), Point(100,1));
surface.Add(Point(0,2), Point(100,2));
surface.Add(Point(0,3), Point(100,3));
...
</code>
Jag tror att ni förstår. Problemet med denna lösningen är ju att jag kan t.ex inte ange formar som har fler än 2 st x-värden på samma y axel. Så hur löser man detta effektivast?
Fråga 2
Vad gör jag för fel på Rotate funktionen ovan?
Om det är något som någon inte förstod så är det bara att fråga så förklarar jag mer :)
Tack på förhand!Sv: Kollision hantering, hur lösar man detta på effektivast?
Vad gäller 2D är det lite lättare. Du vill ha polygoner?
Det finns lite olika varianter; först de enkla:
1. "Axis aligned Bounding Box" - kolla på max och min för x och y, jämför det. Det är i princip det du gör. Jag är inte säker på vad du menar med "inte ange formar som har fler än 2 st x-värden på samma y axel".
Jag skulle implementera det som (halv-pseudo):
pair<double, double> MaxMinX()
{
double min, max;
for each point
min = min(point.x, min);
max = max(point.x, min);
return make_pair(min, max);
}
Och motsvarande för y. Det känns som att du har väldigt många funktioner?
Hur som helst gör du ju flera tester på t.ex. points[i].GetY() == points[d].GetY(), och det verkar vara det som är problemet. Varför gör du så?
Principen är iaf. att räkna ut de 4 värdena för varje shape, och sen se om det finns ett överlapp. Har inte exakta formeln i huvet, men något i stil med att MinX1 \in [MinX2, MaxX2] ELLER MaxX1 \in [MinX2, MaxX2], och så motsvarande för y.
Det är dock ganska dåligt, ger fula falska kollisioner.
2. Bounding sphere. Bestäm en centrumpunkt c och en radie r på varje objekt.
kolla om |c1-c2| < r1 + r2.
Den är mycket enkel, och funkar bra om objekten påminner mer om cirklar än om rektanglar.
3. Sen finns det "Oriented bounding box" som roterar med objekt. I 2D känns det inte som att det är värt jobbet att använda dem... De är annars bra om man vill minimera "extra" kollisionarea. (Då får man kolla om någon av hörnpunkterna ligger i den andra rektangeln + några jobbiga specialfall.)
4. En som ger väldigt hög kvalitet är att först dela upp den ursprungliga formen i trianglar. Aslätt om det är en konvex form, annars är det den svåra biten (man kan kräva att den som gör formen alltid måste göra det i rätt ordning).
Sen får man jämföra alla trianglar i form1 med alla trianglar i form2, och där är det ett antal kriterier man får ställa upp.
Mitt tips är att få den första varianten att funka först - den är långsam, men den funkar.
Vad gäller rotationen så är jag inte helt med på hur du har tänkt göra. Det normala är att man gör något i stil med:
1. Flytta hela formen så att origo ligger i rotationscentrum.
2. Rotera varje punkt. (x' = x*cos(alpha) + y*sin(alpha), y' = x*sin(alpha) - y*cos(alpha) eller något i den stilen, kommer inte ihåg exakt)
3. Flytta ut formen igen.Sv:Kollision hantering, hur lösar man detta på effektivast?
Japp, jag vill ha polygoner :)
Med "inte ange formar som har fler än 2 st x-värden på samma y axel" så menade jag t.ex att det är omöjligt via min klass att hantera t.ex ett liggande S, om jag tänker rätt som jag förstås inte behöver göra.
Jag skrev den här Surface klassen ganska sent på kvällen så jag får väl skylla på att jag var trött, hur som helst så har jag tagit bort att kolla på points[i].GetY() == points[d].GetY() flera gånger :) Så om jag har förstått dig rätt så ska jag göra som jag har gjort nu, men också göra samma sak på y axeln?
Angående rotationen
Jag kan inte utgå ifrån föremålets mittpunkt för att SFML:s sf::Image::Rotate() funktion roterar bilden från den minsta (x,y) (längst upp till väntster) punkten och inte från bildens mittpunkt i sig. Jag använder nämligen mig av det biblioteket.
Men, jag ska bygga om klassen nu. Jag återkommer, men svara dock gärna ändå :)Sv: Kollision hantering, hur lösar man detta på effektivast?
<code>
#ifndef H_SURFACE_H
#define H_SURFACE_H
class Object;
class Surface
{
private:
std::vector<std::pair<Point, Point> > points;
public:
Surface() { }
bool Collision(const Point &);
bool Collision(const Surface &);
//bool PointExist(const Point &);
bool Add(const Point &, const Point &);
void Clear()
{
points.clear();
}
/*
void Rotate(const float &,sf::RenderWindow &);
float GetLowestXPoint() const;
float GetLowestYPoint() const;
float GetLargestXPoint() const;
float GetLargestYPoint() const;
*/
};
bool Surface::Collision(const Point & a)
{
int size = points.size();
for(int i=0;i<size;i++)
{
if(points[i].first.GetY() == a.GetY() && points[i].first.GetX() <= a.GetX() && a.GetX() <= points[i].second.GetX())
{
return true;
}
}
return false;
}
bool Surface::Collision(const Surface & a)
{
int size = points.size();
for(int i=0;i<size;i++)
{
for(int d = 0; d < a.points.size(); d++)
{
if(points[i].first.GetY() == a.points[d].first.GetY())
{
float me_min_x = points[i].first.GetX();
float me_max_x = points[i].second.GetX();
float you_min_x = a.points[d].first.GetX();
float you_max_x = a.points[d].second.GetX();
if(you_min_x < me_max_x && me_max_x < you_max_x )
{
return true;
}
if(me_min_x <= you_min_x && me_max_x >= you_max_x)
{
return true;
}
}
}
}
return false;
}
bool Surface::Add(const Point & a, const Point & b)
{
if(a.GetY() != b.GetY())
{
return false;
}
points.push_back(std::make_pair(a,b));
return true;
}
/*
float Surface::GetLowestXPoint() const
{
float min = points[0].GetX();
int size = points.size();
for(int i = 0; i< size; i++)
{
if(points[i].GetX() < min)
{
min = points[i].GetX();
}
}
return min;
}
float Surface::GetLargestXPoint() const
{
float max = points[0].GetX();
int size = points.size();
for(int i = 0; i< size; i++)
{
if(points[i].GetX() > max)
{
max = points[i].GetX();
}
}
return max;
}
float Surface::GetLargestYPoint() const
{
float max = points[0].GetY();
int size = points.size();
for(int i = 0; i< size; i++)
{
if(points[i].GetY() > max)
{
max = points[i].GetY();
}
}
return max;
}
float Surface::GetLowestYPoint() const
{
float min = points[0].GetY();
int size = points.size();
for(int i = 0; i< size; i++)
{
if(points[i].GetY() < min)
{
min = points[i].GetY();
}
}
return min;
}
void Surface::Rotate(const float & a, sf::RenderWindow & window)
{
int size = points.size();
Point min(GetLowestXPoint(),GetLowestYPoint());
for(int i=0;i<size;i++)
{
//float hypo = sqrt(pow(points[i].GetX()-min.GetX(),2) + pow(points[i].GetY() - min.GetY(),2));
float x = points[i].GetX()*cos(a) + points[i].GetY()*sin(a);
float y = points[i].GetX()*sin(a) - points[i].GetY()*cos(a);
std::cout << "X->" << x << std::endl;
std::cout << "Y->" << y << std::endl;
sf::Image image(5,5,sf::Color(255,255,255));
sf::Sprite sp(image);
window.Draw(sp);
sp.SetPosition(x,y);
points[i].Set(x,y);
}
window.Display();
sf::Sleep(5.f);
}
*/
#endif
</code>Sv:Kollision hantering, hur lösar man detta på effektivast?
<code>
#ifndef H_SURFACE_H
#define H_SURFACE_H
class Object;
class Surface
{
private:
std::vector<std::pair<Point, Point> > points;
public:
Surface() { }
std::vector<Point> GetPointsBetween(const Point &, const Point &) const;
bool Collision(const Point &) const;
bool Collision(const Surface &) const;
bool Add(const Point &, const Point &);
Point Surface::GetLowestPoint() const;
Point Surface::GetLargestPoint() const;
void Rotate(const float & a, sf::RenderWindow & window); /* sf::RenderWindow parametern ska bort när jag har fått rotate funktionen att fungera */
void Clear()
{
points.clear();
}
};
std::vector<Point> Surface::GetPointsBetween(const Point & a, const Point & b) const /* Säkert onödig stor lösning, men den fungerar */
{
std::vector<Point> ret;
ret.push_back(a);
if(a == b)
{
return ret;
}
ret.push_back(b);
Point max = (a.GetX() < b.GetX()) ? b : a;
Point min = (a.GetX() < b.GetX()) ? a : b;
bool shift = true;
if(min.GetY() > max.GetY())
{
shift = false;
}
float hypo = sqrt(pow(max.GetX() - min.GetX(),2) + pow(max.GetY() - min.GetY(),2));
double framex = (max.GetX() - min.GetX())/hypo;
double framey = (max.GetY() - min.GetY())/hypo;
if(shift)
{
for(float x = min.GetX(), y = min.GetY(); x<=max.GetX() || y<=max.GetY();)
{
if(x >= max.GetX() && y >= max.GetY())
{
break;
}
if(x <= max.GetX())
{
x += framex;
}
if(y <= max.GetY())
{
y += framey;
}
ret.push_back(Point(x,y));
}
}
else
{
for(float x = max.GetX(), y = max.GetY(); x>=min.GetX() || y<=min.GetY();)
{
if(x <= min.GetX() && y >= min.GetY())
{
break;
}
if(x >= min.GetX())
{
x -= framex;
}
if(y <= min.GetY())
{
y -= framey;
}
ret.push_back(Point(x,y));
}
}
return ret;
}
bool Surface::Collision(const Point & a) const
{
Point min = GetLowestPoint(), max = GetLargestPoint();
if(min.GetX() > a.GetX() || max.GetX() < a.GetX() || max.GetY() < a.GetY() || min.GetY() > a.GetY())
{
return false;
}
int size = points.size();
for(int i=0;i<size;i++)
{
float k1 = (points[i].second.GetY()-points[i].first.GetY())/(points[i].second.GetX()-points[i].first.GetX());
float k2 = (a.GetY()-points[i].first.GetY())/(a.GetX()-points[i].first.GetX());
if(k1 == k2 && a.GetX() <= points[i].second.GetX() && points[i].first.GetX() < a.GetX())
{
return true;
}
}
return false;
}
bool Surface::Collision(const Surface & a) const
{
Point min=GetLowestPoint(), max = GetLargestPoint();
if(min.GetX() > a.GetLargestPoint().GetX() || max.GetX() < a.GetLowestPoint().GetX() || max.GetY() < a.GetLowestPoint().GetY() || min.GetY() > a.GetLargestPoint().GetY())
{
return false;
}
int size = points.size();
std::vector<int> m;
m.reserve(size);
for(int i=0;i<size;i++) /* Gör jag rätt med att testa olika punkter i slumpmässig ordning? */
{
m.push_back(i);
}
std::random_shuffle(m.begin(),m.end());
for(int i = 0;i<size;i++)
{
std::vector<Point> n = GetPointsBetween(points[m[i]].first,points[m[i]].second);
int nsize = n.size();
for(int d = 0; d < nsize; d++)
{
if(a.Collision(n[d]))
{
return true;
}
}
}
return false;
}
bool Surface::Add(const Point & a, const Point & b)
{
points.push_back(std::make_pair(a,b));
return true;
}
Point Surface::GetLowestPoint() const
{
int size = points.size();
int min_x = points[0].first.GetX();
int min_y = points[0].first.GetY();
for(int i=0;i<size;i++)
{
if(min_y > points[i].first.GetY())
{
min_y = points[i].first.GetY();
min_x = points[i].first.GetX();
continue;
}
if(min_x > points[i].first.GetX() && min_y == points[i].first.GetY())
{
min_x = points[i].first.GetX();
}
}
return Point(min_x,min_y);
}
Point Surface::GetLargestPoint() const
{
int size = points.size();
int max_x = points[0].second.GetX();
int max_y = points[0].second.GetY();
for(int i=0;i<size;i++)
{
if(max_y < points[i].second.GetY())
{
max_y = points[i].second.GetY();
max_x = points[i].second.GetX();
continue;
}
if(max_x < points[i].second.GetX() && max_y == points[i].second.GetY())
{
max_x = points[i].second.GetX();
}
}
return Point(max_x,max_y);
}
void Surface::Rotate(const float & a, sf::RenderWindow & window) /* fungerar inte */
{
int size = points.size();
Point min(GetLowestPoint());
for(int i=0;i<size;i++)
{
float x = points[i].first.GetX() + (points[i].first.GetX() - min.GetX())*cos(a) + (points[i].first.GetY() - min.GetY())*sin(a);
float y = points[i].first.GetY() + (points[i].first.GetY() - min.GetY())*sin(a) - (points[i].first.GetX() - min.GetX())*cos(a);
points[i].first.Set(x,y);
x = points[i].second.GetX() + (points[i].second.GetX() - min.GetX())*cos(a) + (points[i].second.GetY() - min.GetY())*sin(a);
y = points[i].second.GetX() + (points[i].second.GetY() - min.GetY())*sin(a) - (points[i].second.GetX() - min.GetX())*cos(a);
points[i].second.Set(x, y);
}
}
#endif
</code>
Är detta en ok/bra lösning tycker du Niklas? Dessutom, hur exakt menade du att jag skulle göra för att kunna rotera punkterna? Har nämligen inte ännu fått det fungera och provat allt möjligt.Sv: Kollision hantering, hur lösar man detta på effektivast?
Jag förstår t.ex. inte vad "get points between" gör. Kollar man sen på Collision är jag inte alls med på vad du gör efter
if(min.getX()...)
Om det är för att göra en "tätare" kollisionsfit så har den iaf en ganska ordentlig bugg.
"k1 == k2" kommer aldrig inträffa i praktiken. När man jämför flyttal måste man använda något i stil med abs(a-b) < eps, där man får välja ett bra värde på eps.
Kan du beskriva lite mer hur du har tänkt?Sv:Kollision hantering, hur lösar man detta på effektivast?
Jag tänkte såhär:
Anledningen varför min rotate funktion inte fungerade i den första klassen som jag gjorde var antagligen att klassen inte klarade av om det var vilt spridda punkter, dvs punkterna behövde ligga på samma y axel. Att få rotate funktionen fungera är jätteviktigt då nästan allt går tja, åt helvete om jag inte får den att fungera. Därför tänkte jag att om jag gör om klassen så jag kan ange vilt spridda punkter så bör det i alla fall bli lättare för mig att få den funktionen att fungera. För att kolla om ett Surface har chans att ligga ovanpå ett annat så tänkte jag att om dess högsta x värde i första figuren är mindre än det andra minsta x värde så är en krok omöjlig. Detsamma gäller för Y:
<code>
if(min.GetX()....)
{
return false;
}
</code>
Detsamma gäller ju också för att kolla om en pixel så där gjorde jag samma sak :) Jag för att kolla om en punkt ligger mitt emellan 2 st andra punkter tänkte jag på det jag hade lärt mig i Matematik A, y = kx + m, d.v.s om en punkt har samma k värde som en annan punkt så ligger den på linjen, annars inte. Man kan ju liksom rita det som en triangel. Så jag har faktiskt lite svårt att förstå vad du menar med abs(a-b). Skulle vara tacksamt om du förklarade det för det enda sättet jag kan, för att kolla om en punkt finns mitt emellan två andra är just att göra på detta sättet :(
Skulle dock Surface:en befinna sig inom den minsta och högsta punkten så finns det en risk för krok. Istället för att kolla alla linjer i ordning så tänkte jag att det bör gå snabbare att göra det i slumpmässig ordning, särskilt om det är många linjer. Det bör ju gå snabbare att hitta en linje som krockar om jag gör det i slumpmässig än om inte. Eller?
Ursäktar om jag kanske skrev lite otydligt, men säg till i så fall så för jag ge det ett försök till :)
Förstår du hur jag tänker?Sv: Kollision hantering, hur lösar man detta på effektivast?
Rotationer är egentligen väldigt enkla. Du behöver en vinkel och en rotationspunkt.
Börja med att flytta hela figuren (matematikst) så att rotationspunkten ligger i origo. Så om du har punkterna (0,0), (2,0) och (2,2), och vill rotera kring (1,1), så drar du ifrån (1,1) från alla punkterna, och får de nya:
(-1, -1), (1, -1), (1,1)
Sen har du en vinkel alpha, och då gör du för varje punkt:
x' = x * cos(alpha) - y * sin(alpha)
y' = x * sin(alpha) + y * cos(alpha)
Alpha ska vara angiven i radianer.
Slutligen ska du flytta tillbaka figuren, och lägger då till rotationspunkten igen. Koden du hade innan såg iaf ut som att det var det du gjorde.
"För att kolla om ett Surface har chans att ligga ovanpå ett annat så tänkte jag att om dess högsta x värde i första figuren är mindre än det andra minsta x värde så är en krok omöjlig. Detsamma gäller för Y:"
Ja, jag tror du har gjort rätt där, jag menar att du bör nog nöja dig med detta till att börja med och se till att få programmet att fungera...
Testet är enkelt; "x1min > x2max eller x2min > x1max", och samma för y, betyder att det inte är någon kollision.
Det är det man kallar för "bounding box".
<b>Jag för att kolla om en punkt ligger mitt emellan 2 st andra punkter </b>
Varför ska du kolla det?
För det första är det mycket liten sannolikhet att den ligger mitt emellan; det som inträffar är att en punkt har åkt in inuti figuren.
<b>tänkte jag på det jag hade lärt mig i Matematik A, y = kx + m, d.v.s om en punkt har samma k värde som en annan punkt så ligger den på linjen, annars inte. </b>
Njae, en punkt har inget k-värde. Men det du gör är egentligen att bilda två linjer, dels den som går genom ett segment, och dels en som går genom den punkt du kollar. Och i det fallet är det korrekt att kolla på k-värdet. Problemet är bara:
1. Låt säga att du har en punkt som i frame 1 sitter två pixlar till vänster, och i frame två sitter två pixlar till höger om det segmentet du kollar; då hittar du inte kollisionen trots att den borde ha uppstått.
2. Även om du mot all förmodan skulle ligga på linjen, så får du t.ex. k1 = 1.00000001 och k2 = 0.9999999, och då gäller inte k1=k2, på grund av att datorn inte har så hög precision. Det du får kolla på är istället k1-k2, som i det här fallet blir typ 0.0000002, och då kan du tycka att det är ganska litet, så du kan jämföra det med t.ex. 0.01, och om diffen är mindre än 0.01 så är det "typ samma". 0.01 kallar vi "eps" i det här fallet.
Problemet är att om du skriver k1-k2 < eps, så kommer du alltid få sant om k2>k1. Så vad du tar är istället absolutbeloppet; abs(k1-k2)<eps
<b>Skulle dock Surface:en befinna sig inom den minsta och högsta punkten så finns det en risk för krok. Istället för att kolla alla linjer i ordning så tänkte jag att det bör gå snabbare att göra det i slumpmässig ordning, särskilt om det är många linjer. Det bör ju gå snabbare att hitta en linje som krockar om jag gör det i slumpmässig än om inte. Eller?</b>
Som sagt, vänta med detta - det är ett ganska svårt problem, och du täcker inte in alla specialfall. Det är inte bara att kolla om "linjer krockar". Det skulle kunna vara så att ett objekt ligger helt och hållet i ett annat, eller att de skär varandra på sätt som du inte kan hitta. Sök lite på nätet efter kollisionsdetektion, så ser du att det är rätt krångligt.
Oavsett så är det ganska vanligt med slumpmässig ordning i simulatorer, men det är inte av prestandaskäl, utan för att det ger ett vettigare beteende.
Grejen är att du måste ändå nästan alltid gå igenom alla, så din variant snabbar bara upp det i de fallen man faktiskt har kollisioner.Sv:Kollision hantering, hur lösar man detta på effektivast?
<code>
class Surface
{
public:
Surface();
virtual ~Surface();
//....
virtual void AddPoint( /* Vad ska stå här för att göra denna funktionen så framtidsäker som möjligt */ ) = 0;
};
</code>
Tack ännu en gång för ditt svar :)Sv: Kollision hantering, hur lösar man detta på effektivast?
Lägg det på de ärvda klasserna istället. Varje enskild klass får avgöra hur man ska lägga in nya punkter.
Sen är det så att för just kollisionsdetektion är det svårt att hitta en bra klasstruktur.
Du får väldigt många specialfall. Låt säga att du har "polygon", P; och "rektangel", R.
Du får du varianterna
P, P
P, R
R, P
R, R
De tre sista måste läggas till när klassen rektangel skapas. Men hur löser du det rent kodtekniskt?
Och än värre blir det förstås när "cirkel" kommer med.
Vad man ofta gör är att skippa det "snygga" och "rätta" sättet att göra det på, och istället kör med idnummer för typerna, och lägger callbacks i en hashtabell. Det är möjligt att det går att göra detta med metaprogrammering. Har du inte koll på exakt vad jag menar i det här sista stycket spelar det inte så stor roll. Poängen är att du har gett dig in i en ganska svår grej... men man lär sig mycket på det.