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 }
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
...
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.