Arbeit zu BSP
Übersicht

![]() |
VertexBetreff: Arbeit zu BSP |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
für's Studium habe ich eine Arbeit zum Thema Binary Space Partitioning Trees (BSP-Bäume) ausgearbeitet. Es geht darum, den Algorithmus zum Erstellen eines solchen Baums zu parallelisieren. Wen es interessiert, die Arbeit kann unter http://vertex.dreamfall.at/bsp...lelbsp.pdf eingesehen werden. Der erste Teil beschäftigt sich mit dem BSP-Algorithmus (das wäre für euch 3D Grafiker sicherlich der interessante Teil) und der zweite Teil mit dem Parallelisieren mittels Work Stealing. Die Anwendung habe ich nicht hochgeladen, weil Webserver auf ein paar MB begrenzt ist und zweitens das Projekt in Java programmiert wurde. Ciao Olli Edit: Manchmal sucht man ja im Forum nach einer Funktion, die ein Dreieck an einer Ebene schneidet: Code: [AUSKLAPPEN] package de.skawronek.parallelbspcompiler.math;
/** * Eine Ebene in Hesse-Normalenform beschrieben durch den Normalenvektor * {@link #normal} und die Konstante {@link #constant}. * * @author Oliver Skawronek * */ public class Plane { public static enum Side { Planar, Positive, Negative; } private Vector3d normal; private double constant; public Plane() { normal = new Vector3d(); } public Plane(Vector3d normal, double constant) { this.normal = normal; this.constant = constant; } public Plane(Triangle triangle) { normal = triangle.getNormal(); constant = triangle.get1().dot(normal); } public Vector3d getNormal() { return normal; } public double getConstant() { return constant; } public double distance(Vector3d point) { return normal.dot(point) - constant; } /** * * @param point * @return Seite, auf der <code>point</code> liegt. */ public Side side(Vector3d point) { double d = distance(point); if (Math.abs(d) < Constants.DBL_EPSILON) return Side.Planar; else if (d > 0.0) return Side.Positive; else return Side.Negative; } /** * Ermittelt die Seite, auf der <code>triangle</code> liegt: * <ul> * <li>alle Eckpunkte liegen entweder auf der positiven Seite oder sind plan * zur Ebene: {@link Side#Positive}</li> * <li>alle Eckpunkte liegen entweder auf der negativen Seite oder sind plan * zur Ebene: {@link Side#Negative}</li> * <li>sonst: {@link Side#Planar}</li> * </ul> * * @param triangle * @return Seite, auf der das Dreieck liegt. */ public Side side(Triangle triangle) { int planar = 0, pos = 0, neg = 0; for (int i = 0; i < 3; i++) { switch (side(triangle.get(i))) { case Planar: planar++; break; case Positive: pos++; break; case Negative: neg++; break; } } // Liegen alle drei Ecken auf der Ebene? if (planar == 3) { // Zeigt der Normalvektor des Dreiecks in die selbe Richtung wie die // Ebene? if (Math.abs(normal.dot(triangle.getNormal()) - 1.0) < Constants.DBL_EPSILON) return Side.Positive; else return Side.Negative; // Liegen alle Ecken auf der pos. Seite, // oder liegen zwei Ecken auf der Ebene und eine auf der pos. Seite, // oder liegt eine Ecke auf der Ebene und die anderen zwei auf der // pos. Seite? } else if (pos + planar == 3) { return Side.Positive; // Liegen alle Ecken auf der neg. Seite, // oder liegen zwei Ecken auf der Ebene und eine auf der neg. Seite, // oder liegt eine Ecke auf der Ebene und die anderen zwei auf der // neg. Seite? } else if (neg + planar == 3) { return Side.Negative; // Sonst wird das Dreieck geteilt } else { return Side.Planar; } } /** * Berechnet den Schnittpunkt von <code>line</code> mit der Ebene und gibt * diesen zurück. Gibt es keinen Schnittpunkt, wird <code>null</code> * zurückgegeben. * * @param line * @return Schnittpunkt von <code>line</code> mit der Ebene oder * <code>null</code>. */ public Vector3d intersects(Line line) { // d = p2 - p1 Vector3d direction = line.getEnd().copy(); direction.substract(line.getStart()); // n*d double denominator = normal.dot(direction); if (Math.abs(denominator) < Constants.DBL_EPSILON) return null; // t = (c - n*p1)/(n*d) double t = (constant - normal.dot(line.getStart())) / denominator; // Punkt auf Linie? if (t < 0.0 || t > 1.0) return null; // p1 + t*d Vector3d intersection = direction.copy(); intersection.scale(t); intersection.add(line.getStart()); return intersection; } /** * Teilt <code>triangle</code> an der Ebene. Die Dreiecke auf der positiven * Seite werden in <code>positiveTriangles</code> und auf der negativen * Seite in <code>negativeTriangles</code> eingefügt. Die beiden Arrays * müssen mindestens zwei Elemente groß sein. Um anschließend zur ermitteln, * wieviele Dreiecke in welches Array eingefügt worden, sollten alle * Elemente der Arrays vorher auf <code>null</code> gesetzt werden. * * @param triangle * @param positiveTriangles * @param negativeTriangles */ public void intersects(Triangle triangle, Triangle[] positiveTriangles, Triangle[] negativeTriangles) { // Ebenenseiten aller Eckpunkte int planCount = 0; int posCount = 0; int negCount = 0; Side[] sides = new Side[3]; for (int i = 0; i < 3; i++) { sides[i] = side(triangle.get(i)); switch (sides[i]) { case Planar: planCount++; break; case Negative: negCount++; break; case Positive: posCount++; break; } } if (planCount == 3) { if (Math.abs(normal.dot(triangle.getNormal()) - 1.0f) < Constants.DBL_EPSILON) positiveTriangles[0] = triangle; else negativeTriangles[0] = triangle; return; } else if (planCount + posCount == 3) { positiveTriangles[0] = triangle; return; } else if (planCount + negCount == 3) { negativeTriangles[0] = triangle; return; } Line[] edges = new Line[3]; edges[0] = triangle.getEdge1(); edges[1] = triangle.getEdge2(); edges[2] = triangle.getEdge3(); // Kollision aller Kanten mit der Ebene Vector3d[] intersections = new Vector3d[3]; for (int i = 0; i < 3; i++) { intersections[i] = intersects(edges[i]); } if (sides[1] != Side.Planar && intersections[0] != null && intersections[0].equals(intersections[1])) { if (sides[1] == Side.Positive) { positiveTriangles[0] = triangle; } else { negativeTriangles[0] = triangle; } } else if (sides[2] != Side.Planar && intersections[1] != null && intersections[1].equals(intersections[2])) { if (sides[1] == Side.Positive) { positiveTriangles[0] = triangle; } else { negativeTriangles[0] = triangle; } } else if (sides[0] != Side.Planar && intersections[2] != null && intersections[2].equals(intersections[0])) { if (sides[2] == Side.Positive) { positiveTriangles[0] = triangle; } else { negativeTriangles[0] = triangle; } } else if (sides[0] == Side.Planar) { if (sides[1] == Side.Positive) { positiveTriangles[0] = new Triangle(triangle.get1(), triangle.get2(), intersections[1]); negativeTriangles[0] = new Triangle(triangle.get1(), intersections[1], triangle.get3()); } else { negativeTriangles[0] = new Triangle(triangle.get1(), triangle.get2(), intersections[1]); positiveTriangles[0] = new Triangle(triangle.get1(), intersections[1], triangle.get3()); } } else if (sides[1] == Side.Planar) { if (sides[0] == Side.Positive) { positiveTriangles[0] = new Triangle(triangle.get1(), triangle.get2(), intersections[2]); negativeTriangles[0] = new Triangle(intersections[2], triangle.get2(), triangle.get3()); } else { negativeTriangles[0] = new Triangle(triangle.get1(), triangle.get2(), intersections[2]); positiveTriangles[0] = new Triangle(intersections[2], triangle.get2(), triangle.get3()); } } else if (sides[2] == Side.Planar) { if (sides[1] == Side.Positive) { positiveTriangles[0] = new Triangle(intersections[0], triangle.get2(), triangle.get3()); negativeTriangles[0] = new Triangle(intersections[0], triangle.get3(), triangle.get1()); } else { negativeTriangles[0] = new Triangle(intersections[0], triangle.get2(), triangle.get3()); positiveTriangles[0] = new Triangle(intersections[0], triangle.get3(), triangle.get1()); } } else if (intersections[0] != null && intersections[1] != null) { if (sides[1] == Side.Positive) { positiveTriangles[0] = new Triangle(intersections[0], triangle.get2(), intersections[1]); negativeTriangles[0] = new Triangle(triangle.get1(), intersections[0], intersections[1]); negativeTriangles[1] = new Triangle(triangle.get1(), intersections[1], triangle.get3()); } else { negativeTriangles[0] = new Triangle(intersections[0], triangle.get2(), intersections[1]); positiveTriangles[0] = new Triangle(triangle.get1(), intersections[0], intersections[1]); positiveTriangles[1] = new Triangle(triangle.get1(), intersections[1], triangle.get3()); } } else if (intersections[1] != null && intersections[2] != null) { if (sides[2] == Side.Positive) { positiveTriangles[0] = new Triangle(intersections[1], triangle.get3(), intersections[2]); negativeTriangles[0] = new Triangle(triangle.get1(), triangle.get2(), intersections[1]); negativeTriangles[1] = new Triangle(triangle.get1(), intersections[1], intersections[2]); } else { negativeTriangles[0] = new Triangle(intersections[1], triangle.get3(), intersections[2]); positiveTriangles[0] = new Triangle(triangle.get1(), triangle.get2(), intersections[1]); positiveTriangles[1] = new Triangle(triangle.get1(), intersections[1], intersections[2]); } } else if (intersections[2] != null && intersections[0] != null) { if (sides[0] == Side.Positive) { positiveTriangles[0] = new Triangle(triangle.get1(), intersections[0], intersections[2]); negativeTriangles[0] = new Triangle(intersections[0], triangle.get2(), triangle.get3()); negativeTriangles[1] = new Triangle(triangle.get3(), intersections[2], intersections[0]); } else { negativeTriangles[0] = new Triangle(triangle.get1(), intersections[0], intersections[2]); positiveTriangles[0] = new Triangle(intersections[0], triangle.get2(), triangle.get3()); positiveTriangles[1] = new Triangle(triangle.get3(), intersections[2], intersections[0]); } } } @Override public String toString() { return "(" + normal.x + ", " + normal.y + ", " + normal.z + ", " + constant + ")"; } @Override public boolean equals(Object obj) { if (!(obj instanceof Plane)) return false; Plane plane = (Plane) obj; return normal.equals(plane.normal) && Math.abs(constant - plane.constant) < 0.0001; } } |
||
- Zuletzt bearbeitet von Vertex am Sa, Jan 15, 2011 18:31, insgesamt einmal bearbeitet
![]() |
Ana |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich hab mal den anfang angelesen und scheint ja recht interessant zu sein, selbst dafür das ich Grafik als solches nicht so spannend finde. Vielen dank dafür und viel erfolg damit ![]() Ich versteh zwar nicht viel von Rechtsangelegenheiten, aber hat eine Uni nicht die veröffentlichungsrechte für solche Sachen und nicht der Verfasser? Lg Diana |
||
Don't only practice your art,
but force your way into its secrets, for it and knowledge can raise human to divine |
![]() |
Firstdeathmaker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn die Uni dir als Hausaufgabe aufgibt, das zu programmieren, dann hast du noch lange keinen Vertrag mit denen geschlossen, dass du alle Rechte daran abgibst. Von daher kann man damit machen was man will. Problematisch wirds erst, wenn die Uni vielleicht im Jahr darauf die gleiche Aufgabe stellt, und man deine Lösung per im Internet finden kann. Aber illegal ist das nicht, ist schließlich dein code.
Zum Thema: Interressant, mich würde das Konzept interessieren wie du das auf mehrere Prozesse/Threads verteilst. Ich googel mal ![]() |
||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
![]() |
Hummelpups |
![]() Antworten mit Zitat ![]() |
---|---|---|
hm, kenne ich aber auch das man als Student seine Arbeiten nich
einfach so ins Netz stellen sollte :/ warum, weiß ich nicht. |
||
blucode - webdesign - Ressource - NetzwerkSim
BlitzBasic 2D - BlitzMax - MaxGUI - Monkey - BlitzPlus |
![]() |
ozzi789 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nice. thx | ||
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5 |
![]() |
Arrangemonk |
![]() Antworten mit Zitat ![]() |
---|---|---|
bsp nix gut für aufwendige szenen, esseiden, man arbeitet wie in der unreal engine mit static meshes, die mit dem bsp nur ausmachen, ob sie überhaupt sichtbar sind | ||
ingeneur |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
In solchen Arbeiten steckt richtig viel Zeit drin und da finde ich es einfach zu schade, dass es sich einer mal durchliest und das wars. Wenn ich zu einem speziellen Thema was suche, bin ich auch immer froh eine PDF bei Google dazu zu finden und wenn jemand etwas zu BSP sucht, wird es vllt. auch nützlich finden. Zudem habe ich nichts unterschrieben, dass ich irgendwelche Rechte an die BA abtrete. Anders sieht das mit unseren Projektarbeiten in Zusammenarbeit mit unseren Praxispartnern aus. Da steckt dann auch Firmen-Know-How drin, wass natürlich nicht ohne Absprache veröffentlicht werden sollte.
Habe mal im ersten Post noch den Code für die Klasse Plane hinzugefügt. In der Arbeit ist zwar immer die Rede davon, dass ein Polygon (hier ausschließlich Dreiecke) an einer Ebene geteilt werden sollen, aber wie das funktioniert nicht (es ging ja auch hauptsächlich um das Parallelisieren). Im Code kann man sich das aber mal anschauen (Plane.intersects(Triangle ....)) Ciao Olli |
||
vertex.dreamfall.at | GitHub |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group