Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C++: Luokka 2D-koordinaateille

jutti [15.09.2003 16:10:43]

#

Tein luokan kaksiulotteisille koordinaattipisteille. Luokan avulla luodaan olioita, jotka ovat koordinaattipisteitä (x- ja y-koordinaatti). Luokan jäsenillä voidaan siirtää pisteitä, kiertää niitä toistensa ympäri, laskea kahden pisteen etäisyydet ym. Tällä luokalla on helppo piirtää esim. fraktaaleja, joista esimerkkejä seuraavilla sivuilla:

http://edu.loviisa.fi/~jhalmen/fractals (englanniksi)
http://edu.loviisa.fi/~jhalmen/fraktaler (ruotsiksi)

Osoitteet päivitetty!

floatcoord.hpp

//  lyhyet selitykset funktioista

#ifndef FLOATCOORDHPP
#define FLOATCOORDHPP

// Irrallinen funktio absoluuttista arvoa varten
float Abs(float x);

class FloatCoord
{
  public:
  float x;
  float y;

  // Muodostimet:

  // alustaa pisteen x=0 ja y=0
  FloatCoord();

  // alustaa pisteen annetuilla arvoilla
  FloatCoord(float xin, float yin);

  // Kiertää pistettä annetun (x0,y0):n ympäri,
  // angle radiaaneissa
  void Rotate(float x0, float y0, float angle);

  // Kiertää pistettä toisen pisteolion ympäri
  void Rotate(FloatCoord *p, float angle);

  // Kiertää pistettä origon ympäri
  void Rotate(float angle);

  // Siirtää pistettä absoluuttisen matkan
  void Add(float xd, float yd);

  // Siirtää pistettä toisen pisteen x- ja y-arvojen mukaan
  void Add(FloatCoord *p);

  // Siirtää pistettä suhteessa origoon,
  // esim p1.Div(4); siirtää p1:n neljäsosan päähän origosta
  void Div(float div);

  // Sama kuin yllä, mutta suhteessa toiseen pisteolioon
  void Div(FloatCoord *p, float div);

  // Sama kuin yllä, mutta suhteessa annettuun koordinaattiin
  void Div(float x0, float y0, float div);

  // Samat kuin yllä, mutta käyttäen kertolaskua,
  // esim. p1.Mul(4); nelinkertaistaa pisteen etäisyyden
  // origosta (samaa janaa pitkin)
  void Mul(float mul);
  void Mul(FloatCoord *p, float mul);
  void Mul(float x0, float y0, float mul);

  // Laskee pisteiden etäisyyksiä
  float Distance(FloatCoord *another);
  float operator-(FloatCoord &another);

  // Ynnää x- ja y-arvoihin toisen pisteolion arvot
  void operator+=(FloatCoord &another);
};

#endif

floatcoord.cpp

#include <math.h>
#include "floatcoord.hpp"

float Abs(float x)
{
   if (x > 0)
      return x;
   return -x;
}

FloatCoord::FloatCoord()
{
 x = 0;
 y = 0;
}

FloatCoord::FloatCoord(float xin, float yin)
: x(xin), y(yin)
{
}

// Kierrä origon ympäri
void FloatCoord::Rotate(float angle)
{
   float xn, yn;

   xn = x * cos(angle) - y * sin(angle);
   yn = x * sin(angle) + y * cos(angle);
   x = xn;
   y = yn;
}

// Kierrä toisen pisteen ympäri
// (siirtää pisteen ensin origoa kohti,
// kiertää, sitten siirtää takaisin. Näppärää!
// samaa tekniikkaa käyttävät muutkin funktiot alempana)
void FloatCoord::Rotate(float x0, float y0, float angle)
{
   x -= x0;
   y -= y0;

   Rotate(angle);

   x += x0;
   y += y0;
}

void FloatCoord::Rotate(FloatCoord *p, float angle)
{
   Rotate(p->x, p->y, angle);
}

void FloatCoord::Add(float xd, float yd)
{
  x += xd;
  y += yd;
}

void FloatCoord::Add(FloatCoord *p)
{
  x += p->x;
  y += p->y;
}

void FloatCoord::operator+=(FloatCoord &another)
{
  x += another.x;
  y += another.y;
}

void FloatCoord::Div(float div)
{
  x /= div;
  y /= div;
}

void FloatCoord::Div(float x0, float y0, float div)
{
   x -= x0;
   y -= y0;
   Div(div);
   x += x0;
   y += y0;
}

void FloatCoord::Div(FloatCoord *p, float div)
{
   Div(p->x, p->y, div);
}


void FloatCoord::Mul(float mul)
{
  x *= mul;
  y *= mul;
}

void FloatCoord::Mul(float x0, float y0, float mul)
{
   x -= x0;
   y -= y0;
   Mul(mul);
   x += x0;
   y += y0;
}

void FloatCoord::Mul(FloatCoord *p, float mul)
{
   Mul(p->x, p->y, mul);
}


float FloatCoord::Distance(FloatCoord *another)
{
   float d;

   d = pow(x - another->x, 2) + pow(y - another->y, 2);
   d = sqrt(d);
   return d;
}

// Ajattelin, että olisi mukavaa pystyä kirjoittamaan
// etaisyys = p1 - p2;
float FloatCoord::operator-(FloatCoord &another)
{
   float d;

   d = pow(x - another.x, 2) + pow(y - another.y, 2);
   d = sqrt(d);
   return d;
}

Esimerkkiohjelma

// (ei tee juuri mitään, mutta kuitenkin...)
// Eli linkitä yhdessä floatcoord.cpp:n kanssa
#include <iostream>
#include <math.h>
#include "floatcoord.hpp"

int main(void)
{
   // Muodosta tasasivuinen kolmio p1, p2, p3
   FloatCoord p1(1, 1);
   FloatCoord p2(5, 1);
   FloatCoord p3 = p2;
   p3.Rotate(&p1, M_PI/3); // kierrä 60 astetta

   // Tutki kärjen koordinaatit
   cout << p3.x << endl
        << p3.y << endl;

   // Kierrä kolmiota p2:n ympäri 90 astetta
   p1.Rotate(&p2, M_PI/2);
   p3.Rotate(&p2, M_PI/2);

   // jne
}

toodles [20.09.2003 08:57:37]

#

Hmm? :(
...
H:\kirjasto\floatcoord.cpp(30) : warning C4244: '=' : conversion from 'double' to 'float', possible loss of data
H:\kirjasto\floatcoord.cpp(31) : warning C4244: '=' : conversion from 'double' to 'float', possible loss of data
H:\kirjasto\floatcoord.cpp(120) : warning C4244: '=' : conversion from 'double' to 'float', possible loss of data
...

jutti [22.09.2003 21:15:33]

#

Ai niin, tuo on paha tapa mulla. Pitäisi ilmeisesti aina käyttää double eikä float. Mutta nuo on pelkkiä varoituksia, eikä virheitä, joten kääntäminen pitäisi onnistua.

xn = x * cos(angle) - y * sin(angle);

Muuttujat ovat tyyppiä float mutta sin() ja cos() ovat tyyppiä double. "possible loss of data" ei tarkoita muuta kuin että 14 desimaalin tarkkuus pienenee kuuteen. Suunnilleen.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta