Gå til innhold

C#: [Hjelp]Regne ut vektor verdier ut ifra vinkel og lengde.


Anbefalte innlegg

Som tittelen sier prøver jeg å lage en funksjon som regner ut en vektor ut ifra en gitt lengde og vinkel. Her er koden:

public Point GetVectorByLengthAndAngle(double length, double angle)
	{
		if (length == 0)
			return new Point(0, 0);
		else if (length < 0)
			throw new ArgumentException("Length cannot be negative.");
		if (360< angle || angle < 0)
			throw new ArgumentException("Angle cannot be negative or bigger than 360.");
	  double angleBuf = (((90 < angle && angle <=180)||(270 < angle && angle<=360)) ? 90 - (angle % 90) :(angle % 90));
	  return new Point((int)Math.Round(length * Math.Cos(angleBuf) * ((90 < angle && angle <= 270) ? -1 : 1)),(int) Math.Round(length * Math.Sin(angleBuf) * ((180 <= angle && angle <= 360) ? 1 : -1)));
	}

Det jeg gjør er å omforme en 0-360 graders vinkel til en 0-90 graders vinkel, og bruker denne i i den trigonometriske formelen Hyp * Cos(vinkel) = Hos og Hyp * Sin(vinkel) = Mot hvor Hyp er lengden, Hos er X komponenten, og Mot er Y komponenten i vektoren. Deretter gir jeg komponentene riktig fortegn utifra vinkelen. Dette virker desverre ikke (jeg testet ved å prøve å forlenge en vektor, men den returnerte vektoren hadde en vinkel som var villt forskjellig fra den opprinnelige). Hva gjør jeg galt?

Lenke til kommentar
Videoannonse
Annonse

Som gnålern sier, må du regne i radianer, og ikke i grader.

PI = 180 grader.

 

Men du gjør det mye vanskeligere enn det er.

 

return new Point(Math.Cos(vinkel) * lengde, Math.Sin(vinkel) * lengde)

 

edit:

Det er da heller ingen grunn til at vinkelen må være innenfor 0-360 grader.

Jeg ville ikke tatt med noen av de testene du utfører, siden ingen av tilfellene vil gi et program som kræsjer.

 

Hvis det derimot er kritisk at vinkelen faller innenfor 360 grader, så kan du bare sette vinkel %= 360.

 

Det at lengden derimot er negativ vil vel i de fleste tilfeller ikke ha noe å si, men om det er en feil eller ikke er selvsagt helt opp til kravspesifikasjonen til programmet ditt.

 

For å gjøre om grader til radianer multipliserer du med PI / 180.

Endret av GeirGrusom
Lenke til kommentar
  • 2 uker senere...

Mulig det er litt sent nå, men jeg benytter sjansen til å reklamere litt for evaldraw. Evaldraw er perfekt for å gjøre små matte/teori tester før du bruker koden i ditt eget program.

 

Følgende kode tegner en linje i origo ut mot vektoren. Vektorens vinkel styres av musa sin x-posisjon.

 

Jeg har kommentert koden grundig og lagd et par hjelpevariabler som

tegnePosX = originX + x;

tegnePosY = originY - y;

for å gjøre den mer forståelig.

Den kan absolutt kortes ned.

 

Hent evaldraw her:

http://advsys.net/ken/download.htm

 

/* 

Dette er et evaldraw script
evaldraw hjemmesia: 
http://advsys.net/ken

Last ned fra
http://advsys.net/ken/download.htm

*/

()
{
  cls();

  // Finn mident paa skjermen ved aa hente ut
  // vinduets bredde og hoyde

  originX = xres/2;
  originY = yres/2;

  // Vinkelen vaar styres med musa.
  // deler mousa sin x-posisjon paa vinduets bredde
  // og faar et tall mellom 0-1
  // ganger dette med 360 grader.

  angle = mousx/xres*360;

  // Sett av 2 variabler som vi sender inn i funksjonen
  x=0; y=0;

  // konverter vinkelen til radianer
  // og send inn x,y variablene
  GetVectorByLengthAndAngle(100, radToDeg(angle), x,y);

  // flytt tegneposisjonen til midten av skjermen
  moveto(originX, originY);

  // Transeler (flytt) punktet vaart til der vi vil
  // tegne det
  // Jeg tok originY-y fordi skjermen vaar sin positive y-akse gaar nedover.
  // Ulikt det vi er vant med fra matta. (+y bruker aa vaere opp)
  tegnePosX = originX + x;
  tegnePosY = originY - y; 

  // tegn en linje til vektorens endepunkt
  lineto(tegnePosX, tegnePosY);

  // Skriv ut hva vinkelen var (i grader, ikke radianer)
  printf("%g", angle);

  // skriv ut vektorens x og y komponenter
  printf("\nX=%g \nY=%g",x,y);
}

// Edit:
// & tegnet foran pointx og point y betår at vi sender en 
// "referanse" til variablene istedet for å sende kopier
// dette gjør sitt til at pointx og point i blir endret
// i koden lengre opp
GetVectorByLengthAndAngle(length,angle, &pointx, &pointy)
{
  pointx = cos(angle) * length;
  pointy = sin(angle) * length; 
}

radToDeg(rad)
{
  return rad*PI/180.0;
}

Endret av JAPCU
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...