/* Copyright (C) 2014 A.Vontobel  
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * The license is in LICENCE-GPL.txt.
 * If not, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
 */

package net.sf.drawj2d.cmd.statics;

import net.sf.drawj2d.cmd.Fkt;
import java.util.*;

/**
 *
 * @author av
 */
public class clResultierende extends net.sf.drawj2d.cmd.statics.clKraft {

    private ArrayList kräfte = new ArrayList();

    public clResultierende() {
        super(0, 0, 0, 0);
        GESPERRT = true; // verhindert das direkte Überschreiben der Resultierenden.
        ZUERSTBERECHNEN = true; // führt nach, ob das Resultat schon berechnet und noch aktuell ist.
    }

    /** Fügt eine Kraft hinzu.
    @return Anzahl Teilkräfte (nach dem Hinzufügen) */
    public int add(clKraft neueKraft) {
        boolean hinzugefügt = kräfte.add(neueKraft);
        if (!hinzugefügt) {
            System.err.println("[clResultierende] Fehler: Kraft hinzufuegen fehlgeschlagen!");
        }
        ZUERSTBERECHNEN = true;
        return kräfte.size();
    }

    /** Berechnet die Resultierende. Die Methode wird von der Vaterklasse clKraft aufgerufen,
    wenn ein Resultat abgefragt wird, und ZUERSTBERECHNEN gesetzt ist.
     Die Methode muss nur von Hand aufgerufen werden, wenn eine bereits hinzugefügte Kraft geändert wurde.*/
    @Override
    public boolean berechnen() {
        double Rx = 0;
        double Ry = 0;
        double x0, y0;

        if (debug) {
            System.out.println("[clResultierende]: berechnen");
        }
        double M = 0;
        /** Bezugspunkt.
         * An sich beliebig, gewählt wird der arithm.Mittelpunkt (der Kräfte ungleich 0).
         * Am Schluss wird der Punkt der Resultierenden gespeichert, der am nächsten zum arithm.Mittelpunkt liegt.*/
        double[] arithmMittelpkt = new double[2];
        int anzKräfte = 0; // Anzahl Kräfte, ohne Nullkräfte
        for (clKraft aktKraft : kräfte) {
            if (aktKraft.f() != 0) {
                anzKräfte++;
                arithmMittelpkt[0] += aktKraft.pkt()[0];
                arithmMittelpkt[1] += aktKraft.pkt()[1];
            }
        }
        if (anzKräfte == 0) {
            anzKräfte = 1; // Division durch 0 verhindern
        }
        arithmMittelpkt[0] /= anzKräfte;
        arithmMittelpkt[1] /= anzKräfte;

        for (clKraft aktKraft : kräfte) {
            Rx += aktKraft.F()[0];
            Ry += aktKraft.F()[1];
            //double dx = aktKraft.pkt()[0] - arithmMittelpkt[0];
            //double dy = aktKraft.pkt()[1] - arithmMittelpkt[1];
            //M += dx * aktKraft.F()[1] - dy * aktKraft.F()[0]; // TODO clKraft.getM könnte verwendet werden.
            M += aktKraft.getM(arithmMittelpkt);
        }

        // Bezugspunkt suchen.
        x0 = arithmMittelpkt[0];
        y0 = arithmMittelpkt[1];
        double Rabs = Math.sqrt(Rx * Rx + Ry * Ry); // Absolutwert der Resultierenden
        if (Rabs != 0) { // Division durch 0 verhindern
            double abstand = M / Rabs;
            double ex = Ry / Rabs;   // senkrechte auf Resultierende, normiert, x-Komponente
            double ey = -Rx / Rabs;  // senkrechte auf Resultierende, normiert, y-Komponente
            x0 += abstand * ex;
            y0 += abstand * ey;
        }

        setKraftIntern(Rx, Ry, x0, y0);

        if (debug) {
            System.out.println("[clResultierende]: berechnen fertig");
        }
        ZUERSTBERECHNEN = false;
        return true;
    }
    
    /** Gibt die Kraftkomponenten an.*/
    @Override
    public double[] F() {
        aktualisiere();
        return super.F();
    }
    
    /** Gibt den Absolutwert der Kraft an.*/
    @Override
    public double f() {
        aktualisiere();
        return super.f();
    }
    
    /** Angriffspkt*/
    @Override
    public double[] pkt() {
        aktualisiere();
        return super.pkt();
    }
    
    /** Schreibt die Angaben zur Kraft auf stdout.*/
    @Override
    public void print() {
        aktualisiere();
        super.print();
    }
    
    /** Angaben zur Kraft. */
    @Override
    public String text() {
        aktualisiere();
        return super.text();
    }

    /** Anzahl Kräfte, welche die Resultierende zusammenfasst. */
    public int anz() {
        return kräfte.size();
    }
    
    /** Gibt an, ob eine hinzugefügte Kraft geändert hat. Prüft, ob eine Kraft ZUERSTBERECHNEN == true hat.
     Falls ja, wird für die Kraft berechnen() aufgerufen.
     * Im Zweifelsfall R.berechnen() aufrufen! */ // TODO
    private boolean aktualisiere() {
        boolean hatgeändert = false;
        for (clKraft aktKraft : kräfte) {
            if (aktKraft.ZUERSTBERECHNEN || aktKraft.HATGEÄNDERT) {
                aktKraft.berechnen();
                ZUERSTBERECHNEN = true;
            }
        }
        if (hatgeändert) berechnen();
        return hatgeändert;
    }

    /** Test*/
    public static void main(String[] args) {
        clKraft kraftH = new clKraft(-35, 0, 7.2, 4.8);
        clKraft kraftF4 = new clKraft(0, -12, 5.8, 4.3);
        clKraft kraftF3 = new clKraft(0, -20, 3.3, 4.0);
        clKraft kraftF2 = new clKraft(0, -27, 1.5, 3.8);
        clKraft kraftF1 = new clKraft(0, -28, 1.0, 1.3);
        clResultierende R = new clResultierende();
        R.add(kraftH);
        R.add(kraftF4);
        R.add(kraftF3);
        R.add(kraftF2);
        R.add(kraftF1);
        System.out.println("Rx = " + Fkt.nf(R.F()[0], 1));
        System.out.println("Ry = " + Fkt.nf(R.F()[1], 1));
        System.out.println("x0 = " + Fkt.nf(R.pkt()[0], 3));
        System.out.println("y0 = " + Fkt.nf(R.pkt()[1], 3));
        // auf Grundlinie (x-Achse)
        double[] X = new double[2];
        boolean nichtparallel = R.getAngriffspktAufLinie(0, 0, 2, 0, X);
        if (!nichtparallel) {
            System.err.println("Warnung: Grundlinie parallel zur Wirkungslinie. Kein Schnittpunkt.");
        }
        System.out.println("x1 = " + Fkt.nf(X[0], 3));
        System.out.println("y1 = " + Fkt.nf(X[1], 3));
    }
}

 

Ads help maintain this website.