Gå til innhold

Eksperiment; hjelp med sin(), cos().


Anbefalte innlegg

Trenger litt hjelp med programmet mitt, jeg vil få rotasjonen av cursoren til å gå mer smooth. Tror noen dere kunne hjelpe meg med dette? Har ikke så mye viten når det kommer til trigonometri o.l.

 

Her er det jeg har så langt (Mulig det er litt rotete :blush: ):

#include <windows.h>
#include <math.h>
#include <iostream>

using namespace std;

void clrscr()
{
system("cls");
}

int main()
{
int neg = -100;
int neu = 0;
int pos = 100;
int dia = 200;
int speed = 10;
int position = 1000;

while(1==1)
{
/*=================================================*/
for(float s = neu; s < pos; s++)
{
	Sleep(speed);

clrscr();

int x = (sin(s) * dia) + position;
int y = (cos(-s) * dia) + position;

SetCursorPos(x, y);

cout << "x: " << x << " y: " << y;
}
/*=================================================*/	
for(float s = pos; s > neg; s--)
{
	Sleep(speed);

clrscr();

int x = (sin(s) * dia) + position;
int y = (cos(-s) * dia) + position;

SetCursorPos(x, y);

cout << "x: " << x << " y: " << y;
}
/*=================================================*/ 
	for(float s = neg; s < neu; s++)
{
	Sleep(speed);

clrscr();

int x = (sin(s) * dia) + position;
int y = (cos(-s) * dia) + position;

SetCursorPos(x, y);

cout << "x: " << x << " y: " << y;
}
/*=================================================*/
}
}

Takk!

Endret av Mightal
Lenke til kommentar
Videoannonse
Annonse

#include <windows.h>
#include <math.h>
#include <iostream>
#include <time.h>
using namespace std;

void wait(int millis)
{
   //dette er en dårlig metode for å vente. Bør bruke SDL elns.
   //ventetiden varierer etter cpu og os.
   int endwait=clock() + millis;
   while (clock() < endwait) {}
}

void clrscr()
{
   system("cls");
}

int main()
{
   int neu = 0;
   float pos = 2*3.14;
   int dia = 100;
   int speed = 10;
   int position = 500;
   cout << "Trykk ctrl+c for aa avbryte" << endl;
   while(1)
   {
/*=================================================*/
   for(float s = neu; s < pos; s=s+0.01){
       //wait(speed);
       Sleep(speed);
       //clrscr();
       double x = (sin(s) * dia) + position;
       double y = (cos(-s) * dia) + position;
       SetCursorPos((int)x, (int)y);
       //cout << "x: " << x << " y: " << y;
   }//end for
   }//end while
}//end main

 

Dette var Morsomt, Mightal :)

 

Bruker double og caster til int igjen som SetCursorPos krever. La til en wait funksjon som ikke krever windows... men er dårlig.

Synd at c++ ikke har en skikkelig getCurrentTimeMillis() funksjon. Må bruke os kall eller bibliotek.

Endret av JAPCU
Lenke til kommentar

Det er ikke nødvendig å vente, det er bedre å bevege pekeren etter hvor lang tid som har gått.

 

double x, y;
double angle = 0.0;
double radius = 10.0;
int pos_x = 50;
int pos_y = 10;

long long frequency = 0;
long long old_time = 0;
long long new_time;
float time = 0f;

// ! Windows spesifik kode ! 
QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
QueryPerformanceTimer((LARGE_INTEGER*)&old_time);

while(1)
{
 // ! Windows spesifikk
 QueryPerformanceTimer((LARGE_INTEGER*)&new_time);

 time = ((float)(new_time - old_time)) / frequency; 
 old_time = new_time;

 angle += (2 * PI) * time;

 x = cos(angle) * radius; y = sin(angle) * radius;

 SetCursorPos((int)x + pos_x, (int)y, pos_y);
}

Endret av GeirGrusom
Lenke til kommentar

Da har jeg oppdatert koden min! Mulig den er litt unødvendig lang men jeg tar ting som det kommer, er tross alt en nybegynner! :p

 

#include <windows.h>
#include <math.h>
#include <time.h>
#include <iostream>

using namespace std;

void clrscr()
{
system("cls");
}

void wait(int milli)
{
int time = clock() + milli;
while (clock() < time) {}
}

int main()
{
int neg = -100;
int neu = 0;
int pos = 100;
int dia = 200;
int speed = 0; //higher value will make it go slower
int position = 500;

HDC hdc = GetDC(HWND_DESKTOP);

while(1 == 1)
{
/*=================================================*/
for(float s = neu; s < pos; s = s + 0.01)
{
	wait(speed);

clrscr();

int x = (sin(s) * dia) + position;
int y = (cos(-s) * dia) + position;

SetCursorPos(x, y);

SetPixel(hdc, x, y, RGB(255, 0, 0));

cout << "x: " << s << " y: " << -s << endl;
cout << "x: " << x << " y: " << y << endl;
}
/*=================================================*/	
for(float s = pos; s > neg; s = s - 0.01)
{
	wait(speed);

clrscr();

int x = (sin(s) * dia) + position;
int y = (cos(-s) * dia) + position;

SetCursorPos(x, y);

SetPixel(hdc, x, y, RGB(255, 0, 0));

cout << "x: " << s << " y: " << -s << endl;
cout << "x: " << x << " y: " << y << endl;
}
/*=================================================*/ 
	for(float s = neg; s < neu; s = s + 0.01)
{
	wait(speed);

clrscr();

int x = (sin(s) * dia) + position;
int y = (cos(-s) * dia) + position;

SetCursorPos(x, y);

SetPixel(hdc, x, y, RGB(255, 0, 0));

cout << "x: " << s << " y: " << -s << endl;
cout << "x: " << x << " y: " << y << endl;
}
/*=================================================*/
}
}

Endret av Mightal
Lenke til kommentar
Det er ikke nødvendig å vente, det er bedre å bevege pekeren etter hvor lang tid som har gått.

 

double x, y;
double angle = 0.0;
double radius = 10.0;
int pos_x = 50;
int pos_y = 10;

long long frequency = 0;
long long old_time = 0;
long long new_time;
float time = 0f;

// ! Windows spesifik kode ! 
QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
QueryPerformanceTimer((LARGE_INTEGER*)&old_time);

while(1)
{
 // ! Windows spesifikk
 QueryPerformanceTimer((LARGE_INTEGER*)&new_time);

 time = ((float)(new_time - old_time)) / frequency; 
 old_time = new_time;

 angle += (2 * PI) * time;

 x = cos(angle) * radius; y = sin(angle) * radius;

 SetCursorPos((int)x + pos_x, (int)y, pos_y);
}

 

 

Flott! du ignorerte det jeg sa, da melder jeg meg ut av denne diskusjonen.

Det var slettes ikke meningen, kan du være snill og fortelle hvordan den fungerer?

Lenke til kommentar

Du må være klar over at datamaskinen jobber med radianer, ikke grader e.l.

 

En full sirkel går fra 0 til 2 ganger pi

 

Så -100 til 0 vil lage et feilaktig mønster, siden det fører til at den vinkelen øker med ca. 57 grader for hvert steg.

 

Det som skjer i koden jeg skrev, er at den beregner antall sekunder siden forrige "frame" og øker med en vinkel på 360 grader (2PI) for hvert sekund.

Dette vil føre til at jo kjappere maskin du har jo glattere vil den bevege seg rundt.

 

QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
QueryPerformanceTimer((LARGE_INTEGER*)&old_time);

Denne henter informasjon fra high resolution timeren, første er frekvensen, og andre er nåværende verdi.

 

// ! Windows spesifikk
 QueryPerformanceTimer((LARGE_INTEGER*)&new_time);

 time = ((float)(new_time - old_time)) / frequency;
 old_time = new_time;

 angle += (2 * PI) * time;

Her henter vi ny timer verdi, regner ut forskjellen, og deler på frekvensen. Da får vi et flyttall som er i antall sekunder.

Deretter legger vi til en full sirkel, og multipliserer med tiden.

 

x = cos(angle) * radius; y = sin(angle) * radius;

 SetCursorPos((int)x + pos_x, (int)y, pos_y);

Vi regner ut sinus og cosinus verdien, og plasserer musepekeren.

Lenke til kommentar

Et tjuv-triks er å kalle timeBeginPeriod(1); i begynnelsen av programmet og timeEndPeriod() i slutten. Da kan man bruke timeGetTime å få tiden siden programmet har startet med 1 ms presisjon.

 

trenger spesielle includes og linking mot et windowslib, mmsystem.lib eller noe sånt, men er nice å bruke.

Endret av _vamecum
Lenke til kommentar

High resolution timer er den funksjonen i Windows som har høyest presisjon etter det jeg vet. Man bruker den som regel i spill, fordi den aldri vil gi tilbake 0 (med mindre systemet ikke støtter high resolution timer)

Andre timer funksjoner har en oppløsning på 15 ms og under, og kan da gi 0 tilbake dersom det tar mindre en 15 ms mellom hver frame, som vil føre til at programmet står helt stille (x * 0 = 0)

Lenke til kommentar
Det er ikke nødvendig å vente, det er bedre å bevege pekeren etter hvor lang tid som har gått.

 

double x, y;
double angle = 0.0;
double radius = 10.0;
int pos_x = 50;
int pos_y = 10;

long long frequency = 0;
long long old_time = 0;
long long new_time;
float time = 0f;

// ! Windows spesifik kode ! 
QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
QueryPerformanceTimer((LARGE_INTEGER*)&old_time);

while(1)
{
 // ! Windows spesifikk
 QueryPerformanceTimer((LARGE_INTEGER*)&new_time);

 time = ((float)(new_time - old_time)) / frequency; 
 old_time = new_time;

 angle += (2 * PI) * time;

 x = cos(angle) * radius; y = sin(angle) * radius;

 SetCursorPos((int)x + pos_x, (int)y, pos_y);
}

Har prøvd meg litt frem nå, dette er helt klart mer effektivt enn mitt script. Rettet på en liten feil, vet ikke om det bare var min compiler.

#include <windows.h>
#include <math.h>

#define PI 3.14159265358979323846

int main()
{
HWND hWnd = GetConsoleWindow(); 
ShowWindow(hWnd, SW_HIDE);
/*==========================================================*/
double x, y;
double angle = 0.0;
double radius = 500;
int pos_x = GetSystemMetrics(SM_CXSCREEN) / 2;
int pos_y = GetSystemMetrics(SM_CYSCREEN) / 2;
/*==========================================================*/ 
long long frequency = 0;
long long old_time = 0;
long long new_time;
float time = 0;
/*==========================================================*/
QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
QueryPerformanceCounter((LARGE_INTEGER*)&old_time);
/*==========================================================*/
HDC hdc = GetDC(HWND_DESKTOP);
/*==========================================================*/
while(!GetAsyncKeyState(0x23)) //Loop til man trykker på 'end'
{
 QueryPerformanceCounter((LARGE_INTEGER*)&new_time);

 time = ((float)(new_time - old_time)) / frequency; 
 old_time = new_time;

 angle = angle + (2 * PI) * time;

 x = cos(angle) * radius; y = sin(angle) * radius;

 SetCursorPos((x + pos_x), (y + pos_y));
 SetPixel(hdc, (x + pos_x), (y + pos_y), RGB(255, 0, 0));
}
}

Endret av Mightal
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...