logo

Programy on-line

autor Piotr Kotarski

Programy on-line

Znajdują się tu różnego rodzaju aplkacje wykonane w canvas + JavaScript z wykorzystaniem biblioteki jQuery.

Poniżej opisałem kilka algorytmów wykorzystywanych w tych programach.

linia

Pomysły:

  1. Rysowanie grotu strzałki
  2. Odbicia kulek

linia

  1. Rysowanie strzałki (wektora)

    Grot strzałki (np. wektora) ma postać trójkąta (rysunek).

    Twoja przeglądarka nie obsługuje elementu canvas.

    Dane:

    Stałe:
    	ds - długość grotu strzałki, np. ds=15
    	ss - szerokość grotu strzałki, np. ss=4
    Parametry wywołania:
    	x0,y0 - współrzędne początku wektora
    	d     - długość wektora
    	fi    - kąt względem osi OX
    

    Założenia:

    • Obliczenia we współrzędnych ekranowych (tzn. punkt (0,0) umieszczony jest w lewym górnym rogu),

    • Kąty podane w stopniach

    Obliczenia:

    Obliczam współrzędne punktów (x1,y1), (x2,y2) i (x3,y3):

    var sfi=Math.sin(fi*Math.PI/180);
    var cfi=Math.cos(fi*Math.PI/180);
    
    x1 = x0+d*cfi;		//współrzędne końca wektora
    y1 = y0-d*sfi;
    x2 = x1-ds*cfi-ss*sfi;	//współrzędne punktów wyznaczających strzałkę
    y2 = y1+ds*sfi-ss*cfi;
    x3 = x1-ds*cfi+ss*sfi;
    y3 = y1+ds*sfi+ss*cfi;
    

    Teraz wystarczy narysować wypełniony trójkąt o wierzchołkach (x1,y1), (x2,y2) i (x3,y3)!

    Gotowe funkcje:

    var ds=15;
    var ss=2;
    var grot=function(x1,y1,fi)
    {	var sfi = Math.sin(fi*Math.PI/180);
    	var cfi = Math.cos(fi*Math.PI/180);
    	ctx.beginPath();
    	ctx.moveTo(x1,y1);
    	ctx.lineTo(x1-ds*cfi-ss*sfi,y1+ds*sfi-ss*cfi);
    	ctx.lineTo(x1-ds*cfi+ss*sfi,y1+ds*sfi+ss*cfi);
    	ctx.lineTo(x1,y1);
    	ctx.fill();
    }
    var wektor=function(x0,y0,d,fi)
    {	x1 = x0+d*Math.cos(Math.PI/180*fi);
    	y1 = y0-d*Math.sin(Math.PI/180*fi);
    	ctx.beginPath();
    	ctx.moveTo(x0,y0);
    	ctx.lineTo(x1,y1);
    	ctx.closePath();
    	ctx.stroke();
    	grot(x1,y1,fi);
    }
    

    linia

  2. Odbicia kulek

    Problem polega na obliczeniu kierunków i prędkości dwóch kulek po ich zderzeniu (jak w bilardzie).

    Założenia:

    • Masy kulek są jednakowe

    • Rozmiary (promienie) kulek są jednakowe

    • Pomijamy efekty tarcia

    • Pomijamy wirowanie kulek

    Na rysunku przedstawiono sytuację w momencie zderzenia.

    Twoja przeglądarka nie obsługuje elementu canvas.

    Dane:

    (x1,y1)        - położenie środka pierwszej kuli w momencie zderzenia
    (x2,y2)        - położenie środka drugiej kuli w momencie zderzenia
    V1 = [V1x,V1y] - wektor prędkości pierwszej kuli
    V2 = [V2x,V2y] - wektor prędkości drugiej kuli
    

    Wynik:

    V1_ = [V1x_,V1y_] - wektor prędkości pierwszej kuli po zderzeniu
    V2_ = [V2x_,V2y_] - wektor prędkości drugiej kuli po zderzeniu
    

    Obliczenia:

    W pierwszej kolejności przeliczamy wektory prędkości z układu współrzędnych (xy) na układ (tn) (rysunek), gdzie t oznacza kierunek styczny, a n kierunek normalny w punkcie zderzenia.

    W tym celu najpierw wyznaczam wektory jednostkowe t i n:
    // odległość między środkami kul:
    var d = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
    
    // wektory jednostkowe t i n:
    var nx = (x2-x1)/d;
    var ny = (y2-y1)/d;
    var tx = -ny;
    var ty = nx;
    

    Składowe wektorów V1 i V2 w nowym układzie współrzędnych obliczamy jako iloczyn skalarny wektorów predkości V1 i V2 i wektorów jednostkowych n i t:

    var v1n = v1x*nx+v1y*ny;
    var v1t = v1x*tx+v1y*ty;
    
    var v2n = v2x*nx+v2y*ny;
    var v2t = v2x*tx+v2y*ty;
    

    Składowe styczne nie ulegają zmianie, a więc:

    var v1t_ = v1t;
    var v2t_ = v2t;
    

    Składowe normalne zmieniają się tak, jak przy zderzeniu centralnym, a więc (przy przyjętych założeniach):

    var v1n_ = v2n;
    var v2n_ = v1n;
    

    Uwaga: powyższy wzór dotyczy tylko przypadku zderzenia identycznych kul. W przypadku różnych kul wzory są bardziej złożone!!!

    Na końcu przeliczamy z powrotem składowe prędkości z układu współrzędnych (tn) na układ (xy).

    v1x_ = (v1n_*(x2-x1)-v1t_*(y2-y1))/d;
    v1y_ = (v1n_*(y2-y1)+v1t_*(x2-x1))/d;
    
    v2x_ = (v2n_*(x2-x1)-v2t_*(y2-y1))/d;
    v2y_ = (v2n_*(y2-y1)+v2t_*(x2-x1))/d;
    

    I już!!!

    W praktyce powyższe wzory upraszczam, pomijając tworzenie niektórych zmiennych pomocniczych...

  3. linia

© Piotr Kotarski