Hallo,
ich musste für eine Simulation die Gewichtsverteilung einer Masse im Ursprung auf mehrere Stützpunkte berechnen.
Dazu habe ich das folgende Script geschrieben, vielleicht kann es mal jemand gebrauchen.
PHP-Code:
// Punktklasse
// Speichert Koordinaten und
// Gewichtung eines Punktes
Point = function(x, y)
{
this.x = x;
this.y = y;
this.w = 0;
}
Point.prototype.setWeight = function(w)
{
this.w = w;
};
// Baryzentrumklasse
// Speichert Koordinaten,
// Gewichtung und
// Teilpunkreferenzen eines Baryzentrums
Barycentre = function(p1, p2)
{
this.x = (p1.x + p2.x) / 2;
this.y = (p1.y + p2.y) / 2;
this.w = 0;
this.p1 = p1;
this.p2 = p2;
}
// legt das Gewicht eines Baryzentrums fest
// und weist den Teilpunkten / Teilbaryzentren ihr Gewicht zu
Barycentre.prototype.setWeight = function(w)
{
this.w = w;
this.p1.setWeight(w / 2);
this.p2.setWeight(w / 2);
};
// Diese Funktion Reduziert die Menge aller Punkte
// auf 3 Punkte oder Baryzentren
function reduce(points)
{
var l;
var i;
var j;
var z;
var steps = new Array();
var step;
var source = points;
var pos;
var depth = 0;
while(source.length > 3)
{
l = source.length;
z = Math.floor(l / 2);
i = l;
j = l - i;
step = (steps[depth] = new Array());
depth++;
while((i > 3) && (j < z))
{
pos = 2 * j;
step.push(new Barycentre(source[pos], source[pos + 1]));
i--;
j = l - i;
}
if((l % 2) == 1)
{
step.push(source[l - 1]);
}
else if(l == 4)
{
step.push(source[l - 2]);
step.push(source[l - 1]);
}
source = step;
}
return source;
}
// diese Funktion berechnet die Gewichtsverteilung
// auf 3 Punkte oder Baryzentren
// Diese sorgen dann für die weitere Verteilung
// auf ihre Teilpunkte / Teilbaryzentren
function setWeights(points, w)
{
var A = points[0];
var B = points[1];
var C = points[2];
var divisor = B.x * C.y + A.y * C.x + B.y * A.x - B.y * C.x - A.x * C.y - B.x * A.y;
divisor /= w;
C.setWeight((B.y * A.x - B.x * A.y) / divisor);
B.setWeight((A.y * C.x - A.x * C.y) / divisor);
A.setWeight((B.x * C.y - B.y * C.x) / divisor);
}
// diese Funktion ermittelt die Koordinaten eines
// Baryzentrums einer Menge von Punkten oder Baryzentren
// unter verwendung ihrer Gewichte
function getBarycentre(points)
{
var w = 0;
var x = 0;
var y = 0;
var p;
var i = points.length;
while(--i > -1)
{
p = points[i];
w += p.w;
x += p.w * p.x;
y += p.w * p.y;
}
return {x: x / w, y: y / w, w: w};
}
// in diesem Array werden die Ursprungspunkte gespeichert
var points = new Array();
var n = 20;
var r = 50;
var angle = 0;
// Punkte werden eingefüllt, ihr Schwerpunkt muss im Ursprung liegen
for(var i=0; i < n; i++)
{
angle = 2 * Math.PI / n * i;
points.push(new Point(r * Math.cos(angle), r * Math.sin(angle)));
}
// hier werden die 3 durch Reduktion
// erhaltenen Punkte oder Baryzentren gespeichert
new_points = reduce(points);
// Das Gesammtgewicht wird festgelegt und evtl.
// durch Rekursion auf die Punkte und Baryzentren verteilt
setWeights(new_points, 4);
// Zur Kontrolle berechne ich das Baryzentrum der
// nun gewichteten Punkte
bz = getBarycentre(new_points);
// Ausgabe des Baryzentrums,
// muss 0 | 0 und das oben angegebene erhalten
trace(Math.round(bz.x) + " | " + Math.round(bz.y) + " (Gesammtgewicht: " + bz.w + ")");
EDIT: noch das Lämpchen davor gemacht