Impostazione e recupero di valori da un grafico x-y

0

Ho un mucchio di grafici x-y dati a me e devo essere in grado di trasformarli in una sorta di struttura dati da cui sarò in grado di ottenere Y con il valore X.
Il problema è che, sebbene io abbia 4, al massimo 5 valori di Y dati a me, e i miei valori X possono variare fino a 9000. Quindi l'informazione che ho è qualcosa del tipo

Point # X       Y
1       1000    100
2       3250    460
3       6000    320
4       6500    300

Inizialmente la mia idea era qualcosa del tipo:

function getY($x){
    $data[1000] = 100;
    $data[3250] = 460;
    $data[6000] = 320;
    $data[6500] = 300;

    if(isset($data[$x])){
        return $data[$x];
    }

    $minKnown = null;
    $maxKnown = null;

    foreach($data as $_x => $y){
        if($_x < $x){
            $minKnown = $_x;
        }

        if($_x > $x){
            $maxKnown = $_x;
            break;
        }
    }

    return $data[$minKnown] + (($x - $minKnown) / ($maxKnown - $minKnown)) * ($data[$maxKnown] - $data[$minKnown]);

}     }

Questa funzione ho appena scritto per illustrare la mia idea. Fondamentalmente se un punto non è definito ma da qualche parte tra 2 punti noti, supponendo che non ci siano curve tra i due punti ottieni il valore che co-risponde alla posizione di X tra i due valori noti di X. Non sono nemmeno sicuro se la mia spiegazione verbale è in realtà corretta o no, ma immagino sia per quello che ho scritto per la funzione.

Ad ogni modo, stavo pensando, dal momento che i grafici sono ampiamente utilizzati, ci sono modi migliori per farlo e spero che altrimenti potrei rivelarmi più intelligente di quanto pensassi, il che è spaventoso.

    
posta php_nub_qq 08.01.2015 - 22:28
fonte

1 risposta

2

Dato che hai detto che presumi che non ci siano curve, il grafico stesso probabilmente assomiglierebbe allo sviluppo di un magazzino. Quindi proverei un approccio di calcolo vettoriale. Con i dati che hai dato nel tuo esempio otterresti 3 vettori definiti da due punti. (Per generalizzare, otterresti un vettore in meno di quanto hai ottenuto.)

Nel tuo esempio:

Vector1: Punto1- > Punto2 (Punto2 [x] - Punto1 [x], Punto2 [y] - Punto1 [y])
Vector2: Punto2- > Punto3 (Punto3 [x] - Punto2 [x], Punto3 [y] - Punto2 [y])
Vector3: Punto3- > Punto4 (Punto4 [x] - Punto3 [x], Punto4 [y] - Punto3 [y])

Con valori:

Vector1: (3250 - 1000, 460 - 100) = (2250, 360)
Vector2: (6000 - 3250, 320 - 460) = (2750, -140)
Vector3: (6500 - 6000, 300 - 320) = (500, -20)

Ora la funzione lineare standard ha la forma y = m * x + b. Il vettore stesso non ha bisogno del b. Quindi per Vector1 è: 360 = m * 2250
Risolti per m otteniamo: m = 360/2250 = 0,16 Ora torniamo alla linea originale tra P1 e P2, che richiederà un valore per b.
Otteniamo questo ora con: 100 = 0,16 * 1000 + b = > b = -60 Con ciò sappiamo che ogni valore y tra Point1 e Point2 sarà definito da questa equazione: y = 0.16 * x - 60.
Puoi verificarlo inserendo semplicemente i valori di uno dei punti nell'equazione: P1 100 = 1000 * 0,16 - 60
P2 460 = 3250 * 0,16 - 60

Esempio di codice:

$vector1x = $Point2->X - $Point1->X;
$vector1y = $Point2->Y - $Point1->Y;

$m1 = $vector1y / $vector1x
$b1 = $Point1->y - $Point1->x * $m1
// do the same for the other points as described.

Ora quando ottieni un valore per x che vuoi ottenere il valore y di do sth come questo:

function getY($x)
{
    if($x >= $Point1->X && $x <= $Point2->X)
    {
        $y = $m1 * $x + $b1;
    }
    else if($x <= $Point3->X)
    {
        $y = $m2 * $x + $b2;
    }
    else if($x <= $Point4->X)
    {
        $y = $m3 * $x + $b3;
    }
    else
    {
        throw new Exception("Cannot calculate value with given data!");
    }
    return $y; 
}

Spero che questo approccio soddisfi le tue esigenze e ti aiuti a risolvere il problema.

    
risposta data 28.03.2015 - 01:35
fonte

Leggi altre domande sui tag