4 Stimmen

Zeichnen der Scheiben eines 3D-Tortendiagramms in der richtigen Reihenfolge

Ich versuche gerade, eine alte Anwendung zu reparieren: Ich habe eine Funktion, die ein Paar von Winkeln nimmt und zeichnet eine 3D-Scheibe eines explodierten Tortendiagramms. Ich habe auch Funktionen, die eine Sammlung von Zahlen nehmen, erzeugen die Winkel und rufen die Scheibe Zeichnung Funktion wiederholt, bis die gesamte Torte gezeichnet wird.

Wiederholte Aufrufe der Funktion zum Zeichnen von Slices überlagern die bereits vorhandenen Slices und die Reihenfolge ist nie ganz richtig. Meine Frage ist, wie kann ich garantieren, dass die Stücke am nächsten an den Betrachter zuletzt gezeichnet werden, so dass die Stücke richtig überlappen?

function drawSlice(startAngle, endAngle)
  // draws a slice as shown in picture

function drawPie(list of angles to make up pie)
  for each angle in angles
    drawSlice(angle)

// example usage
drawPie([30,15,40,10,5])

Eine Scheibe sieht so aus: Alt-Text http://img233.imageshack.us/img233/2627/slice.png

2voto

macbirdie Punkte 15798

Vielleicht müssen Sie das Zeichnen der Scheiben in zwei gleiche Etappen unterteilen. Beide beginnen in dem Winkel, der am weitesten vom Betrachter entfernt ist, und verlaufen in entgegengesetzter Richtung.

Nachdem Sie die Scheiben in zwei Stufen geteilt haben, sortieren Sie die beiden ganzen Scheiben und die beiden Teile der Scheibe, die auf der 50 %-Grenze lag, nach ihrem Mittelpunkt auf dem Umfang in Richtung des Betrachters.

Wenn es z.B. zwei Scheiben gibt, die erste ist 80% und beginnt in dem Winkel, der am weitesten vom Betrachter entfernt ist, würde man sie in zwei Scheiben aufteilen, wobei 50% in der ersten Phase gezeichnet werden, dann würde man die 20% Scheibe zeichnen, die oben beginnt und in die andere Richtung geht und erst dann würde man die restlichen 30% der ersten Scheibe zeichnen.

Entschuldigen Sie die umständliche Erklärung, aber ich hoffe, Sie haben den Sinn verstanden ;)

Bearbeiten: Zur Veranschaulichung des Falles, dass ein kleines Stück sowohl überlappt als auch ein größeres Stück überlappt. Beachten Sie jedoch, dass es sich hier nicht um eine explodierte Torte handelt und diese viel einfacher zu zeichnen ist.

Example chart for a Stack Overflow question

1voto

user4812 Punkte 5312

EDIT :

mbeckish hat Recht - das sollte das Problem lösen. Bauen Sie zwei Listen mit der "Cartoon-Race-Methode" auf - d.h. fügen Sie so lange zu einer Liste hinzu, bis der Gesamtgehalt an Winkeln die andere Liste übersteigt, wechseln Sie dann die Liste und machen Sie weiter. Sobald das erledigt ist, zeichnen Sie die "kleinere" Liste zuerst. Da diese höchstens 180 Grad enthält, kann sie den Gefahrenpunkt nie überschreiten. Wenn sie gleich groß sind, ist das egal. (Es ist nicht schön)

define clockwiseAngles[], antiClockwiseAngles[]
define totalClockwiseAngles, totalAntiClockwiseAngles

for each angle in angles
  if totalClockwiseAngles > totalAntiClockwiseAngles
    totalAntiClockwiseAngles += angle
    AntiClockwiseAngles.push(angle)
  else
    totalClockwiseAngles += angle
    clockwiseAngles.push(angle)

if totalClockwiseAngles > totalAntiClockwiseAngles
  // draw all anticlockwise angles
  // draw all clockwise angles
else
  // draw all clockwise angles  
  // draw all anticlockwise angles

1voto

Lars Haugseth Punkte 14242

Unter der Annahme, dass der Wert des Winkels, wenn er gerade auf uns gerichtet ist, 270 beträgt, ergibt sich einfach den Abstand des Mittelpunkts der Scheiben von dieser Sechs-Uhr-Linie berechnen:

 Math.abs(270 - (startAngle + endAngle) / 2)

Anschließend sortieren Sie die Scheiben nach diesem Abstand und zeichnen sie in absteigender Reihenfolge.

0voto

overslacked Punkte 4067

Angenommen, die Funktion, die das Slice zeichnet, hat ihre Daten in einer Art Liste, dann sortieren Sie diese Liste so, dass die näheren Elemente später erscheinen und zuletzt gezeichnet werden.

Einige Codes oder andere Details würden jedoch helfen, Ihnen eine bessere Antwort zu geben.

0voto

mbeckish Punkte 10318

Vielleicht sollten Sie einfach die Standardmethoden verwenden, um einen Zylinder aus einer bestimmten Perspektive zu zeichnen, und dann die Oberfläche des Zylinders einfärben, um die Slices abzugrenzen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X