• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Animacja w konsoli z wykorzystaniem równań parametrycznych

Object Storage Arubacloud
0 głosów
491 wizyt
pytanie zadane 19 listopada 2016 w C i C++ przez Arek Wolszczak Nowicjusz (120 p.)

Potrzebuję zrobić animację w konsoli używając języka C. Animacja ma polegać na tym że dwa obiekty poruszają się po dwóch różnych krzywych parametrycznych, a kiedy się zderzą(czyli będą mieć te same współrzędne) program ma się skończyć.

 

Ogólny zarys działania programu:

Równanie 1 - cykloida, równanie 2 - okrąg

1. Obliczenie współrzędnych x i y obiektów z równań parametrycznych

2. Wykorzystując przejście do nowej linii i spacje, wstawienie obiektów w oknie konsoli

3. Odczekanie sekundy i "wyczyszczenie" okna konsoli wykorzystując przejście do nowej linii

4. Powrót do punktu 1

 

Problemy:

1. Obliczone współrzędne zawierają części ułamkowe a karetki nie da sie przesunąć o np 4.2345 spacji. Co zrobić aby program używał tylko części całkowitych z obliczonych współrzędnych?

2. Po wstawieniu obiektu 1 karetka będzie znajdować w miejscu o współrzędnych x1 y1 a nie w umownych początku czyli w lewym górnym rogu okna konsoli. Czy da sie ją przywrócić do początku?

3. Czy da sie zrobić tak żeby funkcja printf wyświetlała jakiś obiekt n razy w zależności od n?

4. Czy ten schemat programu ma w ogóle sens?

 

Poniżej kod (nie zawiera jeszcze części dla obiektu 2 i warunku zakończenia)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <unistd.h>

int main()
{
    int a=1;
    int b=1;
    int c=5;
    int t,i,j,k;
    float x1,y1,x2,y2;
    for (t=0; t<1; t++)
    {
        x1=(a*t)-(b*sin(t)); /*obliczenie wspolrzednych */
        y1=a-(b*cos(t));
        x2=7+c*cos(t);
        y2=7+c*sin(t);
        if (x1==x2 && y1==y2)
        {
            
        }
        for (i=0;i<y1;i++) /*przesuniecie karetki w dol */
        {
            printf("\n");
        }
        for (j=0;i<x1;j++) /*przesuniecie karetki w prawo */
        {
            printf(" ");
            printf("*"); /*wstawienie obiektu nr 1 */
        }
        sleep(1)
        for (k=0; k<44; k++) /*wyczyszczenie okna konsoli*/
        {
            printf("\n");
        }
    }
    return 0;
}

 

1 odpowiedź

+1 głos
odpowiedź 19 listopada 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 20 listopada 2016 przez plkpiotr

Według mnie jest sporo niedopowiedzeń w poleceniu, bo faktycznie powinniśmy działać na tablicach, a te lubią liczby całkowite, a nie zmiennoprzecinkowe, stąd albo działamy tylko na tych pierwszych, albo dokonujemy konwersji (czego odradzam, bo będzie pracochłonne, a niekoniecznie poprawi nam obliczenia).

Tablica jednowymiarowa... Hm... Jeżeli ma to być animacja na płaszczyźnie dwuwymiarowej, to będzie nam właśnie dwuwymiarowa tablica potrzebna, szczególnie jeżeli chcemy ją rysować. Krok t również wydaje mi się za mały na liczby stałoprzecinkowe.

Na podstawie Twojego kodu napisałem analogiczny, żeby Ci coś zilustrować w jaki sposób to zrealizować... Wizualnie zobaczysz co dzieje się podczas przebiegu pętli, program rysuje „okrąg” i „cykloidę” : )

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <conio.h>

#define SIZE 20

int main() {
    int a = 1;
    int b = 1;
    int c = 5;
    int x1, y1, x2, y2;
    char dlaOkregu[SIZE][SIZE];
    char dlaCykloidy[SIZE][SIZE];
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            dlaCykloidy[i][j] = ' ';
            dlaOkregu[i][j] = ' ';
        }
    }
    for(int t=0;t< SIZE;t++) {
        x1 = (a * t) - (b * sin(t));
        y1 = a - (b * cos(t));
        x2 = 7 + c * cos(t);
        y2 = 7 + c * sin(t);
        printf("Wspolrzedne cykloidy: (%d;%d)\n", x1, y1);
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                dlaCykloidy[x1][y1] = 'O';
                printf("%2c", dlaCykloidy[i][j]);
            }
            printf("\n");
        }
        printf("Wspolrzedne okregu: (%d;%d)\n", x2, y2);
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                dlaOkregu[x2][y2] = 'O';
                printf("%2c", dlaOkregu[i][j]);
            }
            printf("\n");
        }
        usleep(600000);
        system("cls");
        if (x1 > SIZE || x2 > SIZE || y1 > SIZE || y2 > SIZE)
            break;
    }
    return 0;
}

Wtedy na wyjściu otrzymasz:

Wspolrzedne cykloidy: (18;0)
 O
   O
   O

   O
 O
 O
   O
   O

   O
 O
 O
 O
   O

   O
   O
 O

Wspolrzedne okregu: (11;7)
         O O   O   O
       O             O
                       O
     O
                       O
     O                 O
     O
                       O
       O             O
         O O   O   O
               O

Kluczowy będzie dobór parametrów a,b,c,t, bo zauważ, że cykloida, gdy "za długo" będzie się kręcić to nie ma szans się spotkać z okręgiem. Stwórzmy tablicę dwuwymiarową, wypełnijmy ją spacjami. Dla każdej z dwóch plansz (możesz zrobić na jednej) obliczamy współrzędne i zaznaczmy ten punkt literką O dla każdej nowej iteracji (możesz zmodyfikować, że za każdym przelotem napisze inny znak). Ja rozszerzyłem wyświetlanie do dwóch jednostek, aby w naturalny sposób była to kwadratowa siatka. Potem czyścimy konsolę. Jeśli piszesz pod Linux jest na to gotowa funkcja:

void ClrScr(){
  printf("\033[2J"); // Czyści ekran
  printf("\033[0;0f"); // Ustawia kursor w lewym, górnym rogu
}

Jeżeli jesteś zmuszony korzystać z Windowsa to albo trzeba pobawić się z powrotem karetki lub zastosować gotowca system("cls"); z conio.h. (W wyjątkowych okolicznościach powiedzmy, że można :P)

Nie jest to finalna wersja jednak umożliwi Ci ona zrealizowanie Twojego problemu np. poprzez dodanie warunku, który zrywałby pętlę wyznaczoną przez t gdy współrzędne punktów pokryłyby się...

Musisz po prostu przemyśleć jaka odpowiedź usatysfakcjonuje prowadzącego oraz który ze sposobów będzie dla Ciebie zrozumiały ; ) Powodzenia w dalszym kodzeniu!

Podobne pytania

+1 głos
2 odpowiedzi 2,903 wizyt
pytanie zadane 6 września 2016 w C i C++ przez Bober Nowicjusz (130 p.)
0 głosów
1 odpowiedź 344 wizyt
pytanie zadane 22 stycznia 2018 w C i C++ przez Damskii Nowicjusz (120 p.)
0 głosów
2 odpowiedzi 1,893 wizyt
pytanie zadane 20 lutego 2017 w C i C++ przez WireNess Stary wyjadacz (11,240 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...