JFreeChart. Como capturar as coordenadas (x,y) onde duas séries se cruzam?

Java

19/03/2015

Imagine 3 series, a primeira está representada pela linha RETA no gráfico da figura ela é criada a partir de dados calculados pelo programa, a segunda é a linha CURVA que se origina de pontos inseridos pelo usuário e a terceira é mostrada pela linha PONTILHADA que liga a serie reta à serie curva.

O meu problema está sendo na criação da linha pontilhada (serie3). Supondo que ela comece no ponto mais extremo da linha reta (serie1), ou seja, na “cabeça” da serie1 e que esse ponto seja conhecido e chamado de (x0, y0), imaginando que a serie3 se desloque horizontalmente em direção a linha curva (serie2), será fácil prever o ponto y onde a serie3 interceptará a serie2 porque esse ponto é igual ao ponto y0, mas não será possível prever a coordenada x onde isso ocorre.

[img]http://arquivo.devmedia.com.br/forum/imagem/415303-20150319-152746.jpg[/img]

É aí que surge a minha dúvida! Eu gostaria de saber se existe alguma forma do programa me retornar as coordenada (x, y) onde ocorre o cruzamento entre as duas series.

Ahh! outra possível solução pro meu problema, seria se o programa me retornasse a função da serie curva (serie2).
Bruno

Bruno

Curtidas 0

Respostas

Bruno M.

Bruno M.

19/03/2015

Bem eu não consegui!
Mas usando a matemática, primeiro usei um algorítimo pra fazer interpolação polinomial por spline cubica natural:


public double Spline (int y, double Trt[], double TLt[], double fx) {
    
nt n;
int i;
int k; 
double p; 
double qn;
double sig;
double un;
double x = fx;
double u[] = new double[y - 1 + 10];
double yt[] = new double[y +10];
double xin[] = new double[y +10];
double yin[] = new double[y +10];

    int c = 0;
    while (c <= y){
    c++;
    xin[c] = Trt[c];
    yin[c] = TLt[c];
    //System.out.println("c: "+c);
    }

n = y;
yt[1] = 0;
u[1] = 0;

    for (i = 2; i<=(n - 1); i++){
        sig = (xin[i] - xin[i - 1]) / (xin[i + 1] - xin[i - 1]);
        p = (sig * yt[i - 1]) + 2;
        yt[i] = (sig - 1) / p;
        u[i] = ( (yin[i + 1] - yin[i]) / (xin[i + 1] - xin[i]) ) - ( (yin[i] - yin[i - 1]) / (xin[i] - xin[i - 1]) );
        u[i] = ( (6 * u[i] / (xin[i + 1] - xin[i - 1])) - (sig * u[i - 1]) ) / p;
        //System.out.println("loop2 só roda com 3 pontos. i: "+i);
     }
    
qn = 0;
un = 0;

yt[n] = (un - (qn * u[n - 1])) / ( (qn * yt[n - 1]) + 1);

    for (k = (n - 1); k>=1; k--){
        yt[k] = (yt[k] * yt[k + 1]) + u[k];
    }

    
    
int klo;
int khi;
double h, b, a;

//first find correct interval
klo = 1;
khi = n;

double pos_ou_neg;

  pos_ou_neg = xin[khi] - xin[klo]; 

  
        if (pos_ou_neg >= 0) {
            
            do {
                
            k = khi - klo;
            
                if (xin[k] > x){
                khi = k;
                }
                else{
                klo = k;
                }
            k = khi - klo;
           
            } while (k>1);
            
        } 
        else {
            do {
                k = khi - klo;

                if (xin[k] < x){
                khi = k;
                 //System.out.println("usou-se o se");
                }
                else{
                klo = k;
                //System.out.println("usou-se o senão");
                }
                k = khi - klo;
            } while (k > 1);
            
        }
//       
        
h = xin[khi] - xin[klo];
a = (xin[khi] - x) / h;
b = (x - xin[klo]) / h;
double f = a * yin[klo] + b * yin[khi] + (((a*a*a) - a) * yt[klo] + ((b*b*b) - b) * yt[khi]) * ((h*h) / 6);
//System.out.println("em " +y+" f= " +f);

return f;

}


Depois misturei esse algorítimo a um de calculo da raiz (método da bisseção), só que no lugar de me da a raiz (valor x quando y = 0) eu o modifiquei pra retornar o valor de x para um determinado y dado:


public double SplineBissecao (int y, double Trt[], double TLt[], double yv, int maior, int menor, int prox) { 
 
int n;
int i;
int k; 
double p; 
double qn;
double sig;
double un;
double u[] = new double[y - 1 + 10];
double yt[] = new double[y +10];
double xin[] = new double[y +10];
double yin[] = new double[y +10];

    int c = 0;
    while (c <= y){
    c++;
    xin[c] = Trt[c];
    yin[c] = TLt[c];
    }

n = y;
yt[1] = 0;
u[1] = 0;

    for (i = 2; i<=(n - 1); i++){
        sig = (xin[i] - xin[i - 1]) / (xin[i + 1] - xin[i - 1]);
        p = (sig * yt[i - 1]) + 2;
        yt[i] = (sig - 1) / p;
        u[i] = ( (yin[i + 1] - yin[i]) / (xin[i + 1] - xin[i]) ) - ( (yin[i] - yin[i - 1]) / (xin[i] - xin[i - 1]) );
        u[i] = ( (6 * u[i] / (xin[i + 1] - xin[i - 1])) - (sig * u[i - 1]) ) / p;
     }
    
qn = 0;
un = 0;

yt[n] = (un - (qn * u[n - 1])) / ( (qn * yt[n - 1]) + 1);

    for (k = (n - 1); k>=1; k--){
        yt[k] = (yt[k] * yt[k + 1]) + u[k];
    }

double angular[] = new double[y];

for (int m=1; m < y; m++){
angular[m] = (TLt[y] - TLt[y-m]) / (Trt[y] - Trt[y-m]);
}
boolean igual = false;
for (int m = 1; m<y; m++ ){
    if (angular[y-1] == angular[m]){
        igual = true;   
    }
    else{
        igual = false;
        break;
    }
}

if (igual == true){
    System.out.println("é uma reta!");
}



//----------------------MÉTODO Da Bisseção MODIFICADO--------------------------------//

double x = Trt[maior];
double x2 = Trt[menor];
double x3 = 0;
double fx1 = 0;
double fx2 = 0;
double fx3 = 0;
int contar = 0;

do{
contar++;
//System.out.println("contar= "+contar);
  

//------------------------- f(x1) ----------------------------
int klo;
int khi;
double h, b, a;
klo = 1;
khi = n;
double pos_ou_neg;

  pos_ou_neg = xin[khi] - xin[klo]; 

  
        if (pos_ou_neg >= 0) {
            
            do {
                
            k = khi - klo;
            
                if (xin[k] > x){
                khi = k;
                }
                else{
                klo = k;
                }
            k = khi - klo;
           
            } while (k>1);
            
        } 
        else {
            do {
                k = khi - klo;

                if (xin[k] < x){
                khi = k;
                 //System.out.println("usou-se o se");
                }
                else{
                klo = k;
                //System.out.println("usou-se o senão");
                }
                k = khi - klo;
            } while (k > 1);
            
        }
        
    
h = xin[khi] - xin[klo];
a = (xin[khi] - x) / h;
b = (x - xin[klo]) / h;
fx1 = a * yin[klo] + b * yin[khi] + (((a*a*a) - a) * yt[klo] + ((b*b*b) - b) * yt[khi]) * ((h*h) / 6);
//double fder = ( (yt[khi] / 6) * (((3*(x - xin[klo])* (x - xin[klo])) / (Math.pow((xin[khi] - xin[klo]), 3))) - (1/( xin[khi] - xin[klo] ))) * (xin[khi] - xin[klo]) * (xin[khi] - xin[klo]) + yt[klo] * ((1/( xin[khi] - xin[klo])) - (3*( xin[khi] - x)*( xin[khi] -x)) / (Math.pow((xin[khi] - xin[klo]), 3)))) - (yin[klo]/( xin[khi] - xin[klo]  )) + (yin[khi]/ (xin[khi] - xin[klo]  ));
 

//------------------------- f(x2) ----------------------------

//int klo;
//int khi;
//double h, b, a;
klo = 1;
khi = n;
//double pos_ou_neg;

  pos_ou_neg = xin[khi] - xin[klo]; 

  
        if (pos_ou_neg >= 0) {
            
            do {
                
            k = khi - klo;
            
                if (xin[k] > x2){
                khi = k;
                }
                else{
                klo = k;
                }
            k = khi - klo;
           
            } while (k>1);
            
        } 
        else {
            do {
                k = khi - klo;

                if (xin[k] < x2){
                khi = k;
                 //System.out.println("usou-se o se");
                }
                else{
                klo = k;
                //System.out.println("usou-se o senão");
                }
                k = khi - klo;
            } while (k > 1);
            
        }
h = xin[khi] - xin[klo];
a = (xin[khi] - x2) / h;
b = (x2 - xin[klo]) / h;
fx2 = a * yin[klo] + b * yin[khi] + (((a*a*a) - a) * yt[klo] + ((b*b*b) - b) * yt[khi]) * ((h*h) / 6);


x3 = (x2 + x)/2;

//------------------------- f(x2) ----------------------------

//int klo;
//int khi;
//double h, b, a;
klo = 1;
khi = n;
//double pos_ou_neg;

  pos_ou_neg = xin[khi] - xin[klo]; 

  
        if (pos_ou_neg >= 0) {
            
            do {
                
            k = khi - klo;
            
                if (xin[k] > x3){
                khi = k;
                }
                else{
                klo = k;
                }
            k = khi - klo;
           
            } while (k>1);
            
        } 
        else {
            do {
                k = khi - klo;

                if (xin[k] < x3){
                khi = k;
                 //System.out.println("usou-se o se");
                }
                else{
                klo = k;
                //System.out.println("usou-se o senão");
                }
                k = khi - klo;
            } while (k > 1);
            
        }
h = xin[khi] - xin[klo];
a = (xin[khi] - x3) / h;
b = (x3 - xin[klo]) / h;
fx3 = a * yin[klo] + b * yin[khi] + (((a*a*a) - a) * yt[klo] + ((b*b*b) - b) * yt[khi]) * ((h*h) / 6);



 // if (contar > 1){
    
        if ( (fx2 <= yv && yv <= fx1) || (fx2 >= yv && yv >= fx1) ){
            
            if (fx3 <= yv && fx2 >= yv){
                x = x3;
            }
            if (fx3 <= yv && fx1 >= yv){
                x2 = x3;
            }
            if (fx3 >= yv && fx2 <= yv){
                x = x3;
            }
            if (fx3 >= yv && fx1 <= yv){
                x2 = x3;
            }
            
        
        }else{
            x3 = -200;
            break;
            
        }
   
  //  }

//double intera = ( (Math.log( (Trt[maior] - Trt[menor])/0.00001 ))/ Math.log(2) )  ;
        
 }while ( (Math.abs(x3 - x2) >= 0.00001) ||  (contar <= ( (Math.log( (Trt[maior] - Trt[menor])/0.00001 ))/ Math.log(2) ) ) || contar <=100 ); 

return x3;



}
GOSTEI 0
POSTAR