Консультация № 180088
29.09.2010, 16:29
45.00 руб.
0 5 2
Уважаемые эксперты,помогите пожалуйста решить задачу.
Организовать меню,в ктором составить описание класса для объектов-векторов, которые задаются координатами конца в трехмерном пространстве. Обеспечить операции сложения и вычитания с получением вектора(-суммы или -разности), вычисления скалярного произведения двух векторов, длины вектора и косинуса угла между векторами.
И если можно,то с комментариями. Очень нужно
Заранее спасибо!

Обсуждение

Неизвестный
29.09.2010, 16:31
общий
вот эта задача нужна на С++
Неизвестный
29.09.2010, 20:04
общий
30.09.2010, 22:04
это ответ
Здравствуйте, Olgaa.

Вот полный код программы на с++ для вашей задачи: компилировал в Dev-C++, но и в MS Visual C++ тоже должен сработать.



Приложение:
#include <iostream> // подключаем стандартные библиотеки + библиотеку мат. функций.
#include <windows.h>
#include <math.h>

using namespace std;

void textrus(char t[]) // функция позволяет выводить русский текст
{
char s[255];
CharToOem(t,s);
cout << s << endl;
}

class vector3D // класс трехмерного вектора
{
public:
vector3D();
~vector3D();

void SetVector(char *caption); // функция позволяет ввести координаты вектора
void display(char *caption); // функция выводящая вектор на экран
void summ(vector3D *vec1, vector3D *vec2); // получает вектор суммы
void razn(vector3D *vec1, vector3D *vec2); // получает вектор разности
void dlina(vector3D *vec1); // вычисляет длину вектора
void scalar(vector3D *vec1, vector3D *vec2); // скалярно умножает вектора
void cosinus(vector3D *vec1, vector3D *vec2); // выводит косинус угла между векторами
private:
float x,y,z; // сами координаты
};

vector3D::vector3D() // конструктор класса
{
x = 0.0;
y = 0.0;
z = 0.0;
}

vector3D::~vector3D() // пустой деструктор
{
}

void vector3D::SetVector(char* caption)
{
textrus(caption);
cout << "X = "; cin >> x; // вводим координаты вектора
cout << "Y = "; cin >> y;
cout << "Z = "; cin >> z;
}

void vector3D::summ(vector3D *vec1, vector3D *vec2)
{
x = vec1->x + vec2->x; // складываем координаты векторов
y = vec1->y + vec2->y;
z = vec1->z + vec2->z;
}

void vector3D::razn(vector3D *vec1, vector3D *vec2)
{
x = vec1->x - vec2->x; // вычитаем координаты векторов
y = vec1->y - vec2->y;
z = vec1->z - vec2->z;
}

void vector3D::dlina(vector3D *vec1)
{
textrus("ДЛИНА ВЕКТОРА:");
// ниже мы вычисляем по фрмуле длину вектора
float u = sqrt((vec1->x*vec1->x) + (vec1->y*vec1->y) + (vec1->z*vec1->z) );
printf("%2.2f",u); cout << endl;
}

void vector3D::scalar(vector3D *vec1, vector3D *vec2)
{
float dot = (vec1->x*vec2->x) + (vec1->y*vec2->y) + (vec1->z*vec2->z);
// строчка выше умножает скалярно два вектора
textrus("РЕЗУЛЬТАТ СКАЛЯРНОГО ПРОИЗВЕДЕНИЯ ВЕКТОРОВ:");
printf("%2.2f",dot); cout << endl;
}

void vector3D::cosinus(vector3D *vec1, vector3D *vec2)
{
float dot = (vec1->x*vec2->x) + (vec1->y*vec2->y) + (vec1->z*vec2->z);
float u = sqrt((vec1->x*vec1->x) + (vec1->y*vec1->y) + (vec1->z*vec1->z) );
float u2 = sqrt((vec2->x*vec2->x) + (vec2->y*vec2->y) + (vec2->z*vec2->z) );
// по формуле находим косинус угла между векторами
float cos = ( dot / (u*u2) );

textrus("КОСИНУС УГЛА МЕЖДУ ВЕКТОРАМИ:");
printf("%2.2f",cos); cout << endl;
}

void vector3D::display(char *caption)
{
textrus(caption);
textrus("Вектор с координатами:");
cout << "X = "; printf("%2.2f",x); cout<<endl;
cout << "Y = "; printf("%2.2f",y); cout<<endl;
cout << "Z = "; printf("%2.2f",z); cout<<endl;
}

int main(int argc, char *argv[])
{
// обьявляем экземпляры класса, у нас 2 вектора для работы и один для результатов
vector3D *vector1 = new vector3D;
vector3D *vector2 = new vector3D;
vector3D *result_vector = new vector3D;

int p; // переменная для выбора в меню далее само меню
while (true)
{
textrus("------------------------МЕНЮ-------------------------");
textrus("\t1 - Сложение двух векторов");
textrus("\t2 - Разность двух векторов");
textrus("\t3 - Высчитать длину вектра");
textrus("\t4 - Скалярное произведение векторов");
textrus("\t5 - Косинус угла между векторами");
textrus("\t0 - Выход из программы");
textrus("-----------------------------------------------------");

cin >> p;
system("cls"); // очистим экран

switch (p) // смотрим что выбрали в меню и вызываем соответствующие функции
{
case 1:
vector1->SetVector("Введите координаты вектора 1:");
vector2->SetVector("Введите координаты вектора 2:");
result_vector->summ(vector1,vector2);
result_vector->display("-----------РЕЗУЛЬТАТ----------");
break;
case 2:
vector1->SetVector("Введите координаты вектора 1:");
vector2->SetVector("Введите координаты вектора 2:");
result_vector->razn(vector1,vector2);
result_vector->display("-----------РЕЗУЛЬТАТ----------");
break;
case 3:
vector1->SetVector("Введите координаты вектора:");
result_vector->dlina(vector1);
break;
case 4:
vector1->SetVector("Введите координаты вектора 1:");
vector2->SetVector("Введите координаты вектора 2:");
result_vector->scalar(vector1,vector2);
break;
case 5:
vector1->SetVector("Введите координаты вектора 1:");
vector2->SetVector("Введите координаты вектора 2:");
result_vector->cosinus(vector1,vector2);
break;
case 0:
exit(0); break;
}
}


system("PAUSE");
return EXIT_SUCCESS;
}
5
Программа работает. Большое спасибо!!! и всё очень ясно и понятно )
Неизвестный
29.09.2010, 23:59
общий
это ответ
Здравствуйте, Olgaa.
Программа. Проверял в MS VS 2010.
Работает по принципу калькулятора с обратной(польской) записью.
Код:
// Компилировать с включеной информацией о типах времени выполнения 
// Для MS VS это /GR

#include <locale>
#include <limits>
#include <iostream>
#include <iomanip>
#include <deque>
#include <valarray>
#include <stdexcept>
#include <cfloat>
#include <typeinfo>
#include <sstream>
#include <string>

using namespace std;

// Программа работает по принципу калькулятора с обратной(польской) записью
// Этот класс здесь исключительно для полиморфизма и возможности выводить/хранить
// в регистрах как числа, так и вектора
class register_object
{
public:
virtual string to_string() const=0;
virtual ~register_object(){};
};

// Собственно вектор
class my_vector:public register_object
{
public:
// Конструктор
explicit my_vector(double dx=0,double dy=0,double dz=0);
// Деструктор
virtual ~my_vector();
// Оператор сложения
my_vector operator+(const my_vector& right) const;
// Оператор вычитания
my_vector operator-(const my_vector& right) const;
// Скалярное произведение
double operator*(const my_vector& right) const;
// Длина вектора
double length() const;
// Выводит на экран
virtual string to_string() const;
// Сосинус между векторами
friend double cos(const my_vector& left,const my_vector& right);
// Оператор вывода
template<class Elem,class Traits> friend basic_istream<Elem,Traits>& operator>>(basic_istream<Elem,Traits>& stream,my_vector& vec);
private:
double _dx,_dy,_dz;
};

// Служит для хранения в регистрах калькулятора чисел типа double
class my_num:public register_object
{
public:
explicit my_num(double val=0);
virtual ~my_num();
virtual string to_string() const;
private:
double _val;
};

// Собственно программа
class application
{
public:
~application();
void run();
private:
// Возможный выбор пользователя
enum user_choice
{
INPUT,
PLUS,
MINUS,
SCALAR,
LENGTH,
COS,
DELETE,
QUIT
};

// Меню
user_choice menu();
// Ввод вектора
my_vector input_vector();
// Печать регистров калькулятора
void print_registers();
// Сложение векторов
my_vector plus_operation();
// Вычитание векторов
my_vector minus_operation();
// Скалярное произведение
double scalar_operation();
// Длина
double length_operation();
// Косинус
double cos_operation();

typedef deque<register_object*> register_stack;
typedef register_stack::const_reverse_iterator rev_it;
// Здесь будем хранить значения
register_stack registers;

void check_registers(register_stack::size_type count) const;
void delete_registers(register_stack::size_type count);
};

int main()
{
locale::global(locale(""));

application app;
app.run();

return 0;
}

my_vector::my_vector( double dx/*=0*/,double dy/*=0*/,double dz/*=0*/ )
:_dx(dx)
,_dy(dy)
,_dz(dz)
{}

my_vector my_vector::operator+( const my_vector& right ) const
{
return my_vector(_dx+right._dx,_dy+right._dy,_dz+right._dz);
}

my_vector my_vector::operator-( const my_vector& right ) const
{
return my_vector(_dx-right._dx,_dy-right._dy,_dz-right._dz);
}

double my_vector::operator*( const my_vector& right ) const
{
return _dx*right._dx+_dy*right._dy+_dz*right._dz;
}

double my_vector::length() const
{
return sqrt(_dx*_dx+_dy*_dy+_dz*_dz);
}

string my_vector::to_string() const
{
stringstream sstream;
sstream<<'('<<_dx<<','<<_dy<<','<<_dz<<')';
return sstream.str();
}

my_vector::~my_vector()
{
}

double cos( const my_vector& left,const my_vector& right )
{
double result=left*right/left.length()/right.length();
if(!_finite(result))
{
throw runtime_error("Невозможно вычислить косинус");
}
return result;
}

template<class Elem,class Traits>
basic_istream<Elem,Traits>& operator>>(basic_istream<Elem,Traits>& stream,my_vector& vec)
{
double dx,dy,dz;
stream>>dx>>dy>>dz;
if(!stream.fail())
{
vec._dx=dx;
vec._dy=dy;
vec._dz=dz;
}
return stream;
}


my_num::my_num( double val/*=0*/ )
:_val(val)
{

}

string my_num::to_string() const
{
stringstream sstream;
sstream<<_val;
return sstream.str();
}

my_num::~my_num()
{

}

application::~application()
{
// Освободим память.
// Т.к. полиморфизм работает через указатели/ссылки мы ее выреляли динамически
while(!registers.empty())
{
delete registers.front();
registers.pop_front();
}
}

void application::run()
{
user_choice choice;
// Реакция на ввод пользователя
while((choice=menu())!=QUIT)
{
try
{
switch(choice)
{
case INPUT:
{
registers.push_front(new my_vector(input_vector()));
break;
}
case PLUS:
{
my_vector tmp=plus_operation();

delete_registers(2);
registers.push_front(new my_vector(tmp));
break;
}
case MINUS:
{
my_vector tmp=minus_operation();

delete_registers(2);
registers.push_front(new my_vector(tmp));
break;
}
case SCALAR:
{
double tmp=scalar_operation();

delete_registers(2);
registers.push_front(new my_num(tmp));
break;
}
case LENGTH:
{
double tmp=length_operation();

delete_registers(1);
registers.push_front(new my_num(tmp));
break;
}
case COS:
{
double tmp=cos_operation();

delete_registers(2);
registers.push_front(new my_num(tmp));
break;
}
case DELETE:
{
delete_registers(1);
break;
}
}
}
catch(const runtime_error& ex)
{
cout<<ex.what()<<endl;
}
catch(...)
{
cout<<"Необработанное исключение"<<endl;
}
print_registers();
}
}

application::user_choice application::menu()
{
while(true)
{
cout<<"Меню:"<<endl
<<"1 - Ввод вектора"<<endl
<<"2 - Сложить"<<endl
<<"3 - Вычесть"<<endl
<<"4 - Скалярное произведение"<<endl
<<"5 - Длина вектора"<<endl
<<"6 - Косинус угла между векторами"<<endl
<<"7 - Удалить последнее значение"<<endl
<<"0 - Выход"<<endl
<<"Ваш выбор:";
wint_t choice=_getwche();
cout<<endl<<endl;
switch(choice)
{
case '0':
return QUIT;
case '1':
return INPUT;
case '2':
return PLUS;
case '3':
return MINUS;
case '4':
return SCALAR;
case '5':
return LENGTH;
case '6':
return COS;
case '7':
return DELETE;
default:
cout<<"Будьте внимательней"<<endl;
}
}
}

my_vector application::input_vector()
{
my_vector res;
cout<<"Введите координаты вектора(dx,dy,dz):";
cin>>res;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
throw runtime_error("Ошибочный ввод");
}
return res;
}

void application::print_registers()
{
if(registers.size())
{
cout<<"------------------------------"<<endl;
cout<<"Стек регистров калькулятора:"<<endl;
cout<<"------------------------------"<<endl;
register_stack::size_type i=registers.size();
while(i--)
{
cout<<setw(14)<<left<<(i?"":"Результат:")<<registers[i]->to_string()<<endl;
}
cout<<"------------------------------"<<endl;
}
}

my_vector application::plus_operation()
{
check_registers(2);
return *dynamic_cast<my_vector*>(registers[0])+*dynamic_cast<my_vector*>(registers[1]);
}

my_vector application::minus_operation()
{
check_registers(2);
return *dynamic_cast<my_vector*>(registers[1])-*dynamic_cast<my_vector*>(registers[0]);
}

double application::scalar_operation()
{
check_registers(2);
return *dynamic_cast<my_vector*>(registers[1])**dynamic_cast<my_vector*>(registers[0]);
}

double application::length_operation()
{
check_registers(1);
return dynamic_cast<my_vector*>(registers[0])->length();
}

double application::cos_operation()
{
check_registers(2);
return cos(*dynamic_cast<my_vector*>(registers[0]),*dynamic_cast<my_vector*>(registers[1]));
}

// Проверяет требуемое количество регистров на наличие в них векторов, а не, например, чисел
void application::check_registers( register_stack::size_type count ) const
{
stringstream sstream;

if(registers.size()<count)
{
sstream<<"Требуется "<<count<<" операнд(а)";
throw runtime_error(sstream.str());
}
for(register_stack::size_type i=0;i<count;++i)
{
// Проверка на соответствие по типу указателя
if(typeid(*registers[i])!=typeid(my_vector))
{
sstream<<"Требуется "<<count<<" вектор(а)";
throw runtime_error(sstream.str());
}
}
}

// Очищает требуемое количество регистров
void application::delete_registers( register_stack::size_type count )
{
if(count>registers.size())
{
count=registers.size();
}
while(count--)
{
delete registers.front(); registers.pop_front();
}
}


Пример работы:
Код:
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:1

Введите координаты вектора(dx,dy,dz):1 2 3
------------------------------
Стек регистров калькулятора:
------------------------------
Результат: (1,2,3)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:1

Введите координаты вектора(dx,dy,dz):3 4 5
------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
Результат: (3,4,5)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:1

Введите координаты вектора(dx,dy,dz):0 5 0
------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
Результат: (0,5,0)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:1

Введите координаты вектора(dx,dy,dz):1 0 0
------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
(0,5,0)
Результат: (1,0,0)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:1

Введите координаты вектора(dx,dy,dz):2 4 6
------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
(0,5,0)
(1,0,0)
Результат: (2,4,6)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:1

Введите координаты вектора(dx,dy,dz):9 8 6
------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
(0,5,0)
(1,0,0)
(2,4,6)
Результат: (9,8,6)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:1

Введите координаты вектора(dx,dy,dz):7 7 7
------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
(0,5,0)
(1,0,0)
(2,4,6)
(9,8,6)
Результат: (7,7,7)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:5

------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
(0,5,0)
(1,0,0)
(2,4,6)
(9,8,6)
Результат: 12,1244
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:7

------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
(0,5,0)
(1,0,0)
(2,4,6)
Результат: (9,8,6)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:4

------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
(0,5,0)
(1,0,0)
Результат: 86
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:7

------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
(0,5,0)
Результат: (1,0,0)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:6

------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
(3,4,5)
Результат: 0
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:7

------------------------------
Стек регистров калькулятора:
------------------------------
(1,2,3)
Результат: (3,4,5)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:2

------------------------------
Стек регистров калькулятора:
------------------------------
Результат: (4,6,8)
------------------------------
Меню:
1 - Ввод вектора
2 - Сложить
3 - Вычесть
4 - Скалярное произведение
5 - Длина вектора
6 - Косинус угла между векторами
7 - Удалить последнее значение
0 - Выход
Ваш выбор:
5
Неизвестный
30.09.2010, 00:02
общий
Евгений Набоков:
Такие методы:
Код:
void dlina(vector3D *vec1); // вычисляет длину вектора
void scalar(vector3D *vec1, vector3D *vec2); // скалярно умножает вектора
void cosinus(vector3D *vec1, vector3D *vec2); // выводит косинус угла между векторами

логичнее делать статическими.

Кстати. Если пользователь введет в Вашем меню не корректные данные(напр. букву) то бесконечный цикл гарантирован.
Неизвестный
30.09.2010, 18:41
общий
Согласен, просто решил, что задание исключает какие либо функции для работы с векторами вне класса. С меню да, накосячил, спасибо что сообщили.
Форма ответа