Eli jos haluan laskea kulman radiaaneina vaikka paikasta 110,220 paikkaan 0,0?
Voisiko joku väläyttää koodia?
https://www.ohjelmointiputka.net/keskustelu/
Tuolta taitaa näppärästi löytyä vastaus.
static inline float Angle(float x0,float y0,float x1,float y1) { float kulma=atan((y0-y1)/(x0-x1)); float rad=kulma*PI/180; return rad; }
Miksei tuo funktio toimi?
Kai on PI määritetty? =)
Mitä tapahtuu, jos x0 == x1?
Funktio atan palauttaa jo valmiiksi radiaaneja, joten muunnoksesi vain sotkee asioita. Lisäksi kannattaa käyttää funktiota atan2 atanin sijasta, jolloin koordinaattien merkit otetaan huomioon ja kulma osoittaa suoraan oikeaan tason neljännekseen. Tällöin ei myöskään tule ongelmaa nollalla jakamisen kanssa.
Suosittelen lukaisemaan tämän sivun tutoriaaleja - ainakin itselle valottui moni asia :).
Toi atan2 vaatii kaksi argumenttiä. Eli miten se käytännössä tapahtuu?
oisko, y-arvojen erotus ja x-arvojen erotus, jos oikeen muistan.
Tässäpä koodi.Mielestäni kaikki on oikein.Mitäpä mieltä ootte?
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "SDL.h" #include <math.h> #define PI 3.141592654 double x=310,y=230; static inline double Angle(double x0,double y0,double x1,double y1); /* The screen surface */ SDL_Surface *screen = NULL; /* This function draws to the screen; replace this with your own code! */ static void draw () { SDL_Rect rect; Uint32 color; /* Create a black background */ color = SDL_MapRGB (screen->format, 0, 0, 0); SDL_FillRect (screen, NULL, color); SDL_Rect paikka; paikka.x=x; paikka.y=y; paikka.w=20; paikka.h=20; color = SDL_MapRGB (screen->format, 255,0,0); SDL_FillRect (screen,&paikka,color); double angle=Angle(x,y,0,0); x+=cos(angle)*1; y+=sin(angle)*1; /* Make sure everything is displayed on screen */ SDL_Flip (screen); SDL_Delay(100); /* Don't run too fast */ } int main (int argc, char *argv[]) { int done; /* Initialize SDL */ if (SDL_Init (SDL_INIT_VIDEO) < 0) { printf ("Couldn't initialize SDL: %s\n", SDL_GetError ()); exit (1); } atexit (SDL_Quit); /* Set 640x480 16-bits video mode */ screen = SDL_SetVideoMode (640, 480, 16, SDL_SWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN); if (screen == NULL) { printf ("Couldn't set 640x480x16 video mode: %s\n", SDL_GetError ()); exit (2); } SDL_WM_SetCaption ("SDL MultiMedia Application", NULL); done = 0; while (!done) { SDL_Event event; /* Check for events */ while (SDL_PollEvent (&event)) { switch (event.type) { case SDL_KEYDOWN: if(event.key.keysym.sym == SDLK_ESCAPE) done = 1; break; default: break; } } /* Draw to screen */ draw (); } return 0; } static inline float Length(float x0, float y0, float x1, float y1) { float dx = x1 - x0, dy = y1 - y0; return sqrt(dx * dx + dy * dy); } static inline double Angle(double x0,double y0,double x1,double y1) { double kulma=atan2((y0-y1),(x0-x1)); return kulma; }
Mietippä tarkkaan mitä seuraava rivi tekee.
double angle=Angle(x,y,0,0);
Millaisia arvoja angle-muuttuja saa ohjelman ajon aikana?
Pitäisikö käyttäjän kenties pystyä muuttamaan suuntaa?
Edit: Et myöskään missään vaiheessa kertonut, mikä ongelmasi on (= mitä ohjelma tekeen ja mitä sen pitäisi tehdä). Tämä on hyvä muistaa jatkossa.
No tää on vaan esimerkki räpellys.
Itse projektissa tietokone tulee siirtämään hiiriosoitinta omalla vuorollaan eli molemmat arvot voivat olla mitä vain.
Oletteko sitä mieltä että vois toimia noin?
Dev-Cpp kiidättää palikkaa samaan suuntaan vaikka vaihdan arvoja...
Pointtini oli siinä, että tuolla koodilla loota liikkuu aina suoraan poispäin vasemmasta yläkulmasta.
Edit: Edelleenkin voin vain arvailla, mitä ohjelman PITÄISI tehdä...
Kiitos Gaxx että kerroit että koordinaatit on annettava toisessa järjestyksessä.
Sain koodin toimimaan eli saan lootan liikkumaan minne haluan.
Asia on järjestyksessä.
Kiitos kaikille vastanneille!!!!!:)
Ps.Tää ohjelmointiputka on kyllä kurko mesta kun vastaukset satelee tänne aikamoista vauhtia....
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "SDL.h" #include <math.h> #include <time.h> #define PI 3.141592654 double x=310,y=230; double kx=800,ky=600; void Randomize(); inline int Random(int lu); static inline double Angle(double x0,double y0,double x1,double y1); static inline float Length(float x0, float y0, float x1, float y1); /* The screen surface */ SDL_Surface *screen = NULL; /* This function draws to the screen; replace this with your own code! */ static void draw () { SDL_Rect rect; Uint32 color; /* Create a black background */ color = SDL_MapRGB (screen->format, 0, 0, 0); SDL_FillRect (screen, NULL, color); SDL_Rect paikka; paikka.x=x; paikka.y=y; paikka.w=20; paikka.h=20; color = SDL_MapRGB (screen->format, 255,0,0); SDL_FillRect (screen,&paikka,color); paikka.x=kx; paikka.y=ky; paikka.w=2; paikka.h=2; SDL_FillRect (screen,&paikka,color); double angle=Angle(kx,ky,x,y); x+=cos(angle)*1; y+=sin(angle)*1; if (Length(x,y,kx,ky)<10) { kx=Random(639); ky=Random(479); } /* Make sure everything is displayed on screen */ SDL_Flip (screen); SDL_Delay(10); /* Don't run too fast */ } int main (int argc, char *argv[]) { int done; Randomize(); kx=Random(639);ky=Random(479); /* Initialize SDL */ if (SDL_Init (SDL_INIT_VIDEO) < 0) { printf ("Couldn't initialize SDL: %s\n", SDL_GetError ()); exit (1); } atexit (SDL_Quit); /* Set 640x480 16-bits video mode */ screen = SDL_SetVideoMode (640, 480, 16, SDL_SWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN); if (screen == NULL) { printf ("Couldn't set 640x480x16 video mode: %s\n", SDL_GetError ()); exit (2); } SDL_WM_SetCaption ("SDL MultiMedia Application", NULL); done = 0; while (!done) { SDL_Event event; /* Check for events */ while (SDL_PollEvent (&event)) { switch (event.type) { case SDL_KEYDOWN: if(event.key.keysym.sym == SDLK_ESCAPE) done = 1; break; default: break; } } /* Draw to screen */ draw (); } return 0; } static inline float Length(float x0, float y0, float x1, float y1) { float dx = x1 - x0, dy = y1 - y0; return sqrt(dx * dx + dy * dy); } static inline double Angle(double x0,double y0,double x1,double y1) { double kulma=atan2((y0-y1),(x0-x1)); return kulma; } inline int Random(int lu) { lu++; return rand()%lu; //int t=rand(); //return rand()/(32768/lu+1); } void Randomize() { //(rand(time()); srand(time(NULL)); }
Tässä vielä koodi joka tekee jotain "järkevää".Siinä muillekkin oppia tästä aiheesta.
Aihe on jo aika vanha, joten et voi enää vastata siihen.