krzywe beziera

0

Witam,
mam problem z programem z grafiki. Muszę napisać program, który rysuje krzywe beziera, po kliknięciu 4 punktów. Problem w tym, że program który mam pozwala na narysowanie tylko jednej krzywej a powinien kilka, i każdą powinno być można edytować i na koniec zatwierdzić kształt krzywej. Z góry dzięki na pomoc, o to kod:

import java.awt.*; 
import java.awt.event.*; 

public class Bezier extends Frame { 
   Point[] punkty; 
   int numpoints; 
   double t; 
   double k=.025;    
   int moveflag = 5;       
    MenuBar pasek; 
    Menu plik; 
   MenuItem newB, zamknij; 
    
public   Bezier() { 
      super("Krzywa Beziera"); 
      pasek=new MenuBar(); 
      plik=new Menu("Plik"); 
      newB=new MenuItem("Nowy"); 
      zamknij=new MenuItem("Zamknij"); 
      plik.add(newB); 
      plik.add(zamknij); 
      pasek.add(plik); 
      setMenuBar(pasek); 
   } 
       
   public void init() { 
   resize(600,600); 
   setLayout(new FlowLayout()); 
   punkty = new Point[4]; 
   numpoints = 0; 
   } 

   public void paint(Graphics g) { 
   setBackground(Color.lightGray); 
   g.clearRect(0,0,size().width,size().height); 
   for(int i=0;i<numpoints;i++) { 
   g.setColor(Color.red); 
   g.fillOval(punkty[i].x-2, punkty[i].y-2,4,4); 
   g.setColor(Color.red); 
         } 
       Licz(g); 
   } 
    
   public void Licz(Graphics g) { 
   if(numpoints == 4) { 
   double x1,x2,y1,y2; 
   x1 = punkty[0].x; 
   y1 = punkty[0].y; 
   for(t=k;t<=1+k;t+=k){ 
x2=(punkty[0].x+t*(-punkty[0].x*3+t*(3*punkty[0].x-punkty[0].x*t)))+t*(3*punkty[1].x+t*(-6*punkty[1].x+ 
punkty[1].x*3*t))+t*t*(punkty[2].x*3-punkty[2].x*3*t)+punkty[3].x*t*t*t; 
y2=(punkty[0].y+t*(-punkty[0].y*3+t*(3*punkty[0].y-punkty[0].y*t)))+t*(3*punkty[1].y+t*(-6*punkty[1].y+ 
punkty[1].y*3*t))+t*t*(punkty[2].y*3-punkty[2].y*3*t)+punkty[3].y*t*t*t; 
   g.setColor(Color.gray); 
   g.drawLine((int)x1,(int)y1,(int)x2,(int)y2); 
   x1 = x2; 
   y1 = y2; 
   } 
   } 

} 

public boolean action(Event e, Object o) { 
   if (e.target == newB) { 
   numpoints = 0; 
   repaint(); 
   return true; 
   } 
   else if(e.target == zamknij) { 
      System.exit(0); 
   } 
   return false; 

} 
public boolean mouseDown(Event evt, int x, int y) { 
   Point point = new Point(x,y); 

   if(numpoints < 4) { 
   punkty[numpoints] = point; 
   numpoints++; 
   repaint(); 
   } 
   else 
   for(int i=0;i<numpoints;i++) 
   for(int j=-2;j<3;j++) 
   for(int l=-2;l<3;l++) 
   if(point.equals(new Point(punkty[i].x+j,punkty[i].y+l))) 
   moveflag = i; 
   return true; 
   } 
   public boolean mouseDrag(Event evt, int x, int y) { 
   if(moveflag < numpoints) { 
   punkty[moveflag].move(x,y); 
   repaint(); 
   } 
   return true; 
   } 
   public boolean mouseUp(Event evt, int x, int y) { 
   moveflag = 5; 
   return true; 
   }    
public static void main(String args[]) { 
   Bezier B=new Bezier(); B.init(); B.show(); 
   } 
}
0
  1. Dlaczego się umartwiasz i liczysz krzywe Beziera? W standardowej bibliotece Javy są metody do rysowania tych krzywych na podstawie punktów kontrolnych. Prosty przykład:
import java.awt.*;
import java.awt.geom.GeneralPath;
import javax.swing.*;

public class Bezier extends JApplet
{
    private Point[] controlPoints = new Point[4];
    //------------------------
    public void init()
    {
        controlPoints[0] = new Point(20,260);
        controlPoints[1] = new Point(50,10);
        controlPoints[2] = new Point(250,50);
        controlPoints[3] = new Point(450,290);
        add(new Panelik());
    }
    //------------------------
    class Panelik extends JPanel
    {
        public Panelik()
        {
            setPreferredSize(new Dimension(400,400));
            setBackground(Color.WHITE); 
        }
        //--------------------
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g); 
            Graphics2D g2d = (Graphics2D)g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(Color.BLACK);
            for (int i=0;i<controlPoints.length;i++)
            {
                g.fillOval(controlPoints[i].x-2, controlPoints[i].y-2,4,4); 
            }
            GeneralPath path = new GeneralPath();
            g2d.setColor(Color.RED);
            path.moveTo(controlPoints[0].x,controlPoints[0].y);
            path.curveTo(controlPoints[1].x,controlPoints[1].y,controlPoints[2].x,
                                controlPoints[2].y,controlPoints[3].x,controlPoints[3].y);
            g2d.draw(path); 
        }
    }
}
  1. Nie rozumiem Twoich wątpliwości.
   public void paint(Graphics g) { 
   setBackground(Color.lightGray); 
   g.clearRect(0,0,size().width,size().height); //tu "sprzątasz", tzn. wymazujesz wszystko, a dalej rysujesz __tylko__ jedną krzywą.
   for(int i=0;i<numpoints;i++) { 
   g.setColor(Color.red); 
   g.fillOval(punkty[i].x-2, punkty[i].y-2,4,4); 
   g.setColor(Color.red); 
         } 
       Licz(g); 
   }

Musisz utworzyć kolekcję krzywych Beziera i rysować je w pętli.

0

1.niestety nie mogę skorzystać z gotowych metod.
2.jak to zrobić żebym mógł stworzyć tą kolekcję krzywych, gdzie dodać pętlę ?

0

Używasz metod, które są przestarzałe od Javy 1.1 (to już chyba 18 lat). Z czego Ty się uczysz?
Nie zajmowałem się edycją (ciągnięciem punktów kontrolnych).

import java.awt.*; 
import java.awt.event.*; 
import java.util.*;
 
public class Bezier extends Frame 
{ 
    Point[] punkty = new Point[4];; 
    int numpoints = 0; 
    double t; 
    double k=.025;    
    int moveflag = 5;       
    MenuBar pasek; 
    Menu plik; 
    MenuItem newB, zamknij;
    ArrayList<Point[]> krzywe = new ArrayList<Point[]>();   
 
    public   Bezier() 
    { 
        super("Krzywa Beziera"); 
        pasek=new MenuBar(); 
        plik=new Menu("Plik"); 
        newB=new MenuItem("Nowy"); 
        zamknij=new MenuItem("Zamknij"); 
        plik.add(newB); 
        plik.add(zamknij); 
        pasek.add(plik); 
        setMenuBar(pasek); 
    } 
 
    public void init() 
    { 
        resize(600,600); 
        setLayout(new FlowLayout()); 
    } 
 
    public void paint(Graphics g) 
    { 
        setBackground(Color.lightGray); 
        g.clearRect(0,0,size().width,size().height); 
        //System.out.println(krzywe.size());
        for(int k=0;k<krzywe.size();k++)
        {
            Point[] points = krzywe.get(k);
            for(int i=0;i<4;i++) 
            { 
                g.setColor(Color.red); 
                g.fillOval(points[i].x-2, points[i].y-2,4,4); 
                g.setColor(Color.red); 
            } 
            licz(g,points); 
        }
        for(int i=0;i<numpoints;i++) 
        { 
            g.setColor(Color.red); 
            g.fillOval(punkty[i].x-2, punkty[i].y-2,4,4); 
            g.setColor(Color.red); 
        }        
    } 
 
    public void licz(Graphics g,Point[] punkty) 
    { 
        double x1,x2,y1,y2; 
        x1 = punkty[0].x; 
        y1 = punkty[0].y; 
        for(t=k;t<=1+k;t+=k)
        { 
            x2=(punkty[0].x+t*(-punkty[0].x*3+t*(3*punkty[0].x-punkty[0].x*t)))+t*(3*punkty[1].x+t*(-6*punkty[1].x+ 
            punkty[1].x*3*t))+t*t*(punkty[2].x*3-punkty[2].x*3*t)+punkty[3].x*t*t*t; 
            y2=(punkty[0].y+t*(-punkty[0].y*3+t*(3*punkty[0].y-punkty[0].y*t)))+t*(3*punkty[1].y+t*(-6*punkty[1].y+ 
            punkty[1].y*3*t))+t*t*(punkty[2].y*3-punkty[2].y*3*t)+punkty[3].y*t*t*t; 
            g.setColor(Color.gray); 
            g.drawLine((int)x1,(int)y1,(int)x2,(int)y2); 
            x1 = x2; 
            y1 = y2; 
        }  
    } 
 
    public boolean action(Event e, Object o) 
    { 
        if (e.target == newB) 
        { 
            numpoints = 0; 
            repaint(); 
            return true; 
        } 
        else if(e.target == zamknij) 
        { 
            System.exit(0); 
        } 
        return false;  
    } 
    public boolean mouseDown(Event evt, int x, int y) 
    { 
        Point point = new Point(x,y); 
 
        if(numpoints < 4) 
        { 
            punkty[numpoints] = point; 
            numpoints++; 
            repaint(); 
        } 
        if(numpoints == 4)
        {  
            krzywe.add(punkty);       
            for(int i=0;i<numpoints;i++) 
                for(int j=-2;j<3;j++) 
                    for(int l=-2;l<3;l++) 
                        if(point.equals(new Point(punkty[i].x+j,punkty[i].y+l))) 
                            moveflag = i;
            punkty = new Point[4];
            numpoints = 0;
            repaint();
        }   
        return true; 
    } 
    public boolean mouseDrag(Event evt, int x, int y) 
    { 
        if(moveflag < numpoints) 
        { 
            punkty[moveflag].move(x,y); 
            repaint(); 
        } 
        return true; 
    } 
    public boolean mouseUp(Event evt, int x, int y) 
    { 
        moveflag = 5; 
        return true; 
    }    
    public static void main(String args[]) 
    { 
        Bezier B=new Bezier(); 
        B.init(); 
        B.show(); 
    } 
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1