pfeil am spline laufen lassen

Status
Nicht offen für weitere Antworten.

KillaBee

Mitglied
HAllo Leute,

ich möchte ein Programm, wo ich einen Pfeil an einem selbstgemalten spline entlang laufen lassen möhte.

Leider habe ich keine ahnung wie ich das anstellen soll.

mein bisherigen Coe seht ihr hier:

Bitte helft mir.

Code:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;

public class LineTest extends Applet implements AdjustmentListener,
									ItemListener, ActionListener {
    static final int WIDTH	= 0;
    static final int SKEW	= 1;
    static final int SCALE	= 2;
    static final int ROTATE	= 3;

    static String labels[] = {
        "Linienstärke:",
        "Verzerrung:",
        "Größe ändern:",
        "Rotation:",
    };

    static final int MIN = 0;
    static final int DEF = 1;
    static final int MAX = 2;

    static double limits[][] = {
        {0.0,		4.0,	20.0},
        {-2.0,		0.0,	2.0},
        {0.01,		0.8,	3.0},
        {-Math.PI,	0.0,	Math.PI},
    };


    Button resetbutton;				//Reset Button
    Checkbox doublebuftoggle;		//DoubleBuffer Button, damit's nicht flackert
    Checkbox antialiastoggle;		//Antialias für glatte Ränder
    TextField fields[] = new TextField[labels.length];
    Scrollbar sliders[] = new Scrollbar[labels.length];
    BezierCanvas canvas;

    public void init() {
        setLayout(new BorderLayout());
        setBackground(Color.gray);
        add("Center", canvas = new BezierCanvas(this));

        Panel p = new Panel();

        //GridBagLayout definiert das eigentliche Layout der tabelle(Anordnung)
        GridBagLayout gridbag = new GridBagLayout();

        //Begrenzungen einrichten
        GridBagConstraints c = new GridBagConstraints();
        c.anchor = GridBagConstraints.WEST;
        c.gridx = 0;	//gridx, gridy = Startposition
        c.gridy = 0;

        doublebuftoggle = new Checkbox("Double Buffer", false);
        doublebuftoggle.addItemListener(this);

        gridbag.setConstraints(doublebuftoggle, c);
        p.add(doublebuftoggle);
        c.gridx++;
        antialiastoggle = new Checkbox("Antialias", false);
        antialiastoggle.addItemListener(this);
        gridbag.setConstraints(antialiastoggle, c);
        p.add(antialiastoggle);
        c.gridx = 0;
        c.gridy++;
        p.setLayout(gridbag);
        resetbutton = new Button("Reset");
        resetbutton.addActionListener(this);
        gridbag.setConstraints(resetbutton, c);
        p.add(resetbutton);
        c.gridy++;
        c.gridwidth = 2;
        c.fill = GridBagConstraints.HORIZONTAL;
        for (int i = 0; i < fields.length; i++) {
            Panel p2 = new Panel();
            GridBagLayout gb2 = new GridBagLayout();
            GridBagConstraints c2 = new GridBagConstraints();
            c2.gridx = 0;
            c2.gridy = 0;
            c2.anchor = GridBagConstraints.WEST;
            c2.weightx = 1.0;
            p2.setLayout(gb2);
            Label label = new Label(labels[i]);
            gb2.setConstraints(label, c2);
            p2.add(label);
            c2.gridx = 1;
            c2.anchor = GridBagConstraints.EAST;
            fields[i] = new TextField("", 6);
            gb2.setConstraints(fields[i], c2);
            p2.add(fields[i]);
            c2.gridx = 0;
            c2.gridy = 1;
            c2.gridwidth = 2;
            c2.fill = GridBagConstraints.HORIZONTAL;
            sliders[i] = new Scrollbar(Scrollbar.HORIZONTAL,
                                       0, 20, 0, 120);
            sliders[i].addAdjustmentListener(this);
            gb2.setConstraints(sliders[i], c2);
            p2.add(sliders[i]);

            c.gridy++;
            gridbag.setConstraints(p2, c);
            p.add(p2);
        }
        add("West", p);
        resetValues();
    }

    Choice makeChoice(String labelstr, Panel p,
                      GridBagLayout gridbag, GridBagConstraints c,
                      String[] items) {
        Label label = new Label(labelstr);
        gridbag.setConstraints(label, c);
        p.add(label);
        c.gridx++;
        Choice choice = new Choice();
        choice.addItemListener(this);
        for (int i = 0; i < items.length; i++) {
            choice.add(items[i]);
        }
        gridbag.setConstraints(choice, c);
        p.add(choice);
        c.gridx = 0;
        c.gridy++;
        return choice;
    }

    public void resetValues() {
        canvas.stroke = 1;
        for (int i = 0; i < limits.length; i++) {
            double def = limits[i][DEF];
            fields[i].setText(roundstr(def));
            sliders[i].setValue(sliderset(i, def));
            handleValue(i, def);
        }

        canvas.repaint();

    }

    public void handleValue(int index, double val) {
        switch (index) {
        case WIDTH:
            canvas.penwidth = val;
            break;
        case SKEW:
            canvas.skew = val;
            break;
        case SCALE:
            canvas.scale = val;
            break;
        case ROTATE:
            canvas.rotate = val;
            break;
        }
    }

    public String roundstr(double value) {
        return Double.toString(Math.round(value * 100.0) / 100.0);
    }

    public int sliderset(int fieldindex, double val) {
        return (int) (100.0 * ((val - limits[fieldindex][MIN])
                               / (limits[fieldindex][MAX]
                                  - limits[fieldindex][MIN])));
    }

    public double fieldval(int fieldindex) {
        TextField t = fields[fieldindex];
        String val = t.getText();
        double ret;
        try {
            ret = Double.valueOf(val).doubleValue();
        } catch (NumberFormatException e) {
            ret = limits[fieldindex][DEF];
        }
        ret = Math.max(limits[fieldindex][MIN],
                       Math.min(limits[fieldindex][MAX], ret));
        t.setText(roundstr(ret));
        sliders[fieldindex].setValue(sliderset(fieldindex, ret));
        return ret;
    }

    public double sliderval(int fieldindex) {
        Scrollbar s = sliders[fieldindex];
        int val = s.getValue();
        double ret = (limits[fieldindex][MIN]
                      + val / 100.0 * (limits[fieldindex][MAX]
                                       - limits[fieldindex][MIN]));
        fields[fieldindex].setText(roundstr(ret));
        return ret;
    }

    public void adjustmentValueChanged(AdjustmentEvent e) {
        Object target = e.getSource();
        for (int i = 0; i < sliders.length; i++) {
            if (target == sliders[i]) {
                handleValue(i, sliderval(i));
                canvas.repaint();
                break;
            }
        }
    }


    public void actionPerformed(ActionEvent e) {
        resetValues();
    }

    public void itemStateChanged(ItemEvent e) {
        e.getStateChange();
        if (e.getSource().equals(antialiastoggle)) {
            canvas.antialias = antialiastoggle.getState();
        } else if (e.getSource().equals(doublebuftoggle)) {
            canvas.doublebuf = doublebuftoggle.getState();
        }
        canvas.repaint();
    }

    public static void main(String argv[]) {
        Frame f = new Frame("Java 2D");
        final LineTest demo = new LineTest();
        f.add(demo);
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {System.exit(0);}
        });
        f.pack();
        f.setSize(new Dimension(500,400));
        demo.init();
        f.show();
    }
}

class BezierCanvas extends Canvas {
    LineTest applet;
    double scale;
    double rotate;
    double skew;
    double penwidth;
    int stroke;
    boolean antialias;
    boolean doublebuf;
    int     eofill = GeneralPath.WIND_EVEN_ODD;
    int caps;
    int join;

    public BezierCanvas(LineTest app) {
        applet = app;
        setBackground(Color.gray);
    }

    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }

    BufferedImage img;

    public void update(Graphics g) {
        paint(g);
    }

    public void paint(Graphics g) {
        Graphics2D g2;
        int width = getSize().width;
        int height = getSize().height;
        if (doublebuf) {
            boolean newimg = (img == null ||
                              img.getWidth() != width ||
                              img.getHeight() != height);
            if (newimg) {
                img = (BufferedImage) createImage(width, height);
            }
            g2 = img.createGraphics();
        } else {
            img = null;
            g2 = (Graphics2D) g;
        }
        g2.clearRect(0, 0, width, height);

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                             (antialias
                              ? RenderingHints.VALUE_ANTIALIAS_ON
                              : RenderingHints.VALUE_ANTIALIAS_OFF));
        g2.setRenderingHint(RenderingHints.KEY_RENDERING,
                             (antialias
                              ? RenderingHints.VALUE_RENDER_QUALITY
                              : RenderingHints.VALUE_RENDER_SPEED));

        g2.translate(width / 2.0, height / 2.0);
        g2.scale(scale, scale);
        g2.rotate(rotate);
        g2.shear(-skew, 0.0);

        GeneralPath p = new GeneralPath(eofill);
        //x/y zu x/y
        p.moveTo(-100.0f,   0.0f); //(-100|  0)
        p.lineTo(  20.0f,   0.0f);

        p.moveTo(  20.0f,   0.0f); //(  20|  0)
        p.lineTo(  20.0f, -40.0f);

        p.moveTo(  20.0f, -40.0f); //(  20|-40)
        p.lineTo( 100.0f,  20.0f);

        p.moveTo( 100.0f,  20.0f); //( 100| 20)
        p.lineTo(  20.0f,  80.0f);

        p.moveTo(  20.0f,  80.0f); //(  20| 80)
        p.lineTo(  20.0f,  40.0f);

        p.moveTo(  20.0f,  40.0f); //(  20| 40)
 		p.lineTo(-100.0f,  40.0f);

 		p.moveTo(-100.0f,  40.0f); //(-100| 40)
 		p.lineTo(-100.0f,   0.0f);

        p.closePath();
        if (stroke != 0) {
            BasicStroke bs;
            if (caps == BasicStroke.CAP_BUTT) {
                bs = new BasicStroke((float) penwidth, caps, join, 10.0f);
            } else {
                float dash[] = { width / 10.0f };
                bs = new BasicStroke((float) penwidth, caps,
                                     join, 10.0f, dash, 0.0f);
            }
            if (stroke != 1) {
                g2.setStroke(new BasicStroke(antialias ? (float)(1/scale) : 0,
                                             BasicStroke.CAP_ROUND,
                                             BasicStroke.JOIN_ROUND));
                g2.draw(bs.createStrokedShape(p));
            } else {
                g2.setStroke(bs);
                g2.draw(p);
            }
        } else {
            g2.fill(p);
        }
        g2.dispose();
        if (doublebuf) {
            g.drawImage(img, 0, 0, null);
        }


    }
}

Ich danke für jeden Code und Hilfe
 

abollm

Top Contributor
Erst einmal ein bis zwei Verständnisfragen:

Du willst den Pfeil in deinem Programm an einem selbstgemalten Spline entlanglaufen lassen, richtig?

Wenn ja, soll der Pfeil frei platzierbar sein, d.h. z.B. von oben oder von unten den Spline ablaufen können?
 

KillaBee

Mitglied
hi,

ja der pfeil soll an einem selbst gemalten spline langlaufen.

der pfeil soll am startpunkt des splines durch knopfdruck im uhrzeigersinn laufen
 

abollm

Top Contributor
Folgenden Code habe ich aufgegablet, vielleicht hilft er dir ja:

Code:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.event.*;
 
public class PPlot
{
    PPlotPanel plotPanel;
 
    public PPlot()
    {
        plotPanel = new PPlotPanel();
        PointMover mover = new PointMover(plotPanel);
        plotPanel.addMouseListener(mover);
        plotPanel.addMouseMotionListener(mover);
        JFrame f = new JFrame();
        f.setTitle("Kurve nachfahren");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(getSpinnerPanel(), "North");
        f.getContentPane().add(plotPanel);
        f.setSize(600,600);
        //f.setLocation(200,200);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
 
    private JPanel getSpinnerPanel()
    {
        final SpinnerNumberModel model = new SpinnerNumberModel(0.5, 0, 1.0, 0.01);
        JSpinner spinner = new JSpinner(model);
        JSpinner.NumberEditor editor = (JSpinner.NumberEditor)spinner.getEditor();
        Dimension d = editor.getPreferredSize();
        d.width = 50;
        editor.setPreferredSize(d);
        editor.getTextField().setHorizontalAlignment(JTextField.CENTER);
        spinner.addChangeListener(new ChangeListener()
        {
            public void stateChanged(ChangeEvent e)
            {
                double value = model.getNumber().doubleValue();
                plotPanel.setT1(value);
            }
        });
        JPanel panel = new JPanel();
        panel.add(new JLabel("t value for point 1"));
        panel.add(spinner);
        return panel;
    }
 
    public static void main(String[] args)
    {
        new PPlot();
    }
}
 
class PPlotPanel extends JPanel
{
    Point2D.Double a0, a1, a2;       // constants for parametric equation
    Point2D p0, p1, p2;              // start, mid and end points on path
    double t1;                       // t value for p1 along path
    GeneralPath path;
    final int PAD = 20;
 
    public PPlotPanel()
    {
        t1 = 0.5;
    }
 
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        int w = getWidth();
        int h = getHeight();
        if(path == null)
            initVariables(w,h);
        // axes - ordinate
        g2.draw(new Line2D.Double(PAD, PAD, PAD, h - PAD));
        // abcissa
        g2.draw(new Line2D.Double(PAD, h - PAD, w - PAD, h - PAD));
 
        g2.draw(path);
        g2.setPaint(Color.red);
        g2.fill(new Ellipse2D.Double(p0.getX() - 2, p0.getY() - 2, 4, 4));
        g2.fill(new Ellipse2D.Double(p1.getX() - 2, p1.getY() - 2, 4, 4));
        g2.fill(new Ellipse2D.Double(p2.getX() - 2, p2.getY() - 2, 4, 4));
    }
 
    private void initVariables(int w, int h)
    {
        a0 = new Point2D.Double();
        a1 = new Point2D.Double();
        a2 = new Point2D.Double();
        p0 = new Point2D.Double(PAD, h - PAD);
        p1 = new Point2D.Double(w/3, h/3);
        //p1 = new Point2D.Double(0.2, 0.2);
        p2 = new Point2D.Double(w - PAD, h/8);
        path = new GeneralPath();
        calculatePath();
    }
 
    private void calculateConstants()
    {
        double divisor = t1*(t1 - 1.0);
        a0.x = p0.getX();
        a2.x = ( (p1.getX() - p0.getX()) - t1*(p2.getX() - p0.getX()) ) / divisor;
        a1.x = p2.getX() - p0.getX() - a2.getX();
        a0.y = p0.getY();
        a2.y = ( (p1.getY() - p0.getY()) - t1*(p2.getY() - p0.getY()) ) / divisor;
        a1.y = p2.getY() - p0.getY() - a2.getY();
    }
 
    /**
     * Parameter-Gleichung (t)
     *    P = a2*t^2 + a1*t + a0
     */
    private Point2D getParametricValue(double t)
    {
        Point2D.Double p = new Point2D.Double();
        p.x = a2.getX()*t*t + a1.getX()*t + a0.getX();
        p.y = a2.getY()*t*t + a1.getY()*t + a0.getY();
        return p;
    }
 
    private void calculatePath()
    {
        calculateConstants();
        path.reset();
        path.moveTo((float)p0.getX(), (float)p0.getY());
        int w = getWidth();
        double t;
        Point2D p;
        for(int j = 1; j <= w; j++)
        {
            t = j/(double)w;
            p = getParametricValue(t);
            path.lineTo((float)p.getX(), (float)p.getY());
        }
    }
 
    public void setT1(double t)
    {
        Point2D p = getParametricValue(t);
        p1.setLocation(p.getX(), p.getY());
        t1 = t;
        repaint();
    }
 
    public void movePoint(Point2D p, double x, double y)
    {
        p.setLocation(x, y);
        calculatePath();
        repaint();
    }
 
    public Point2D[] getPoints()
    {
        return new Point2D[] { p0, p1, p2 };
    }
}
 
/**
 * To select and drag the three Points on curve.
 */
class PointMover extends MouseInputAdapter
{
    PPlotPanel plotPanel;
    Point2D selectedPoint;
    Point2D.Double offset;
    boolean dragging;
    final int RADIUS = 4;
 
    public PointMover(PPlotPanel pp)
    {
        plotPanel = pp;
        offset = new Point2D.Double();
        dragging = false;
    }
 
    public void mousePressed(MouseEvent e)
    {
        Point p = e.getPoint();
        Point2D[] points = plotPanel.getPoints();
        for(int j = 0; j < points.length; j++)
            if(points[j].distance(p) < RADIUS)
            {
                selectedPoint = points[j];
                offset.x = p.x - points[j].getX();
                offset.y = p.y - points[j].getY();
                dragging = true;
                break;
            }
    }
 
    public void mouseReleased(MouseEvent e)
    {
        dragging = false;
    }
 
    public void mouseDragged(MouseEvent e)
    {
        if(dragging)
        {
            double x = e.getX() - offset.x;
            double y = e.getY() - offset.y;
            plotPanel.movePoint(selectedPoint, x, y);
        }
    }
}
 

KillaBee

Mitglied
den selben code habe ich auch schon gefunden,
danke für deine suche

nur habe ich den code noch nicht ganz aufsplitten und verstehen können...
bzw ich konnte nicht rausfiltern wo genau der punkt die linie bei drücken des knopfes langläuft.
 

abollm

Top Contributor
KillaBee hat gesagt.:
nur habe ich den code noch nicht ganz aufsplitten und verstehen können...
bzw ich konnte nicht rausfiltern wo genau der punkt die linie bei drücken des knopfes langläuft.

Gut, soweit ich den Code verstanden habe, wird die Spline-Kurve (oder Bezier-Kurve, habe ich nicht geprüft) aus den drei roten Punkten gebildet. Startwert des beweglichen Punktes ist der Parameterwert 0.5.

Eine Veränderung des Parameterwerts für diesen Punkt muss folglich eine Veränderung des Splines in seiner Form bewirken.

Wichtig erscheint mir für dich, dass du die für die Punktbewegung/-berechnung relevanten Methoden analysierst und auf dein Problem überträgst -> calculatePath() und movePoint(Point2D p, double x, double y)

Mehr kann ich auf die Schnelle auch nicht dazu sagen.
 

KillaBee

Mitglied
ok danke,
dann werd ich mir die 2 methoden genauer anschauen und versuhen sie auf meinen pfeil abzustimmen
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
I JavaFX TreeView Pfeil nicht mehr Klickbar machen AWT, Swing, JavaFX & SWT 1
I Pfeil zeichnen am Ende einer Linie AWT, Swing, JavaFX & SWT 1
S Swing Pfeil hoch/runter AWT, Swing, JavaFX & SWT 2
E Darstellung komplexer Formen, z.B. gebogener Pfeil AWT, Swing, JavaFX & SWT 2
W Pfeil von JComboBox AWT, Swing, JavaFX & SWT 8
M Swing: ScrollPane Button mit Pfeil ändern wie? AWT, Swing, JavaFX & SWT 2
S Combobox-pfeil AWT, Swing, JavaFX & SWT 3
T [Eclipse] JComboBox -> Dropdown-Pfeil wird nicht angezeig AWT, Swing, JavaFX & SWT 14
S Ich bringe Code mit JavaFX unter Apache NetBeans IDE 12.6 nicht zum laufen. AWT, Swing, JavaFX & SWT 14
N JavaFX applikation auf anderen Systemen zum laufen bringen AWT, Swing, JavaFX & SWT 7
L JavaFX SpaceFX zum Laufen bekommen AWT, Swing, JavaFX & SWT 16
T Swing 2 Thread.sleep parallel laufen lassen AWT, Swing, JavaFX & SWT 4
wolfgang63 JavaFX Animation, Kreise im vorgegebem Takt durchs Fenster laufen lassen AWT, Swing, JavaFX & SWT 3
T GWT Designer: ich bekomms nicht zum laufen AWT, Swing, JavaFX & SWT 2
C Kugel diagonal laufen lassen AWT, Swing, JavaFX & SWT 31
M Kann ein SwingWorker nur einmal laufen? AWT, Swing, JavaFX & SWT 2
D SWT Programm ausserhalb von Eclipse laufen lassen AWT, Swing, JavaFX & SWT 2
H Bekomme den TreeSelectionListener nicht zum Laufen AWT, Swing, JavaFX & SWT 5
F swing beispiele laufen nicht. AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen

Neue Themen


Oben