Rzut ukośny w SVG

0

Witam,
mam do zrealizowania projekt polegający na animacji rzutu ukośnego w SVG.
Ściągnąłem bibliotekę simple_svg http://code.google.com/p/simple-svg/downloads/list
I wszystko ładnie pięknie, zapisuje linie i inne kształty w SVG. Jednak nie wiem jak zrobić żeby zapisywało animację.
Próbowałem wykorzystywać pętle for i owszem program wykonuje tą pętle i rysuje linie, jednak nie jest to animacja tylko w SVG zapisany jest gotowy obraz po zakończeniu pętli. Co zrobić, żeby animacja była pokazywana na żywo?

Pozdrawiam

0

ściągnąć bibliotekę która wspiera animowanie w svg
albo poznać format svg i samemu dorobić animowanie

// edit:
generalnie okazuje się to banalnie proste
tworzysz krzywą po której ma się ruszać element, utworzy się element <path>
teraz wystarczy to wrzucić do elementu który ma się ruszać:

<animateMotion path="TUTAJ PATH" begin="1s" dur="5s" fill="freeze"/>

i tyle

0

W tej bibliotece nie ma takiej komendy jak animateMotion. Jak to zrobić?
Jak na razie w sposób łopatologiczny wygenerowałem krzywą zależną od 45 zmiennych wyznaczanych we wcześniejszych równaniach:
Polygon linia(Stroke(2, Color::Blue));
linia << Point(0,0)<< Point(x1, y1)<< Point(x2, y2) << Point(x3, y3) << Point(x4, y4) << Point(x5, y5)
<< Point(x6, y6) << Point(x7, y7) << Point(x8, y8) << Point(x9, y9)<< Point(x10, y10) << Point(x11, y11)
<< Point(x12, y12) << Point(x13, y13) << Point(x14, y14) << Point(x15, y15) << Point(x16, y16) << Point(x17, y17)
<< Point(x18, y18) << Point(x19, y19) << Point(x20, y20) << Point(x21, y21) << Point(x22, y22 )<< Point(x23, y23) << Point(x24, y24)
<< Point(x25, y25)<< Point(x26, y26) << Point(x27, y27)<< Point(x28, y28)<< Point(x29, y29) << Point(x30, y30)
<< Point(x31, y31) << Point(x32, y32) << Point(x33, y33) << Point(x34, y34)<< Point(x35, y35) << Point(x36, y36)
<< Point(x37, y37) << Point(x38, y38)<< Point(x39, y39)<< Point(x40, y40)<< Point(x41, y41) << Point(x42, y42)
<< Point(x43, y43) << Point(x44, y44) << Point(x45, 0) ;

  doc << linia;

Co należy zrobić aby ta linia rysowała się kolejnymi etapami a nie od razu drukowany był statyczny obrazek.
Byłbym bardzo wdzięczny za pomoc.
Pozdrawiam

0

Jak ma ogólnie wyglądać animacja? Jeśli element ma się obracać wokół prostej to zauważ, że każdy punkt będzie się kręcił po elipsie. Dlatego w tym przypadku trzeba by użyć animateTransform (rotate+scale) dla każdej linii z osobna.

0

Próbowałem na tablicach to zrobić, ale coś nie chciało mi się rysować. Jak byś to zrobił na tablicach żeby to działało ?
Animacja ma wyglądać tak, że zamiast statycznego rysunku paraboli, po odpaleniu pliku *.svg łączenie punktów ma być dynamiczne. Czyli tak jakby ten wykres się rysował na naszych oczach.
Ktoś mi podpowiadał, żeby zastosować opóźnienia za pomocą clocka, ale nie mam pojęcia jak do tego podejść.

0

Przede wszystkim tu masz opis SVG:
http://www.w3.org/TR/SVG/animate.html

Użyj elementu animate. Podobnie jak w przykładzie. W odpowiednim momencie (begin="<czas rozpoczęcia>") zmień przezroczystość (attributeName="opacity") z 0% na 100%.

0

ale w tej bibliotece simple_svg nie ma w ogóle zdefiniowanych takich funkcji, skąd mogę wziąć bibliotekę z takimi funkcjami ?
A tak w ogóle ten poradnik jest do xmla a ja muszę to napisać w devie w c++

0
7alisman napisał(a):

A tak w ogóle ten poradnik jest do xmla a ja muszę to napisać w devie w c++

<facepalm> Ty chyba nie zdajesz sobie sprawy czym jest plik .svg :|

otwórz ten wygenerowany plik .svg w notatniku i samemu spróbuj go przerobić
zajmie ci to dwie minuty

potem dopisz do programu instrukcje które same go przerobią
to też nie powinno zająć dużo czasu

ba - możesz na stałe wklepać szablon gotowego .svg do programu i zmieniać tylko parę danych bez użycia żadnej biblioteki

albo idź szukaj jeszcze przez tydzień biblioteki która ci to "ułatwi"

0

Ah.. faktycznie nie pomyślałem o tym, że można edytować bezpośrednio plik svg... Więc taką animację trzeba zrealizować za pomocą animateMotion path.
Tylko mając parabolę złożoną z takich punktów:

<polygon points="0,768 1024,768 1024,0 0,0 " fill="transparent" stroke-width="1" stroke="rgb(255,0,0)" /> <polygon points="0,768 19.8666,736.536 39.7332,706.502 59.5998,677.898 79.4664,650.724 99.333,624.98 119.2,600.667 139.066,577.784 158.933,556.331 178.799,536.308 198.666,517.716 218.533,500.553 238.399,484.821 258.266,470.519 278.132,457.647 297.999,446.206 317.865,436.194 337.732,427.613 357.599,420.462 377.465,414.742 397.332,410.451 417.198,407.591 437.065,406.16 456.932,406.16 476.798,407.591 496.665,410.451 516.531,414.742 536.398,420.462 556.265,427.613 576.131,436.194 595.998,446.206 615.864,457.647 635.731,470.519 655.598,484.821 675.464,500.553 695.331,517.716 715.197,536.308 735.064,556.331 754.931,577.784 774.797,600.667 794.664,624.98 814.53,650.724 834.397,677.898 854.263,706.502 874.13,736.536 893.997,768 " fill="transparent" stroke-width="2" stroke="rgb(0,0,255)" />

Jak zdefiniować z tego path ? Bo rozumiem, że jak zdefiniuje te punkty jako path wrzucam do <animateMotion path="path" begin="1s" dur="5s" fill="freeze"/> i animacja gotowa ?

0

http://www.w3.org/TR/SVG/paths.html#PathData

czyli na początku piszesz M, potem X Y, a potem powtarzasz L X Y, a na końcu ewentualnie "z" jeżeli chcesz zamknąć figurę

znaczy animacja gotowa o ile chcesz czymś ruszać po tej paraboli
na przykład rysujesz kółko, wrzucasz ten "animateMotion" i powinno ono się wtedy ruszać po tej paraboli
jak chcesz żeby się rysowała linia to użyj przeźroczystości i po kolei "pojawiaj" kolejne fragmenty paraboli jak pisał adf88

0

OK udało się ręcznie przerobić, tylko teraz będzie problem z napisaniem instrukcji, żeby wywołując program i wpisując zmienne w konsoli automatycznie to co wpisałem ręcznie zapisywane było w svg.

0

Skoro parabola ma się "pojawiać" stopniowo segmentami to nie animateMotion tylko animate. Każdy segment pakujesz w osobny znacznik animate i ustawiasz odpowiedni czas "pojawienia" się (dla każdego segmentu inny). Możesz zastosować nawet taki fade-in (stopniową zmianę przezroczystości), wtedy animacja będzie bardziej płynna.

Ewentualnie mam jeszcze inny pomysł, ale chyba format SVG nie ma takiej możliwości, nie wiem (nie doszukałem się). Wycinek paraboli to krzywa beziera o odpowiednich parametrach. Możliwe, że da się utworzyć animację na takiej podstawie, że podajemy do animacji listę wcześniej wyliczonych koordynatów krzywej bezier, tak aby krzywa zmieniała swoje parametry w czasie wedle zadanej listy.

0

Ok, rozumiem. A jeszcze mam pytanie odnośnie liczenia współrzędnych paraboli za pomocą tabel i pętli, jak to zrobić, bo żeby pokolei zliczało to nie problem, pętla for i już. Natomiast nie wiem jak to wpisywać do rysowania.

Oto kod programu:

#include <cstdlib>

#include <iostream>

#include <cmath>

 

#include "simple_svg_1.0.0.hpp"

double Vo,kat,z,tc,t,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19,x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,x30;

double x31,x32,x33,x34,x35,x36,x37,x38,x39,x40,x41,x42,x43,x44,x45;

double Y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15,y16,y17,y18,y19,y20,y21, y22,y23,y24,y25,y26,y27,y28,y29,y30,y31,y32,y33,y34,y35,y36,y37,y38,y39,y40,y41,y42,y43,y44,y45;

double g=10;

using namespace svg;

using namespace std;

void wprowadz_parametry(){

 

    cin>>Vo;

    cin>>kat;

     }

void oblicz(){

 

      z= ((Vo*Vo)*sin(2*kat))/g;

      tc=(2*Vo*sin(kat))/g;

      x1=Vo*cos(kat)*(tc/45);

      x2=Vo*cos(kat)*(2*tc/45);

      x3=Vo*cos(kat)*(3*tc/45);

      x4=Vo*cos(kat)*(4*tc/45);

      x5=Vo*cos(kat)*(5*tc/45);

      x6=Vo*cos(kat)*(6*tc/45);

      x7=Vo*cos(kat)*(7*tc/45);

      x8=Vo*cos(kat)*(8*tc/45);

      x9=Vo*cos(kat)*(9*tc/45);

      x10=Vo*cos(kat)*(10*tc/45);

      x11=Vo*cos(kat)*(11*tc/45);

      x12=Vo*cos(kat)*(12*tc/45);

      x13=Vo*cos(kat)*(13*tc/45);

      x14=Vo*cos(kat)*(14*tc/45);

      x15=Vo*cos(kat)*(15*tc/45);

      x16=Vo*cos(kat)*(16*tc/45);

      x17=Vo*cos(kat)*(17*tc/45);

      x18=Vo*cos(kat)*(18*tc/45);

      x19=Vo*cos(kat)*(19*tc/45);

      x20=Vo*cos(kat)*(20*tc/45);

      x21=Vo*cos(kat)*(21*tc/45);

      x22=Vo*cos(kat)*(22*tc/45);

      x23=Vo*cos(kat)*(23*tc/45);

      x24=Vo*cos(kat)*(24*tc/45);

      x25=Vo*cos(kat)*(25*tc/45);

      x26=Vo*cos(kat)*(26*tc/45);

      x27=Vo*cos(kat)*(27*tc/45);

      x28=Vo*cos(kat)*(28*tc/45);

      x29=Vo*cos(kat)*(29*tc/45);

      x30=Vo*cos(kat)*(30*tc/45);

      x31=Vo*cos(kat)*(31*tc/45);

      x32=Vo*cos(kat)*(32*tc/45);

      x33=Vo*cos(kat)*(33*tc/45);

      x34=Vo*cos(kat)*(34*tc/45);

      x35=Vo*cos(kat)*(35*tc/45);

      x36=Vo*cos(kat)*(36*tc/45);

      x37=Vo*cos(kat)*(37*tc/45);

      x38=Vo*cos(kat)*(38*tc/45);

      x39=Vo*cos(kat)*(39*tc/45);

      x40=Vo*cos(kat)*(40*tc/45);

      x41=Vo*cos(kat)*(41*tc/45);

      x42=Vo*cos(kat)*(42*tc/45);

      x43=Vo*cos(kat)*(43*tc/45);

      x44=Vo*cos(kat)*(44*tc/45);

      x45=Vo*cos(kat)*(tc);

 

      Y1=(Vo*sin(kat)*(tc/45))-((g*((tc/45)*(tc/45)))/2);

      y2=(Vo*sin(kat)*(2*tc/45))-((g*((2*tc/45)*(2*tc/45)))/2);

      y3=(Vo*sin(kat)*(3*tc/45))-((g*((3*tc/45)*(3*tc/45)))/2);

      y4=(Vo*sin(kat)*(4*tc/45))-((g*((4*tc/45)*(4*tc/45)))/2);

      y5=(Vo*sin(kat)*(5*tc/45))-((g*((5*tc/45)*(5*tc/45)))/2);

      y6=(Vo*sin(kat)*(6*tc/45))-((g*((6*tc/45)*(6*tc/45)))/2);

      y7=(Vo*sin(kat)*(7*tc/45))-((g*((7*tc/45)*(7*tc/45)))/2);

      y8=(Vo*sin(kat)*(8*tc/45))-((g*((8*tc/45)*(8*tc/45)))/2);

      y9=(Vo*sin(kat)*(9*tc/45))-((g*((9*tc/45)*(9*tc/45)))/2);

      y10=(Vo*sin(kat)*(10*tc/45))-((g*((10*tc/45)*(10*tc/45)))/2);

      y11=(Vo*sin(kat)*(11*tc/45))-((g*((11*tc/45)*(11*tc/45)))/2);

      y12=(Vo*sin(kat)*(12*tc/45))-((g*((12*tc/45)*(12*tc/45)))/2);

      y13=(Vo*sin(kat)*(13*tc/45))-((g*((13*tc/45)*(13*tc/45)))/2);

      y14=(Vo*sin(kat)*(14*tc/45))-((g*((14*tc/45)*(14*tc/45)))/2);

      y15=(Vo*sin(kat)*(15*tc/45))-((g*((15*tc/45)*(15*tc/45)))/2);

      y16=(Vo*sin(kat)*(16*tc/45))-((g*((16*tc/45)*(16*tc/45)))/2);

      y17=(Vo*sin(kat)*(17*tc/45))-((g*((17*tc/45)*(17*tc/45)))/2);

      y18=(Vo*sin(kat)*(18*tc/45))-((g*((18*tc/45)*(18*tc/45)))/2);

      y19=(Vo*sin(kat)*(19*tc/45))-((g*((19*tc/45)*(19*tc/45)))/2);

      y20=(Vo*sin(kat)*(20*tc/45))-((g*((20*tc/45)*(20*tc/45)))/2);

      y21=(Vo*sin(kat)*(21*tc/45))-((g*((21*tc/45)*(21*tc/45)))/2);

      y22=(Vo*sin(kat)*(22*tc/45))-((g*((22*tc/45)*(22*tc/45)))/2);

      y23=(Vo*sin(kat)*(23*tc/45))-((g*((23*tc/45)*(23*tc/45)))/2);

      y24=(Vo*sin(kat)*(24*tc/45))-((g*((24*tc/45)*(24*tc/45)))/2);

      y25=(Vo*sin(kat)*(25*tc/45))-((g*((25*tc/45)*(25*tc/45)))/2);

      y26=(Vo*sin(kat)*(26*tc/45))-((g*((26*tc/45)*(26*tc/45)))/2);

      y27=(Vo*sin(kat)*(27*tc/45))-((g*((27*tc/45)*(27*tc/45)))/2);

      y28=(Vo*sin(kat)*(28*tc/45))-((g*((28*tc/45)*(28*tc/45)))/2);

      y29=(Vo*sin(kat)*(29*tc/45))-((g*((29*tc/45)*(29*tc/45)))/2);

      y30=(Vo*sin(kat)*(30*tc/45))-((g*((30*tc/45)*(30*tc/45)))/2);

      y31=(Vo*sin(kat)*(31*tc/45))-((g*((31*tc/45)*(31*tc/45)))/2);

      y32=(Vo*sin(kat)*(32*tc/45))-((g*((32*tc/45)*(32*tc/45)))/2);

      y33=(Vo*sin(kat)*(33*tc/45))-((g*((33*tc/45)*(33*tc/45)))/2);

      y34=(Vo*sin(kat)*(34*tc/45))-((g*((34*tc/45)*(34*tc/45)))/2);

      y35=(Vo*sin(kat)*(35*tc/45))-((g*((35*tc/45)*(35*tc/45)))/2);

      y36=(Vo*sin(kat)*(36*tc/45))-((g*((36*tc/45)*(36*tc/45)))/2);

      y37=(Vo*sin(kat)*(37*tc/45))-((g*((37*tc/45)*(37*tc/45)))/2);

      y38=(Vo*sin(kat)*(38*tc/45))-((g*((38*tc/45)*(38*tc/45)))/2);

      y39=(Vo*sin(kat)*(39*tc/45))-((g*((39*tc/45)*(39*tc/45)))/2);

      y40=(Vo*sin(kat)*(40*tc/45))-((g*((40*tc/45)*(40*tc/45)))/2);

      y41=(Vo*sin(kat)*(41*tc/45))-((g*((41*tc/45)*(41*tc/45)))/2);

      y42=(Vo*sin(kat)*(42*tc/45))-((g*((42*tc/45)*(42*tc/45)))/2);

      y43=(Vo*sin(kat)*(43*tc/45))-((g*((43*tc/45)*(43*tc/45)))/2);

      y44=(Vo*sin(kat)*(44*tc/45))-((g*((44*tc/45)*(44*tc/45)))/2);

      y45=(Vo*sin(kat)*(tc/45))-((g*((tc/45)*(tc/45)))/2);

 

     }

int main()

{

    Dimensions dimensions(1024, 768);

    Document doc("my_svg.svg", Layout(dimensions, Layout::BottomLeft));

 

    // Red image border.

    Polygon border(Stroke(1, Color::Red));

    border << Point(0, 0) << Point(dimensions.width, 0)

        << Point(dimensions.width, dimensions.height) << Point(0, dimensions.height);

    doc << border;

    // Long notation.  Local variable is created, children are added to varaible.

 

    LineChart chart(0.0);

    Polyline polyline_a(Stroke(.5, Color::Blue));

    Polyline polyline_b(Stroke(.5, Color::Aqua));

    Polyline polyline_c(Stroke(3.5, Color::Fuchsia));

 

 

    doc << chart;

 

wprowadz_parametry();

oblicz();

 

 

 

 

        Polygon linia(Stroke(2, Color::Blue)); 

linia << Point(0, 0)<< Point(x1, Y1)<< Point(x2, y2) << Point(x3, y3) << Point(x4, y4) << Point(x5, y5)

<< Point(x6, y6) << Point(x7, y7) << Point(x8, y8) << Point(x9, y9)<< Point(x10, y10) << Point(x11, y11)

<< Point(x12, y12) << Point(x13, y13) << Point(x14, y14) << Point(x15, y15) << Point(x16, y16) << Point(x17, y17)

<< Point(x18, y18) << Point(x19, y19) << Point(x20, y20) << Point(x21, y21) << Point(x22, y22 )<< Point(x23, y23) << Point(x24, y24)

<< Point(x25, y25)<< Point(x26, y26) << Point(x27, y27)<< Point(x28, y28)<< Point(x29, y29) << Point(x30, y30)

<< Point(x31, y31) << Point(x32, y32) << Point(x33, y33) << Point(x34, y34)<< Point(x35, y35) << Point(x36, y36)

<< Point(x37, y37) << Point(x38, y38)<< Point(x39, y39)<< Point(x40, y40)<< Point(x41, y41) << Point(x42, y42)

<< Point(x43, y43) << Point(x44, y44) << Point(z, 0)  ;

 

        doc<<linia;

 

 

 

 

    doc.save();

}
0

tak samo w pętli

linia << Point(x[i], y[i])

po cholerę Ci tyle pustych linii w kodzie?

0

Hmmm... próbuję w ten sposób, ale nic mi nie rysuje. Wie ktoś co może być nietak?

#include <cstdlib>
#include <iostream>
#include <cmath>

#include "simple_svg_1.0.0.hpp"
double Vo,kat,z,tc,t;
double g=10;

using namespace svg;
using namespace std;

void wprowadz_parametry(){
    
    cin>>Vo;
    cin>>kat;
     }
void oblicz(){
    int n=45;
    int x[n];
	int y[n];
      z= ((Vo*Vo)*sin(2*kat))/g;
      tc=(2*Vo*sin(kat))/g;
      for(int i=0;i<n;i++)
      x[i]=Vo*cos(kat)*(tc++/45);
      
       for(int i=0;i<n;i++)
       
      y[i]=(Vo*sin(kat)*(tc++/45))-((g*((tc++/45)*(tc++/45)))/2);      
      
     }
int main()
{
    Dimensions dimensions(1024, 768);
    Document doc("my_svg.svg", Layout(dimensions, Layout::BottomLeft));

    // Red image border.
    Polygon border(Stroke(1, Color::Red));
    border << Point(0, 0) << Point(dimensions.width, 0)
        << Point(dimensions.width, dimensions.height) << Point(0, dimensions.height);
    doc << border;
   
  int n=45;
    int x[n];
	int y[n];
	wprowadz_parametry();
oblicz();

        Polygon linia(Stroke(2, Color::Blue)); 
        for(int i=0;i<n;i++)
        linia << Point(x[i], y[i]);
        doc<<linia;
     
    doc.save();
}
0

int x[n]; w funkcji oblicz to nie to samo co int x[n]; w funkcji main. Zadeklarowałeś dwie osobne zmienne!!! To się tyczy też innych zmiennych w kodzie.
Jeśli chcesz aby jakaś funkcja działała na zmiennych utworzonych w innej funkcji to musisz je przekazać przez parametry funkcji.

Dla przykładu:

/* ŹLE */
int main()
{
    int tab1[3] = { 1, 2, 3 };
    int tab2[3];

    KopiujTablice(3);
}

void KopiujTablice(unsigned n)
{
    /* tu tworzone są całkowicie nowe odrębne tablice! */
    int tab1[3];
    int tab2[3];

    for (int i = 0; i < n; i++) tab2[i] = tab1[i];
}
/* Dobrze */
int main()
{
    int tab1[3] = { 1, 2, 3 };
    int tab2[3];

    KopiujTablice(tab1, tab2, 3);
}

void KopiujTablice(int *zrodlo, int *cel, unsigned n)
{
    for (int i = 0; i < n; i++) {
        cel[i] = zrodlo[i];
    }
}
0

Ok, kompiluje się, ale niestety nie drukuje paraboli tylko jakąś elipsę. Co mnie dziwi, bo wg. wzorów powinna wychodzić parabola. Wie ktoś co może być nietak ?

0

Zamotałeś strasznie ten rzut ukośny. Przecież ruch jednostajnie przyspieszony to zwykłe:
user image

W danych dostajesz:
user image - kąt rzutu (nachylenie względem podłoża?)
user image - szybkość początkową

W programie zanim zaczniesz liczyć kolejne punkty najpierw wyznacz współczynniki:
user image
user image
user image

A w pętli podstawiaj wszystko do wzoru.

Point RuchJednostajniePrzyspieszony(Point x0, Point v0, Point a, double t)
{
    return Point(x0.x + v0.x * t + 0.5 * a.x * t * t, x0.y + v0.y * t + 0.5 * a.y * t * t);
}

/* ... */

Point x0 = ...
Point v0 = ...
Point a = ...

double t0 = ... // czas początkowy
double tk = ... // czas końcowy
double dt = (tk - t0) / (n - 1); // krok czasowy
double t = t0; // czas aktualnie liczony
Point x[n]; // wynik

for (int i = 0; i < n; i++)
{
    x[i] = RuchJednostajniePrzyspieszony(x0, v0, a, t);
    t += dt;
}
0

Witam,
za pomocą tych dwóch funkcji udało mi się zrobić, że rzut jest ładnie rysowany dla dowolnych prędkości i kątów, wszystko pięknie:

void wprowadz_parametry(){
   
    cin>>Vo;
    cin>>kat;
     }
void oblicz(){
   double x=0;
   double y=0;
  
   
   alfa=kat*(pi/180);
   vector<double> X;
   vector<double> Y;
   X.push_back(x);
   Y.push_back(y);
   double Vx=Vo*cos(alfa);
    double Vy=Vo*sin(alfa);
     const double dt = 0.02;
       while(y>=0)
     {
                x = x+Vx*dt;
                y = y+Vy*dt;
                X.push_back(x);
                Y.push_back(y);
                Vy=Vy-g*dt;
                }
    
	   Polygon linia(Stroke(2, Color::Blue)); 
 for(int i=0;i<X.size();i++){
		   linia << Point(X[i], Y[i]);}
          doc<<linia; 

Mam teraz pytanie, w jaki sposób zrobić, żeby dopisało mi do pliku svg kod animacji? Bo, żeby wyznaczyło w svg path, trzeba przed współrzędnymi dopisywać M, L itd. i za bardzo nie wiem jak to zrealizować. Proszę o pomoc.

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