int main() { Linie l; Kreis k, k1, k2; zeichne(l); // zeichne(GeoObj&) => Linie::draw() zeichne(k); // zeichne(GeoObj&) => Kreis::draw() abstand(k1,k2); // abstand(GeoObj&,GeoObj&) abstand(l,k); // abstand(GeoObj&,GeoObj&) std::vector<GeoObj*> menge; // inhomogene Menge menge.push_back(&l); // Linie einfügen menge.push_back(&k); // Kreis einfügen ausgeben(menge); // Menge ausgeben }
/* Beschreibung: * prueft, ob ein Robutton mit einem anderen Robutton kollidieren * wuerde und behandelt die Kollision * Eingabewerte: * 1. Argument: Zeiger auf die Simulationsstruktur * 2. Argument: Index des zu untersuchenden Robuttons * Rueckgabewerte: * 0, wenn der Robutton nicht kollidiert ist * 1, wenn der Robutton kollidiert ist */ char pruefe_kollision_robuttons(struct simulation *s, int i) { int j; double b; for (j = 0; j < s->anzahl_robuttons; j++) { if (i == j) continue; /* Kollision mit anderem Robutton pruefen */ if (abstand(s->neue_positionen[i], s->neue_positionen[j]) < 1.0) { /* neue Richtungen der Robuttons bestimmen */ b = acos(s->robuttons[i].richtung.x); if(s->robuttons[i].richtung.y < 0) b = 2 * M_PI - b; b += M_PI / 2.0 + M_PI * drand48(); s->robuttons[i].richtung.x = cos(b); s->robuttons[i].richtung.y = sin(b); b = acos(s->robuttons[j].richtung.x); if(s->robuttons[j].richtung.y < 0) b = 2 * M_PI - b; b += M_PI / 2.0 + M_PI * drand48(); s->robuttons[j].richtung.x = cos(b); s->robuttons[j].richtung.y = sin(b); /* neue Positionen der Robuttons bestimmen */ s->neue_positionen[i].x = s->robuttons[i].position.x + s->robuttons[i].richtung.x; s->neue_positionen[i].y = s->robuttons[i].position.y + s->robuttons[i].richtung.y; s->neue_positionen[j].x = s->robuttons[j].position.x + s->robuttons[j].richtung.x; s->neue_positionen[j].y = s->robuttons[j].position.y + s->robuttons[j].richtung.y; /* aufwendige Kollisionspruefung des 2. Robuttons vermeiden */ if (!ist_tischflaeche(s->tisch, s->neue_positionen[j].x, s->neue_positionen[j].y)) { s->neue_positionen[j].x = s->robuttons[j].position.x; s->neue_positionen[j].y = s->robuttons[j].position.y; } return (1); } } return (0); }
bool sphere::intersect(ray r, shade& rec) const { if(is_tformed()) //Wenn wir eine Transformationsmatrix haben { matrix to = gettformi(); r.ori = to * r.ori; //transformation auf den Ray anwenden r.dir = to * r.dir; r.dir.normalize(); } //Nach http://www.cs.princeton.edu/courses/archive/fall00/cs426/lectures/raycast/sld013.htm //Vector vom Strahlenursprung zum Mittelpunkt vector3d abstand(r.ori, center_); //Faktor der der Länge des Abstandes auf dem Strahl entspricht double m = dot(abstand, r.dir); if(m < 0.001){return (false);} //Sphere liegt hinter Strahlenursprung //Abstand Strahl<-> Mittelpunkt nach Phytagoras(hier zum Quadrat) double distquad = dot(abstand, abstand) - (m * m); //brauchen nur das Quadrat double radiusquad = radius_ * radius_; //besser als Wurzel ziehen //Wenn der Abstand zum Mittelpunkt größer als der Radius ist, dann schneiden if(distquad > radiusquad) {return (false);} //sie sich nicht //Schnittpunktberechnung: //Abstand von m zu einem der Schnittpunkte double n = sqrt(radiusquad - distquad); //2 Faktoren für 2 Schnittpunkte double fak1 = m - n; double fak2 = m + n; //Schnittpunkte: point3d P1 = r.ori + (fak1 * r.dir); point3d P2 = r.ori + (fak2 * r.dir); //Der Schnittpunkt näher am Strahlenurpsrung ist, ist der Gesuchte point3d Pmin; if(distance(r.ori, P1) < distance(r.ori, P2)){Pmin = P1;} else{Pmin = P2;} //Speichern der gewonnen Informationen //Nur wenn das der erste oder der vorderste Treffer ist if(distance(r.ori, Pmin) < rec.distance) { rec.didhit = true; //Juchu getroffen rec.material_ref = getmater(); vector3d normal(center_, Pmin); rec.hitpoint = Pmin; if(is_tformed()) { matrix fro = gettform(); //Tranformation des Hitpoints rec.hitpoint = fro * rec.hitpoint; //Rückstranformation der Normalen fro.transpose(); normal = fro * normal; } normal.normalize(); rec.hitpoint = rec.hitpoint + 0.05*normal; //* normal;//minimal Verschiebung verhindert Schnitt mit sich selbst rec.n = normal; rec.distance = distance(r.ori, Pmin); return (true); } return (false); }