Cześć, mam do napisania program rysujący wykres podanej funkcji oraz wykres interpolacji. Problem jest z tym że mam dużo punktów i gdy dochodzi do rysowania wykresu interpolacji wykres bardzo szybko "ucieka", ma to miejsce głównie dla funkcji trygonometryczny dla funkcji typu: x^2 działa dobrze, bardzo byłbym wdzięczny gdyby ktoś mógł zerknąć na kod i podpowiedzieć co może być źle :)
Problem wygląda mniej więcej tak (zielonym interpolacja, czerwonym podana funkcja):
do obliczania punktów korzystam z parsera JEP http://www.singularsys.com/jep/doc/html/functions.html
główny kod odpowiedzialny za rysowanie i obliczenia
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import org.jfree.data.xy.XYSeries;
import org.apache.commons.math3.analysis.polynomials.PolynomialFunctionLagrangeForm;
/**
*
* @author user
*/
public class Funrys {
protected double OX, OY;//, f1, f2, d, dt;
private BufferedImage Img;
private TPaintPanel Panel;
protected String wzor;
protected List punkty;
protected List<Double> pointsX;
protected List<Double> pointsY;
protected boolean czyInter;
protected PolynomialFunctionLagrangeForm lagrange;
public Funrys(TPaintPanel pp)
{
Panel = pp;
}
public void doSth() {
Img = new BufferedImage(700, 480, BufferedImage.TYPE_INT_RGB);
Graphics ig = Img.getGraphics();
//setParams(1, 1, 9,8, Math.PI/2 , .01);
paint((Graphics2D) ig);
Panel.setSize(700, 480);
Panel.AssignRys(Img);
Panel.repaint();
//setParams(5, 4, 3, 5, Math.PI/2, .01);
}
public void setParams(double ox, double oy, String wzur, boolean inter) {
OX = ox;
OY = oy;
wzor = wzur;
czyInter = inter;
}
//rysowanie wykresu funkcji
private void paint(Graphics2D g) {
int w = 700, h = 480, hw = w/2, hh = h/2;
//g.setFont(new Font("dialog", Font.PLAIN, 9));
//FontMetrics fm = g.getFontMetrics();
g.setColor(new Color(23, 128, 0));
g.drawLine(0, hh, w, hh); //x os
g.drawLine(hw, 0, hw, h); //y os
g.drawString("x", w-10, hh-5);
g.drawString("y", hw-7, 10);
//double sfact = min((hw-fm.stringWidth(Double.toString(-b))-6)/a, (hh-fm.getAscent()-6)/b);
double asfuck = min((hw-20)/OX, (hh-20)/OY);
int xmax = (int)(asfuck*OX), ymax = (int)(asfuck*OY);
g.drawLine(hw-xmax, hh-ymax, hw+xmax, hh-ymax); //ramka
g.drawLine(hw-xmax, hh+ymax, hw+xmax, hh+ymax); // jw
g.drawLine(hw-xmax, hh-ymax, hw-xmax, hh+ymax); //jw
g.drawLine(hw+xmax, hh-ymax, hw+xmax, hh+ymax); // jw
//g.drawString(Double.toString(a), hw+xmax-fm.stringWidth(Double.toString(a))/2, hh+ymax+fm.getAscent()+3);
//g.drawString(Double.toString(-a), hw-xmax-fm.stringWidth(Double.toString(-a))/2, hh+ymax+fm.getAscent()+3);
//g.drawString(Double.toString(b), hw-xmax-fm.stringWidth(Double.toString(b))-3, hh-ymax+fm.getAscent()/2-1);
//g.drawString(Double.toString(-b), hw-xmax-fm.stringWidth(Double.toString(-b))-3, hh+ymax+fm.getAscent()/2-1);
g.drawString(Double.toString(OX), hw+xmax+2, hh); //x
g.drawString(Double.toString(-OX), hw-xmax-24, hh); // -x
g.drawString(Double.toString(-OY), hw+10, hh+ymax+17); // -y
g.drawString(Double.toString(OY), hw+10, hh-ymax-7); // y
g.setColor(new Color(240, 9, 9));
for(int i=1; i<=pointsX.size()-1; i++){
double pX, pY, pX2, pY2;
pX = pointsX.get(i-1)*asfuck;
pY = pointsY.get(i-1)*asfuck;
pX2=pointsX.get(i)*asfuck;
pY2=pointsY.get(i)*asfuck;
Shape l = new Line2D.Double(hw+pX, hh-pY, hw+pX2, hh-pY2);
g.draw(l);
}
/*********************rysowanie interpolacji*************************************/
g.setColor(new Color(0, 255, 0));
if(czyInter){
double inX[] = new double[pointsX.size()];
double inY[] = new double[pointsX.size()];
for(int i=0; i<=pointsX.size()-1; i++){
inX[i]=pointsX.get(i);
inY[i]=pointsY.get(i);
}
double interY[] = new double[pointsX.size()];
//obliczanie wartosc dla podanych X
for(int k=0; k<=(OX*2)/0.01; k++){
interY[k] = interpolacjaStopien(inX[k], 4, inX, inY);
System.out.println(inX[k]+"\t"+k+"\t"+interY[k]);
}
for(int i=1; i<=inX.length-1; i++){
double pX, pY, pX2, pY2;
pX = inX[i-1]*asfuck;
pY = interY[i-1]*asfuck;
pX2 = inX[i]*asfuck;
pY2 = interY[i]*asfuck;
Shape l = new Line2D.Double(hw+pX, hh-pY, hw+pX2, hh-pY2);
g.draw(l);
}
}
}
private static double min(double a, double b) { return (a < b) ? a : b; }
public void getPoints(String wzor){
org.nfunk.jep.JEP myParser = new org.nfunk.jep.JEP();
myParser.addStandardFunctions();
myParser.addStandardConstants();
pointsX = new ArrayList<>();
pointsY = new ArrayList<>();
pointsX.clear();
pointsY.clear();
for(double x =(-OX); x<=OX; x+=0.01){
myParser.addVariable("x", x);
myParser.parseExpression(wzor);
double result = myParser.getValue();
pointsX.add(x);
pointsY.add(result);
}
}
//metoda do interpolacji
public double interpolacjaStopien (double x, int STOPIEN, double tab_x[], double tab_f[]) {
double wynik = 0.0, L;
for (int i=0; i<STOPIEN; i++) {
L = 1.0;
for (int j=0; j<STOPIEN; j++) {
if (j != i)
L = L * (x - tab_x[j]) / (tab_x[i] - tab_x[j]);
}
wynik = wynik + tab_f[i]*L;
}
return wynik;
}
}
- RvMzfkX.png (21 KB) - ściągnięć: 386
<code=java></code>