Klasa Punkt3D – losowanie punktów i wyznaczanie najbliższego i najdalszego względem początku układu współrzędnych

0

Hejka :P

Mam do napisania klasę przedstawiającą punkt 3D. Mam też wylosować 10 pkt. i określić, który jest najbliżej początku układu współrzędnych, a który najdalej. Na razie mam coś takiego i nie wiem jak się zabrać do tych odległości. Jakoś w tablicy je zapisać czy co? Liczę na Waszą pomoc :D Jeśli wszystko jest źle, to nie krzyczcie. Jeszcze nie bardzo ogarnęłam klasy ;)

#include <iostream>
#include<cmath>

using namespace std;

class Punkt3D{
    string nazwa;
    double x;
    double y;
    double z;
public:
    Punkt3D();
    Punkt3D(string name, double x1, double y1, double z1);
    ~Punkt3D();
    string Punkt3D::getNazwa(void);
    double Punkt3D::getX();
    double Punkt3D::getY();
    double Punkt3D::getZ();
    void setNazwa(string name);
    void setX(double x1);
    void setY(double y1);
    void setZ(double z1);
    double Punkt3D::getOdleglosc();

};
Punkt3D::Punkt3D(){
    nazwa = "Punkt";
    x=0.0;
    y=0.0;
    z=0.0;
}
Punkt3D::Punkt3D(string name, double x1, double y1, double z1){
    nazwa = name;
    x = x1;
    y = y1;
    z = z1;
}
Punkt3D::~Punkt3D(){
    cout<<"Koniec punktu " << nazwa <<endl;
}
string Punkt3D::getNazwa(void){
    return nazwa;
}
double Punkt3D::getX(){
    return x;
}
double Punkt3D::getY(){
    return y;
}
double Punkt3D::getZ(){
    return z;
}
void setNazwa(string name){
    nazwa = name;
}
void setX(double x1){
    x=x1;
}
void setY(double y1){
    y=y1;
}
void setZ(double z1){
    z=z1;
}
double Punkt3D::getOdleglosc(){
  odl = (x^2+y^2+z^2)^(1/2);
  return odl;
}


int main()
{
    Punkt3D punkt1=("A1", rand(), rand(), rand());
    Punkt3D punkt2=("A2", rand(), rand(), rand());
    Punkt3D punkt3=("A3", rand(), rand(), rand());
    Punkt3D punkt4=("A4", rand(), rand(), rand());
    Punkt3D punkt5=("A5", rand(), rand(), rand());
    Punkt3D punkt6=("A6", rand(), rand(), rand());
    Punkt3D punkt7=("A7", rand(), rand(), rand());
    Punkt3D punkt8=("A8", rand(), rand(), rand());
    Punkt3D punkt9=("A9", rand(), rand(), rand());
    Punkt3D punkt10=("A10", rand(), rand(), rand());
    double tab[10];
    double najmn;
    double najwie;
    najmn = tab[1];
    najwie = tab[1];
    tab[1] = punkt1.getOdleglosc();
    tab[2] = punkt2.getOdleglosc();
    tab[3] = punkt3.getOdleglosc();
    tab[4] = punkt4.getOdleglosc();
    tab[5] = punkt5.getOdleglosc();
    tab[6] = punkt6.getOdleglosc();
    tab[7] = punkt7.getOdleglosc();
    tab[8] = punkt8.getOdleglosc();
    tab[9] = punkt9.getOdleglosc();
    tab[10] = punkt10.getOdleglosc();

    return 0;
}
0

Można w pętli tworzyć punkty. I jednocześnie sprawdzać czy dany punkt jest najbliższy z aktualnych lub czy jest najdalszy. Jako początkowa wartość najdalszego należy ustawić 0, a dla najbliższego maksymalną double. Jako początkowy punkt dać nulla. Jeśli punkt jest bliższy od najbliższego należy go ustawić jako najbliższy (analogicznie z najdłuższym).

1
  1. Od kiedy to do wyznaczenia odległości stosujemy pierwiastek trzeciego stopnia?
  2. Tak w ogóle, porównując odległości, ich kwadrat odległości jest równie dobry co właściwa odległość, a ponieważ pierwiastkowanie kosztuje, nie warto tego robić.
  3. rand() zwraca wartość int, a Ty potrzebujesz double. Wartość double uzyskasz dzieląc rand() przez RAND_MAX, ale lepiej korzystać z funkcji dostępnych w <random>.
  4. Do wyznaczenia minimalnej wartości skorzystaj z std::min_element(tab, tab+10)
0

Ktoś Tobie wytłumaczył, że ^ to bynajmniej nie jest operator potęgowania?
Skoro liczysz tutaj kwadraty, to nawet nie używaj funkcji pow z cmath, wystarczy przemnożyć przez siebie.

Poza tym, nazywanie takiej funkcji getOdleglosc jest złe z dwóch powodów: mieszane polsko angielskie nazwy powinno się tępić, oraz, co może ważniejsze, tym getem sugerujesz, że funkcja zwraca pole klasy, gdy tymczasem jest to zaledwie metodą coś licząca (która na marginesie mogłaby być const). Ja bym nazwał ją po prostu odleglosc, bądź zgodnie z matematyczną nomenklatura, normaEuklidesowa.

1

Masz błąd na błędzie... Zacznij może od tego..

#include <iostream>
#include <string>

// C++11
class Point3D{
public:
    Point3D(const std::string& name = "Point",
            double x = 0.0, double y = 0.0, double z = 0.0);
    ~Point3D();
    const std::string& getName() const;
    double getX() const;
    double getY() const;
    double getZ() const;
    void setName(const std::string& name);
    void setX(double x1);
    void setY(double y1);
    void setZ(double z1);
    double getDistance2Pow() const;
private:
    std::string name;
    double x;
    double y;
    double z;
};

Point3D::Point3D(const std::string& name_,
        double x_, double y_, double z_)
    : name{name_}, x{x_}, y{y_}, z{z_} { }

Point3D::~Point3D(){
    std::clog << "Point3D destructor name = " << name << '\n';
}

const std::string& Point3D::getName() const {
    return name;
}

double Point3D::getX() const {
    return x;
}

double Point3D::getY() const {
    return y;
}

double Point3D::getZ() const {
    return z;
}

void Point3D::setName(const std::string& name_) {
    name = name_;
}

void Point3D::setX(double x_){
    x = x_;
}

void Point3D::setY(double y_){
    y = y_;
}

void Point3D::setZ(double z_){
    z = z_;
}

double Point3D::getDistance2Pow() const {
    return x * x + y * y + z * z;
}

A i tak lepiej wprowadzić klasę pomocniczą współrzędnych.
NIe używaj rand(...) tylko funkcji z <random>
Nie wiem po co Ci setName(...) ale zostawiłem. Chyba nie będziesz zmieniać nazwy punktu?
Zwracaj uwagę na const w funkcjach nie zmieniających stanu obiektu.

Przykład kompilowany jest w standardzie C++11

0

Program już działa, tylko dalej mam problem z drugą częścią zadania - wylosuj 10 punktów, porównaj ich odległości od początku układu i w wypisz dane punktów najbliższych i najdalszych.
Czy ktoś wie, jak to zrobić w miarę szybko?

#include <iostream>
#include<cmath>

using namespace std;

class Punkt3D{
    string nazwa;
    double x;
    double y;
    double z;
public:
    Punkt3D();
    Punkt3D(string name, double x1, double y1, double z1);
    ~Punkt3D();
    string getNazwa(void);
    double getX();
    double getY();
    double getZ();
    void setNazwa(string name);
    void setX(double x1);
    void setY(double y1);
    void setZ(double z1);
    double getOdleglosc();

};
Punkt3D::Punkt3D(){
    nazwa = "Punkt";
    x=0.0;
    y=0.0;
    z=0.0;
}
Punkt3D::Punkt3D(string name, double x1, double y1, double z1){
    nazwa = name;
    x = x1;
    y = y1;
    z = z1;
}
Punkt3D::~Punkt3D(){
    cout<<"Koniec punktu " << nazwa <<endl;
}
string Punkt3D::getNazwa(void){
    return nazwa;
}
double Punkt3D::getX(){
    return x;
}
double Punkt3D::getY(){
    return y;
}
double Punkt3D::getZ(){
    return z;
}
void Punkt3D::setX(double x1){
    x=x1;
}
void Punkt3D::setY(double y1){
    y=y1;
}
void Punkt3D::setZ(double z1){
    z=z1;
}
double Punkt3D::getOdleglosc(){
    double odl;
  odl = sqrt(x*x+y*y+z*z);
  return odl;
}


int main()
{
    Punkt3D punkt1;
    Punkt3D punkt2=Punkt3D("A2", 125.9, 134, 2);
    cout<<punkt1.getNazwa()<<endl;
    cout<<"Wspolrzedne: "<<endl;
    cout<<punkt1.getX()<<endl;
    cout<<punkt1.getY()<<endl;
    cout<<punkt1.getZ()<<endl;
    cout<<punkt2.getNazwa()<<endl;
    cout<<"Wspolrzedne: "<<endl;
    cout<<punkt2.getX()<<endl;
    cout<<punkt2.getY()<<endl;
    cout<<punkt2.getZ()<<endl;
    return 0;
}

Ehhh... zapomniałem o const w funkcjach.
No ale podaję mniej więcej, jak kod wygląda

0

Zrób pola publiczne i wywal te sztuczne gettery i settery

1
#include <iostream>
#include <random>
#include <cmath>
#include <ctime>

class Point3D
{	
public:
    Point3D(double x = 0.0, double y = 0.0, double z = 0.0) : X(x), Y(y), Z(z) {}
    ~Point3D() {}
    double x() const { return X; }
    double y() const { return Y; }
    double z() const { return Z; }
    void setX(double x) { X = x; }
    void setY(double y) { Y = y; }
    void setZ(double z) { Z = z; }
    double distance() { return std::sqrt(X*X + Y*Y + Z*Z); }

private:
    double X;
    double Y;
    double Z;
};

void sortPoints(Point3D *points)
{
    for (int i = 0; i < 10; i++)
        for (int j = 0; j < 10; j++)
            if (points[j].distance() > points[i].distance())
            {
                Point3D tmp = points[i];
                points[i] = points[j];
                points[j] = tmp;
            }
}

int main()
{
    std::mt19937 gen;
    gen.seed(std::time(0));
	
    std::uniform_real_distribution<> dis(0, 200);
	
    Point3D origin;
    Point3D points[10];
	
    for (int i = 0; i < 10; i++)
    {
        points[i].setX(dis(gen));
        points[i].setY(dis(gen));
        points[i].setZ(dis(gen));
    }
	
    sortPoints(points);
	
    std::cout << "wylosowane i posortowane punkty: \n";
    for (int i = 0; i < 10; i++)
        std::cout << "punkt " << i+1 << ":  (" << points[i].x() << ", " << points[i].y() << ", " << points[i].z() << ")" << "  odleglosc: " << points[i].distance() << "\n";
	
    return 0;
}

-std=c++14 (albo 11 albo 17 chyba)
Bez specjalnych optymalizacji, ale bez przesady to nie assembler, no i zostawiłem te sztuczne settery i gettery.

1 użytkowników online, w tym zalogowanych: 0, gości: 1