Durchschnitt aus mehreren Vektoren in COFFEE bilden

Brüggz

Erfahrenes Mitglied
Gibt es in COFFEE eine Möglichkeit, Rechenoperationen unkompliziert mit mehreren Vektoren durchuführen?
Wer es kennt, ich bin bei dem Videotutorial vom Königsmark Abschnitt COFFEE und Punkte. Da richtet er eine Kugel an einem selektierten Punkt eines Würfels aus.

Ich wollte nun einen Schritt weitergehen und bei mehreren selektierten Punkten die Durchschnittsposition für die Kugel zu berechnen.
Allerdings will es net so recht klappen, da Vektoren zu addieren.

Folgend der normale, funktionierende Code mit rot markiert meinen Änderungen:
Code:
main(doc,op)
{

var kugel=op->GetDown();
// wenn op-Objekt kein Polygonobjekt und kein Unterobjekt, dann Stop
if (!instanceof(op, PolygonObject)) return false;
if (kugel==NULL) return false;

var punkte=op->GetPoints();
var p_anz=op->GetPointCount();
var p_sel=op->GetPointSelection();
var p_sel_anz=p_sel->GetCount();
var i, a, posP, posGes;

// wenn entweder keine Punkte vorhanden oder selektiert, dann Stop
if (p_anz==0 || p_sel_anz==0) return false;

for (i=0; i<p_anz; i++)
	{
	if (p_sel->IsSelected(i))
		{
		posP=punkte;
		}
	posGes=(posGes.x+posP.x)/2...
	}
kugel->SetPosition(posP); kugel->SetPosition(posGes); 
println (posP); println (posGes);
}

mit dieser Zeile:
Code:
posGes=(posGes.x+posP.x)/2...
meine ich eigentlich die Errechnung des Durchschnitts der Vektoren, keine Ahnung wie das gemacht wird.
Also von der Logik her sollte der Zusatz ja stimmen: i zählt hoch, ist Punkt[i] ein selektierter, dann übergib die Position an posP und addiere diese zu PosGes, i zählt weiter hoch und das Ganze geht von vorn los und sollte demnach weiter Positionen addieren bzw. den Durchschnitt berechnen.

btw. hallo Mark :rolleyes:
 
Hi Brüggz! :)

Der Algorithmus sollte stimmen, aber zwei Punkte könnten hinderlich sein:
a) muß nicht die Berechnung mit in die If-Abfrage?
b) weiß nicht, ob man einen gesamten Vektor bearbeiten kann oder nur dessen - tja wie heißt denn das - "Koordinaten", somit verstehe ich Deine Pünktchen im Code nicht so ganz:
Code:
posGes.x=(posGes.x+posP.x)/2;
posGes.y=(posGes.y+posP.y)/2;
posGes.z=(posGes.z+posP.z)/2;
...?

Liebe Grüße,
Mark.
 
also
a) kann meiner Meinung nach, muss aber nicht. Wenn die if-Abfrage einen Wert für posP liefert, wird er trotzdem noch innerhalb des aktuellen i-Wertes zur Gesamtposition addiert. Das Addieren liegt ja innerhalb der for-Schleife, also wird auch für jeden möglichen selektierten Punkt ausgeführt.
b) Meine Denkweise war, dass man evtl. Vektor = x + y + z berechnen kann, anstatt dann 3 Variablen für jede Koordinate zu erhalten. Aber wenn es so funktioniert, soll es mir recht sein.

Werd ich ausprobieren, wenn ich wieder Zeit hab, danke!
 
Hi!

Nach "drüber nachdenken" sollte es natürlich auch mit "ganzen Vektoren" funktionieren ;)
Code:
posGes = (posGes + posP) / 2;
oder
Code:
posGes = vector(posGes.x + posP.x, posGes.y + posP.y, posGes.z + posP.z);
...wobei ersteres wohl am einfachsten/nahe liegensten ist ;)

Liebe Grüße,
Mark.
 
Es klappt so wie du geschrieben hast, ich hatte allerdings vergessen die Positionsvariablen erst als Vektoren zu deklarieren. (es sei denn, das erkennt es automatisch)

Neues Problem: Beim Durchschnittswert von 2 Punkten funktioniert es, allerdings nicht zwangsweise bei mehreren Punkten.

aktueller Code steht unten, da erstmal Nebensache.

Bei den 4 Punkten von Bild2 läuft z.B. die Berechnung von Y folgendermaßen:
zaehler=1: PosGes.y = PosP.y = -100
zaehler=2: PosGes.y = (PosGes + PosP.y)/2 = (-100 + 100)/2 =0
zaehler=3: PosGes.y = (PosGes + PosP.y)/2 = (0 + -100)/2 =-50
zaehler=4: PosGes.y = (PosGes + PosP.y)/2 = (-50 + 100)/2 =25

Logisch also, dass es so nicht funktioniert.
Ich habe nun drüber nachgedacht, innerhalb der Schleifen nur die Werte zu addieren und erst am Ende die ganze Addition durch den zaehler zu dividieren
(aus dem Beispiel wäre das:
(-100 + 100 + -100 + 100)/4 = 0/4)
Da macht er allerdings nicht mit und bringt mir einen Division durch Null-Fehler.
Auch logisch, obwohl er das komischerweise bei der ersten Variante wo der zaehler auf 2 steht nicht bringt?!

Jedenfalls bin ich grad etwas ratlos, wie man das ganze geschickt, ohne 5 Umwege lösen kann. Gibt es in Coffee eine Funktion, die selbst einen Durchschnittswert bildet oder sowas?

Zusatzfrage: wo gibt es mal die ganzen Funktionen und Operatoren von Coffee gelistet? Ich finde die SDK grausam, da sieht man einfach nicht durch.

Code:
main(doc,op)
{

var kugel=op->GetDown();
// wenn op-Objekt nicht vom Typ (Instanz) Polygonobjekt 
// und kein Unterobjekt, dann Stop
if (!instanceof(op, PolygonObject)) return false;
if (kugel==NULL) return false;

// punkte speichert Koordinaten der Punkte
var punkte=op->GetPoints();
var p_anz=op->GetPointCount();
var p_sel=op->GetPointSelection();
var p_sel_anz=p_sel->GetCount();
var i, zaehler=0;
var posP=vector(0,0,0), posGes=vector(0,0,0);

// wenn keine Punkte vorhanden, dann Stop
if (p_anz==0) return false;

// wenn keine Punkte selektiert, posGes auf 0 gesetzt
if (p_sel_anz==0) posGes=vector(0,0,0);


for (i=0; i<p_anz; i++)
	{
		// wenn aktuell durchlaufener Punkt, selektiert ist
		// setze posP auf aktuelle Punktkoordinate, zähle zaehler hoch
		if (p_sel->IsSelected(i))
			{
				posP=punkte[i];
				zaehler++;
				println ("Punkt",zaehler,": ", punkte[i]);
			
				// wenn nur 1 Punkt selektiert, setze posGes=posP
				if (p_sel_anz<=1)	posGes=posP;
				// wenn mehr als 1 Punkt selektiert:
				else
				{
					// wenn der zaehler<=1, setze posGes=posP (Startwert)
					if (zaehler<=1)	posGes=posP;
					// wenn zaehler>1, addiere neue posP zur bisherigen posGes
					else
					{
						posGes.x =(posGes.x+posP.x)/2;
						posGes.y =(posGes.y+posP.y)/2;
						posGes.z =(posGes.z+posP.z)/2;
					}
				}
			}
	}

kugel->SetPosition(posGes);

println ("aktueller Punkt: ", posP);
println ("Koordinate Durchschnitt: ", posGes);
println (" ");
}
 

Anhänge

  • 2punkte.jpg
    2punkte.jpg
    73,1 KB · Aufrufe: 19
  • 4punkte.jpg
    4punkte.jpg
    72 KB · Aufrufe: 19
Zuletzt bearbeitet:
Hi!

Zunächst: "Division by zero" sollte nur kommen, wenn der Nenner "zero" ist, der Zähler darf Null sein und so ergibt 0/4 = 0, was ja richtig ist :)

Zum eigentlichen Thema: hm, Du suchst ja nicht den Durchschnitt der Vektoren, sondern den Mittelpunkt der Punkte! Das ist ein großer Unterschied: liegen drei Punkte auf x = 0, 2 und 3, dann ist deren "Durchschnittliche Position" = (0+2+3)/3 = 5/3. Der Mittelpunkt liegt genau zwischen dem Minimum und dem Maximum, daß heißt, die Punkte dazwischen erhalten kein Gewicht / Einfluss: (0+3)/2 = 3/2.
-> Du muß die jeweiligen Minima und Maxima für X, Y und Z eruieren und schließlich davon die "Mitte" nehmen ... wenn ich Dich richtig verstanden habe ;)

Liebe Grüße,
Mark.
 
Nein ich glaube nicht :p
Nur weil im Beispiel der Mittenwert = Durchschnittswert ist, gilt das ja nicht immer.
Trotzdem danke.

Jedenfalls war mein Problem eigentlich ganz leicht lösbar :p

folgendes habe ich unter die ganzen Schleifen geschrieben (das "/2" bei der oberen Berechnung von posGes.xyz habe ich dann natürlich weggenommen)

if (posGes.x!=0) posGes.x /=zaehler;
if (posGes.y!=0) posGes.y /=zaehler;
if (posGes.z!=0) posGes.z /=zaehler;

Also wenn posGes.xyz 0 sein sollte, muss nichtmehr dividiert werden.
 
Zuletzt bearbeitet:
Hi!

*g* Du hast gewonnen, jetzt verstehe ich Dich überhaupt nicht mehr! :)

ICH schrieb doch, daß Durchschnittswert und Mittelpunkt etwas anderes ist, warum konterst Du dann mit: "gilt das ja nicht immer" ?!

Aber zum Thema: Du möchtest also bei z.B. einer Ebene, daß die Kugel, wenn Du auf der rechten Seite einen Schnitt anwendest - die Fläche also sechs statt 4 Punkte aufweist, wobei die zusätzliche zwei rechts von der Mitte liegen - die Kugel ebenfalls nach rechts wandert und nicht mehr in der Mitte der Ebene liegt? Dann ist die Durchschnittsberechnung natürlich richtig...
...ich dachte, Du die willst Kugel in der Mitte der Fläche positionieren (, wenn auch nicht unbedingt im Schwerpunkt ;) )...

Liebe Grüße,
Mark.

P.S.: Die If-Abfrage wird rechenintensiver sein, als einfach immer durch zaehler zu teilen, auch wenn posGes = 0 ist. Solange zaehler nicht null ist, ist die Operation ja dennoch richtig...
 
Ich hab gekontert, weil du angenommen hast, dass ich nicht den Durchschnitt will. ;)
Schwerpunkt ist das richtige Wort.

Wegen der if-Abfrage hast du Recht. Weiß nicht, was da vorhin falsch lief.

Btw. falls du was zwecks meiner Frage nach einer hübschen Liste/ Erklärung der Coffeesyntax weißt (ausser die hässliche SDK), lass es mich bitte wissen.
 
Hi!
Schwerpunkt ist das richtige Wort.
...der sollte aber doch nicht von der Anzahl der Punkte abhängig sein, oder?! Oder suchst Du den Schwerpunkt aller Punkte, wenn die quasi alle die gleiche Masse besäßen?! (siehe obiges Beispiel mit der Ebene)
Ich fürchte, wenn Du eine echte Schwerpunkts-Berechnung durchführen möchtest, wird's ein wenig komplizierter (Dreieckszerlegung des Polygonobjekts, Berechnung der Teil-Flächen, Addition der jeweiligen Schwerpunkte usw.)

Grüße,
Mark.
 
Zurück