Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/65: Рейтинг темы: голосов - 65, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 13.03.2016
Сообщений: 19

Классы геометрических фигур

17.06.2019, 23:31. Показов 13819. Ответов 26

Студворк — интернет-сервис помощи студентам
Всем привет! У меня возникли сложности с пониманием и реализацией задания.

Имеется задание (надеюсь перевести не составит труда):

Design a small program in C++ that would implement the following:
1. Support a few types of 3D geometric curves – circles, ellipses and 3D helixes. (Simplified
definitions are below). Each curve should be able to return a 3D point and a first derivative (3D
vector) per parameter t along the curve.
2. Populate a container (e.g. vector or list) of objects of these types created in random manner with
random parameters. Ensure that the container will contain objects of all supported types.
3. Print coordinates of points and derivatives of all curves in the container at t=PI/4.
4. Populate a second container that would contain only circles from the first container. Make sure the
second container shares (i.e. not clones) circles of the first one, e.g. via pointers.
5. Sort the second container in the ascending order of circles’ radii. That is, the first element has the
smallest radius, the last - the greatest.
6. Compute the total sum of radii of all curves in the second container.
Additional optional requirements:
7. Split implementation into a library of curves and executable which uses API of this library.
Expectations to the implementation:
1. The implementation must use virtual methods.
2. Has neither explicit memory deallocation nor memory leaks.
3. Curves must be physically correct (e.g. radii must be positive).
4. Containers and sorting must be implemented using STL (C++ Standard Template Library).
5. The implementation may use constructs of C++11 or higher.
6. The code must compile with any compiler of your choice (gcc, Visual C++, etc).
7. The result should be sent via email or posted on github. The delivery must contain source code only
(no compiled binaries): *.h and *.cpp files and project files, so that we can compile the result by
ourselves.
Curve definitions:
- All curves are parametrically defined, i.e. a point is calculated using some C(t) formula.
- Circle is planar in the plane XoY (i.e. all Z-coordinates are 0) and is defined by its radius.
- Ellipse is planar in the plane XoY and is defined by its two radii, along X and Y axes.
- Helix is spatial and is defined by its radius and step (see the figure below). It takes 2 * PI in
parametric space to make a round, i.e. any point on helix satisfies the condition C(t + 2*PI) = C(t) +
{0, 0, step}.

Прошу помощи опытных людей растолковать нюансы разработки данной программы, такие как:
-Каждая кривая должна иметь возможность возвращать 3D-точку и первую производную (3D
вектор) по параметру t вдоль кривой;
-Заполните контейнер (например, вектор или список) объектами этих типов, созданных случайным образом с помощью
случайных параметров. Убедиться, что контейнер будет содержать объекты всех поддерживаемых типов.

Соответственно появился довольно смешной вопрос:
Как заполнить контейнер, например вектор, объектами всех поддерживаемых типов (я так понял окружность, элипс, спираль)?
Как заполнить контейнер случайным образом?
и др.

Возможно кто-то встречал подобные задачи и есть какой либо пример. Примеры Классов окружность, элипс, спираль.

На работу выделено время - 7 дней. Очень прошу дать какую-либо информацию. Задание очень важное для меня.

Если есть дополнительные вопросы по задаче, прошу - задавайте. Пока что каких-либо наработок нет, когда сделаю хоть что-нибудь, обязательно выложу сюда.

Спасибо за внимание!
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.06.2019, 23:31
Ответы с готовыми решениями:

Иерархия геометрических фигур
Проблема с классами, никак не могу из за этого написать последнюю прогу... Помогуте если не сложно Создайте простую иерархию...

Масштабирование геометрических фигур
Было задание: Построить систему классов для описания плоских геометрических фигур: круг, квадрат, прямоугольник. Предусмотреть методы...

Вывод геометрических фигур
Привет всем! Такая проблема: С треугольниками разобрался- могу выводить с помощю цыклов разные и в разных ракурсах. Вот код: #include...

26
24 / 21 / 3
Регистрация: 04.11.2014
Сообщений: 283
17.06.2019, 23:42
Как заполнить вектор всеми поодерживаемыми типами? Ответ: реализуете базовый класс фигуры и наследуете все остальные от него, создаете вектор указателей на базовый класс, проходя по нему с помощью dynamic_cast приводите к нужному типу

Добавлено через 3 минуты
Аналогично примерно и с рандомным заполнением, рандомите число от 0;2 в цикле и создаете объект такого типа, после указатель на него заносите в вектор
2
Just Do It!
 Аватар для XLAT
4202 / 2659 / 654
Регистрация: 23.09.2014
Сообщений: 8,977
Записей в блоге: 3
18.06.2019, 00:12
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
Как заполнить контейнер, например вектор, объектами всех поддерживаемых типов (я так понял окружность, элипс, спираль)?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <vector>
 
// 3D вектор:
struct vec3
{   vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z)
    {
    }
    float x, y, z;
};
 
int main()
{   float x, y, z;
    std::vector<vec3> a;
    
    for(...) 
    {   
        /// Тут вычисляем, например, для сиркля x, y, z:
        ...
    
        a.push_back(vec3(x,y,z));
    }
    
    return 0;
}
+ добавить все то про что написал ЗеХель,

Цитата Сообщение от ЗеХель Посмотреть сообщение
проходя по нему с помощью dynamic_cast приводите к нужному типу
dynamic_cast не нужен. юзаем полиформизм тут , блин
2
24 / 21 / 3
Регистрация: 04.11.2014
Сообщений: 283
18.06.2019, 07:45
XLAT, я просто слишком впритык принял определние объектов и решил, что речь про ооп, вот и предложил решение в этом духе)
1
0 / 0 / 0
Регистрация: 13.03.2016
Сообщений: 19
18.06.2019, 23:19  [ТС]
Сделал следующее: базовый класс, от которого наследуются остальные Circle, Ellipse, Helix.
Следовал определениям кривых из задачи:
- Окружность плоская в плоскости XoY (т. е. все z-координаты равны 0) и определяется ее радиусом.
- Эллипс является плоским в плоскости XoY и определяется двумя его радиусами, вдоль осей X и Y.
- Спираль является пространственной и определяется ее радиусом и шагом (см. рисунок ниже).

Не понял что делать со следующими требованиями:
-Каждая кривая должна иметь возможность возвращать 3D-точку и первую производную (3D-вектор) по параметру t вдоль кривой.
- Все кривые параметрически определены, т. е. точка вычисляется по некоторой формуле C(t).
- Для спирали: Требуется 2 * PI в параметрическом пространстве, чтобы сделать раунд, т. е. любая точка на спирали удовлетворяет условию C(t + 2*PI) = C(t) + {0, 0, step}.

Создал массив указателей на объекты базового класса, и попытался присвоить указателям адреса Circle, Ellipse, и Helix.
Выпадает ошибка.

Попробовал создать вектор объектов базового класса (threeDShape) и заполнить разными объектами - кругом, эллипсом и спиралью, всё отлично работает. Но вот как сюда приплести указатели пока не додумался.

Не могли бы вы посмотреть данный код, указать на мои ошибки и дать совет. Спасибо.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <cstring>
#include <vector>
 
using namespace std;
 
class threeDShape{
    double Ox, Oy, Oz;
    char name[20];
public:
    threeDShape(){
        Ox = Oy = Oz = 0;
        strcpy(name, "unknown");
    }
    
    threeDShape(double x, double y, double z, char *n){
        Ox = x;
        Oy = y;
        Oz = z;
        strcpy(name, n);
    }
    
    double getOx(){ return Ox; }
    double getOy(){ return Oy; }
    double getOz(){ return Oz; }
    char *getName(){ return name; }
    void setOx(double x){ Ox = x; }
    void setOy(double y){ Oy = y; }
    void setOz(double z){ Oz = z; }
};
 
class Circle : public threeDShape{
    double radius;
public:
    Circle(){ radius = 0.0; }
    
    Circle(double x, double y, double r) : threeDShape(x, y, 0.0, "Circle"){
        radius = r;
    }
};
 
class Ellipse : public threeDShape{
    double radius1, radius2;
public:
    Ellipse(){ radius1 = radius2 = 0.0; }
    
    Ellipse(double x, double y, double r1, double r2) : threeDShape(x, y, 0.0, "Ellipse"){
        radius1 = r1;
        radius2 = r2;
    }   
};
 
class Helix : public threeDShape{
    double radius, step;
public:
    Helix(){ radius = step = 0.0; }
    
    Helix(double x, double y, double z, double r, double s) : threeDShape(x, y, z, "Helix"){
        radius = r;
        step = s;
    }
};
 
int main(){
    
    threeDShape *Shape[3];
    
    Shape[0] = &Circle(1.5, 1.0, 2.0);// тут появляется ошибка [Error] taking address of temporary [-fpermissive]
    Shape[1] = &Ellipse(2.5, 3.0, 2.5, 2.5);
    Shape[2] = &Helix(3.0, 3.5, 3.0, 4.0, 1.0);
    
    return 0;
}
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.06.2019, 00:18
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
- Все кривые параметрически определены, т. е. точка вычисляется по некоторой формуле C(t).
т.е. в базовом классе должно быть только t, почитайте про параметрические функции (заданы системой { x = f(t); y = g(t); z = h(t); })

Добавлено через 3 минуты
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
1. The implementation must use virtual methods.
Не вижу
Базовый нужно сделать абстрактным

Добавлено через 1 минуту
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
4. Containers and sorting must be implemented using STL (C++ Standard Template Library).
То же не вижу


и т.д.
1
Just Do It!
 Аватар для XLAT
4202 / 2659 / 654
Регистрация: 23.09.2014
Сообщений: 8,977
Записей в блоге: 3
19.06.2019, 00:26
Кирилл2738,
подправил чуть шоб скомпилилось:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <cstring>
#include <vector>
 
using namespace std;
 
class threeDShape{
    double Ox, Oy, Oz;
    char* name;
public:
    threeDShape(){
        Ox = Oy = Oz = 0;
        //strcpy(name, "unknown");
    }
    
    threeDShape(double x, double y, double z, const char *n){
        Ox = x;
        Oy = y;
        Oz = z;
        name = (char*)n;
        
    }
    
    double getOx(){ return Ox; }
    double getOy(){ return Oy; }
    double getOz(){ return Oz; }
    char *getName(){ return name; }
    void setOx(double x){ Ox = x; }
    void setOy(double y){ Oy = y; }
    void setOz(double z){ Oz = z; }
    
    void show()
    {   std::cout << name << "\n";
    }
};
 
class Circle : public threeDShape{
    double radius;
public:
    Circle(){ radius = 0.0; }
    
    Circle(double x, double y, double r) : threeDShape(x, y, 0.0, "Circle"){
        radius = r;
    }
};
 
class Ellipse : public threeDShape{
    double radius1, radius2;
public:
    Ellipse(){ radius1 = radius2 = 0.0; }
    
    Ellipse(double x, double y, double r1, double r2) : threeDShape(x, y, 0.0, "Ellipse"){
        radius1 = r1;
        radius2 = r2;
    }   
};
 
class Helix : public threeDShape{
    double radius, step;
public:
    Helix(){ radius = step = 0.0; }
    
    Helix(double x, double y, double z, double r, double s) : threeDShape(x, y, z, "Helix"){
        radius = r;
        step = s;
    }
};
 
int main()
{
    threeDShape *Shape[3];
    
    Circle c(1.5, 1.0, 2.0);
    Shape[0] = &c;
    Shape[0]->show();
    
    Ellipse e(2.5, 3.0, 2.5, 2.5);
    Shape[1] = &e;
    Shape[1]->show();
    
    Helix h(3.0, 3.5, 3.0, 4.0, 1.0);
    Shape[2] = &h;
    Shape[2]->show();
    
    return 0;
}
- Compiler Name: TDM-GCC 4.9.2 64-bit Release
1
0 / 0 / 0
Регистрация: 13.03.2016
Сообщений: 19
19.06.2019, 01:04  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
т.е. в базовом классе должно быть только t, почитайте про параметрические функции (заданы системой { x = f(t); y = g(t); z = h(t); })
Спасибо за ответ!
Я так понимаю из базового класса убрать x,y,z и добавить только параметр t. Таким образом получиться, что в производном классе, например в окружности, мы добавляем x,y,z и радиус. Радиус будет вводиться, z по условиям задачи равно 0, а x и y рассчитывается с использованием параметрической функции. Посмотрел уравнение некоторых кривых в параметрической форме, и для окружности выходит так: x = r * cos (t), y = r * sin(t), 0 <= t <= 2* Pi

Следовательно сделать подобное и к другим производным классам.
Соответственно не забывая использовать визуальную функцию (virtual methods).

Что касается Containers and sorting must be implemented using STL (C++ Standard Template Library), до этого я пока что не дошёл, необходимо правильно сделать базовый класс и производные.

Ещё раз спасибо за ответ, если не сложно поправьте меня если я ошибся.

Добавлено через 1 минуту
Цитата Сообщение от XLAT Посмотреть сообщение
подправил чуть шоб скомпилилось
Спасибо большое! Если есть ещё какие-либо замечания - вы очень поможете если выскажите их.
0
Just Do It!
 Аватар для XLAT
4202 / 2659 / 654
Регистрация: 23.09.2014
Сообщений: 8,977
Записей в блоге: 3
19.06.2019, 01:11
Кирилл2738, добавим чуть полиформизма:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>
#include <cstring>
#include <vector>
 
using namespace std;
 
class threeDShape{
    double Ox, Oy, Oz;
    char* name;
public:
    threeDShape(){
        Ox = Oy = Oz = 0;
        //strcpy(name, "unknown");
    }
    
    threeDShape(double x, double y, double z, const char *n){
        Ox = x;
        Oy = y;
        Oz = z;
        name = (char*)n;
        
    }
    
    virtual void calculate() = 0;
    
    double getOx(){ return Ox; }
    double getOy(){ return Oy; }
    double getOz(){ return Oz; }
    char *getName(){ return name; }
    void setOx(double x){ Ox = x; }
    void setOy(double y){ Oy = y; }
    void setOz(double z){ Oz = z; }
    
    void show()
    {   std::cout << name << "\n";
    }
};
 
class Circle : public threeDShape{
    double radius;
public:
    Circle(){ radius = 0.0; }
    
    Circle(double x, double y, double r) : threeDShape(x, y, 0.0, "Circle"){
        radius = r;
    }
    
    void calculate()
    {   std::cout << "calculate Circle\n";
    }
};
 
class Ellipse : public threeDShape{
    double radius1, radius2;
public:
    Ellipse(){ radius1 = radius2 = 0.0; }
    
    Ellipse(double x, double y, double r1, double r2) : threeDShape(x, y, 0.0, "Ellipse"){
        radius1 = r1;
        radius2 = r2;
    }
    
    void calculate()
    {   std::cout << "calculate Ellipse\n";
    } 
};
 
class Helix : public threeDShape{
    double radius, step;
public:
    Helix(){ radius = step = 0.0; }
    
    Helix(double x, double y, double z, double r, double s) : threeDShape(x, y, z, "Helix"){
        radius = r;
        step = s;
    }
    
    void calculate()
    {   std::cout << "calculate Helix\n";
    } 
};
 
int main()
{
    threeDShape *Shape[3];
    
    Circle c(1.5, 1.0, 2.0);
    Shape[0] = &c;
    Shape[0]->show();
    
    Ellipse e(2.5, 3.0, 2.5, 2.5);
    Shape[1] = &e;
    Shape[1]->show();
    
    Helix h(3.0, 3.5, 3.0, 4.0, 1.0);
    Shape[2] = &h;
    Shape[2]->show();
    
    Shape[0]->calculate();
    Shape[1]->calculate();
    Shape[2]->calculate();
    
    return 0;
}
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.06.2019, 01:13
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
т.е. в базовом классе должно быть только t
пардон, я тут чушь сморозил, t должен передаваться как параметр в эти методы:
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
Each curve should be able to return a 3D point and a first derivative (3D
vector) per parameter t along the curve.
1
Just Do It!
 Аватар для XLAT
4202 / 2659 / 654
Регистрация: 23.09.2014
Сообщений: 8,977
Записей в блоге: 3
19.06.2019, 01:54
добавим рандома:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <iostream>
#include <cstring>
#include <vector>
 
using namespace std;
 
class threeDShape{
    double Ox, Oy, Oz;
    char* name;
public:
    threeDShape(){
        Ox = Oy = Oz = 0;
        //strcpy(name, "unknown");
    }
    
    threeDShape(double x, double y, double z, const char *n){
        Ox = x;
        Oy = y;
        Oz = z;
        name = (char*)n;
        
    }
    
    virtual void calculate() = 0;
    
    double getOx(){ return Ox; }
    double getOy(){ return Oy; }
    double getOz(){ return Oz; }
    char *getName(){ return name; }
    void setOx(double x){ Ox = x; }
    void setOy(double y){ Oy = y; }
    void setOz(double z){ Oz = z; }
    
    void show()
    {   std::cout << name << "\n";
    }
};
 
class Circle : public threeDShape{
    double radius;
public:
    Circle(){ radius = 0.0; }
    
    Circle(double x, double y, double r) : threeDShape(x, y, 0.0, "Circle"){
        radius = r;
    }
    
    void calculate()
    {   std::cout << "calculate Circle\n";
    }
};
 
class Ellipse : public threeDShape{
    double radius1, radius2;
public:
    Ellipse(){ radius1 = radius2 = 0.0; }
    
    Ellipse(double x, double y, double r1, double r2) : threeDShape(x, y, 0.0, "Ellipse"){
        radius1 = r1;
        radius2 = r2;
    }
    
    void calculate()
    {   std::cout << "calculate Ellipse\n";
    } 
};
 
class Helix : public threeDShape{
    double radius, step;
public:
    Helix(){ radius = step = 0.0; }
    
    Helix(double x, double y, double z, double r, double s) : threeDShape(x, y, z, "Helix"){
        radius = r;
        step = s;
    }
    
    void calculate()
    {   std::cout << "calculate Helix\n";
    } 
};
 
#include <ctime>
#include <cstdlib>
struct srandom{srandom(){srand(time(NULL));}}orandom;
int random(int min, int max)
{   return min + rand() % (max - min);
}
 
int main()
{
    {   threeDShape *Shape;
        int i = random(0,2);
        std::cout << "random: " << i << "\n";
        
        switch(i)
        {  
            case 0:
                Shape = new Circle(1.5, 1.0, 2.0);
                break;
            case 1:
                Shape = new Ellipse(2.5, 3.0, 2.5, 2.5);
                break;
            case 2:
                Shape = new Helix(3.0, 3.5, 3.0, 4.0, 1.0);
                break;
            default:
                ;
        }
        Shape->calculate();
        
        delete Shape;
    }
    
    return 0;
}

* выше по треду,
там очепятка: полиформизма это полиморфизма
1
0 / 0 / 0
Регистрация: 13.03.2016
Сообщений: 19
19.06.2019, 01:58  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
пардон, я тут чушь сморозил, t должен передаваться как параметр в эти методы:
Я так понял по задаче параметр t - у всех фигур будет один
Print coordinates of points and derivatives of all curves in the container at t=PI/4.

Все остальное ,про параметрические функции, я правильно написал?

Добавлено через 58 секунд
Цитата Сообщение от XLAT Посмотреть сообщение
добавим рандома:
Спасибо большое за рандом! Как только разберусь с правильностью базового класса и производных, буду добавлять ваши наработки=)

Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class threeDShape{
    double T;
    char name[20];
public:
    threeDShape(){
        T = 0;
        strcpy(name, "unknown");
    }
    
    threeDShape(char *n){
        strcpy(name, n);
    }
    
    virtual void calculate() = 0;
    
    double getT(){ return T; }
    char *getName(){ return name; }
    void setT(double t){ T = t; }
};
 
class Circle : public threeDShape{
    double radius, x, y, z;
public:
    Circle(){ radius = x = y = z = 0.0; }
    
    Circle(double r) : threeDShape("Circle"){
        radius = r;
        z = 0.0;
    }
    
    void calculate(){
        x = radius * cos(getT());
        y = radius * sin(getT());
        cout << x;
    }
};
 
class Ellipse : public threeDShape{
    double x, y, z, radius1, radius2;
public:
    Ellipse(){ x = y = z = radius1 = radius2 = 0.0; }
    
    Ellipse(double r1, double r2) : threeDShape("Ellipse"){
        z = 0.0;
        radius1 = r1;
        radius2 = r2;
    }
    
    void calculate(){
        x = radius1 * cos(getT());
        y = radius2 * sin(getT());
    }   
};
 
class Helix : public threeDShape{
    double radius, step, x, y, z;
public:
    Helix(){ x = y = z = radius = step = 0.0; }
    
    Helix(double r, double s) : threeDShape("Helix"){
        radius = r;
        step = s;
    }
    
    void calculate(){
        x = radius * cos(getT());
        y = radius * sin(getT());
        z = (step / 2 * M_PI) * getT();
    }
};
Вот переделал базовый класс и соответственно производные. Похоже на правильный вариант?
0
Just Do It!
 Аватар для XLAT
4202 / 2659 / 654
Регистрация: 23.09.2014
Сообщений: 8,977
Записей в блоге: 3
19.06.2019, 02:03
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
про параметрические функции, я правильно написал?
у вас 2D, а нужно:
3D point
уж со спиралью точно нужно
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.06.2019, 02:11
Кирилл2738, начните с чего нибудь такого
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
struct Point3D { double x{}, y{}, z{}; };
 
struct Vector3D { double x{}, y{}, z{}; };
 
class Shape3D
{
protected:
    Point3D c{}; // "центр"(опорная точка)
    // хранить строку с названием - лишнее, можно воспользоваться средствами <typeinfo>
 
    Shape3D() = default;
    Shape3D(const Point3D& center) : c(center) {}
 
public:
    virtual ~Shape3D() {}
 
    //virtual void show_info(std::ostream&) = 0;    // если уж очень хочется
 
    virtual Point3D curve_point(double t) const = 0;        // точка кривой по параметру t
    virtual Vector3D curve_vector(double t) const = 0;  // вектор(первая производная) кривой по параметру t
};
 
class Circle3D : public Shape3D
{
    double radi{};
 
public:
    Circle3D() = default;
    Circle3D(const Point3D& center, double radius)
        : Shape3D(center), radi(radius) {}
 
    virtual ~Circle3D() {}
 
    virtual Point3D curve_point(double t) const override
    {
        // реализация
        return Point3D();
    }
    virtual Vector3D curve_vector(double t) const override
    {
        // реализация
        return Vector3D();
    }
};
Добавлено через 5 минут
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
Я так понял по задаче параметр t - у всех фигур будет один
Это по заданию нужно вычислить точку и вектор для данного t? а вообще параметр он на то и параметр, что может быть любым
0
0 / 0 / 0
Регистрация: 13.03.2016
Сообщений: 19
19.06.2019, 02:17  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
начните с чего нибудь такого
Большое спасибо! Попробую разобраться)

Цитата Сообщение от zayats80888 Посмотреть сообщение
Это по заданию нужно вычислить точку и вектор для данного t?
Вывести координаты точек и производные всех кривых в контейнере при t=PI / 4.
0
19.06.2019, 02:29

Не по теме:

Цитата Сообщение от Кирилл2738 Посмотреть сообщение
t?
тут не знак вопроса, а запятая, раскладку не переключил :)

0
Just Do It!
 Аватар для XLAT
4202 / 2659 / 654
Регистрация: 23.09.2014
Сообщений: 8,977
Записей в блоге: 3
19.06.2019, 02:40
чтобы без разночтений,
вот яндекс-перевод:
Кликните здесь для просмотра всего текста

Разработать небольшую программу на C++, которая будет выполнять следующие:
1. Поддержка нескольких типов 3D геометрических кривых-круги, эллипсы и 3D спирали. (Упрощенный
определения приведены ниже). Каждая кривая должна иметь возможность возвращать 3D-точку и первую производную (3D
вектор) по параметру t вдоль кривой.
2. Заполните контейнер (например, вектор или список) объектов этих типов, созданных случайным образом с помощью
случайные параметры. Убедитесь, что контейнер будет содержать объекты всех поддерживаемых типов.
3. Вывести координаты точек и производные всех кривых в контейнере при t=PI / 4.
4. Заполните второй контейнер, который будет содержать только круги из первого контейнера. Убедитесь, что
второй контейнер разделяет (т. е. не клоны) круги первого, например, через указатели.
5. Отсортируйте второй контейнер в порядке возрастания радиусов окружностей. То есть первый элемент имеет
наименьший радиус, последний-наибольший.
6. Вычислить общую сумму радиусов всех кривых во втором контейнере.
Дополнительные требования:
7. Разделите реализацию на библиотеку кривых и исполняемый файл, который использует API этой библиотеки.
Ожидания в отношении осуществления:
1. Реализация должна использовать виртуальные методы.
2. Не имеет ни явного освобождения памяти, ни утечек памяти.
3. Кривые должны быть физически правильными (например, радиусы должны быть положительными).
4. Контейнеры и сортировка должны быть реализованы с помощью STL (стандартная библиотека шаблонов C++).
5. Реализация может использовать конструкции C++11 или выше.
6. Код должен компилироваться с любым компилятором по вашему выбору (gcc, Visual C++ и т. д.).
7. Результат должен быть отправлен по электронной почте или размещен на GitHub. Поставка должна содержать только исходный код
(нет скомпилированных двоичных файлов):*.h и *.cpp-файлы и файлы проекта, так что мы можем скомпилировать результат
сами.
Определения кривых:
- Все кривые параметрически определены, т. е. точка вычисляется по некоторой формуле C(t).
- Окружность плоская в плоскости XoY (т. е. все z-координаты равны 0) и определяется ее радиусом.
- Эллипс является плоским в плоскости XoY и определяется двумя его радиусами, вдоль осей X и Y.
- Спираль является пространственной и определяется ее радиусом и шагом (см. рисунок ниже). Он принимает 2 * Пи внутри
параметрическое пространство для округления, т. е. любая точка на спирали удовлетворяет условию C (t + 2*PI) = C (t) +
{0, 0, шаг}.
0
0 / 0 / 0
Регистрация: 13.03.2016
Сообщений: 19
19.06.2019, 22:29  [ТС]
Добрый вечер!

Возникло недопонимание.

Если каждая кривая должна иметь возможность возвращать не только 3D-точку по параметру t, но и первую производную (3D-вектор) при том же параметре, то как понять следующее:

Для окружности производная при любом значении t будет такой - https://www.cyberforum.ru/cgi-bin/latex.cgi?{y}_{x} = -ctg (t), подставляем t=Pi/4 - получим -1. а я так понял у вектора есть x-y-z?

Вообщем не понимаю по по поводу этого вектора.

Объясните, пожалуйста, кому не трудно! Спасибо большое.
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.06.2019, 22:48
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
Для окружности производная
C++
1
Vector3D{ -1 * radi * sin(t), radi * cos(t) };
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
20.06.2019, 11:50
По отсутствию реакции, предположу что проблема так и не решена.
Цитата Сообщение от Кирилл2738 Посмотреть сообщение
Для окружности производная при любом значении t будет такой...подставляем t=Pi/4 - получим -1.
Это верно, проведите касательную к кривой в этой точке, тангенс угла с осью Х(135 град.) и есть -1. Но нам нужно задать эту касательную вектором, для чего мы просто вычисляем dx/dt, dy/dt и dz/dt, подставляем t -> получаем координаты искомого вектора.
Предлагаю ознакомится с моим вариантом решения этого задания(выполнено практически полностью, комментарии я расставил, если что не понятно - спрашивайте, хотя я старался лишнего не городить, код простой). Может что то улучшите в нем.
Что НЕ сделано:
2. Populate a container (e.g. vector or list) of objects of these types created in random manner with
random parameters.
Ensure that the container will contain objects of all supported types.
Additional optional requirements:
7. Split implementation into a library of curves and executable which uses API of this library.
Так же, из за отсутствия интерфейса пользователя(да и код учебный) не отлавливал исключения(по хорошему надо)
Перечитав задание, понял что "опорная" точка в базовом классе не нужна, можно вырезать, если хочется.
Сам код:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#include <iostream>
#include <random>
#include <cmath>
#include <memory>
#include <typeinfo>
#include <algorithm>
//===============================================================>
constexpr double eps = 1e-6;
//===============================================================>
struct Point3D { double x{}, y{}, z{}; };   // точка в 3-х мерном пространстве
 
std::ostream& operator<<(std::ostream& os, const Point3D& p)
{   // выводим точку в поток
    return os << "P{ " << p.x << ", " << p.y << ", " << p.z << " }";
}
//===============================================================>
struct Vector3D { double x{}, y{}, z{}; };  // вектор в 3-х мерном пространстве
 
std::ostream& operator<<(std::ostream& os, const Vector3D& v)
{   // выводим вектор в поток
    return os << "V{ " << v.x << ", " << v.y << ", " << v.z << " }";
}
//===============================================================>
class Shape3D   // базовый класс
{
protected:
    Point3D c{}; // "центр"(опорная точка)
 
    Shape3D() = default;
    Shape3D(const Point3D& center) : c{ center } {}
 
public:
    virtual ~Shape3D() {}
 
    virtual Point3D curve_point(double t) const = 0;    // точка кривой по параметру t
    virtual Vector3D curve_vector(double t) const = 0;  // вектор(первая производная) кривой по параметру t
};
//===============================================================>
class Circle3D : public Shape3D // окружность в плоскости XY
{
    double radi{};
 
public:
    Circle3D() = default;
    Circle3D(const Point3D& center, double radius)
        : Shape3D(center), radi{ radius } {}
 
    virtual ~Circle3D() {}
 
    double radius() const { return radi; }  // для сортировки и суммирования
 
    virtual Point3D curve_point(double t) const override
    {
        return Point3D
        {
            radi * std::cos(t) + c.x,
            radi * std::sin(t) + c.y,
            c.z
        };
    }
    virtual Vector3D curve_vector(double t) const override
    {
        return Vector3D
        {
            -1 * radi * std::sin(t),
            radi * std::cos(t)
        };
    }
};
//===============================================================>
class Ellipse3D : public Shape3D    // эллипс в плоскости XY
{
    double radi_x{};
    double radi_y{};
 
public:
    Ellipse3D() = default;
    Ellipse3D(const Point3D& center, double radius_x, double radius_y)
        : Shape3D(center), radi_x{ radius_x }, radi_y{ radius_y } {}
 
    virtual ~Ellipse3D() {}
 
    virtual Point3D curve_point(double t) const override
    {
        return Point3D
        {
            radi_x * std::cos(t) + c.x,
            radi_y * std::sin(t) + c.y,
            c.z
        };
    }
    virtual Vector3D curve_vector(double t) const override
    {
        return Vector3D
        {
            -1 * radi_x * std::sin(t),
            radi_y * std::cos(t)
        };
    }
};
//===============================================================>
class Helix3D : public Shape3D  // спираль с осью, параллельной оси Z
{
    double radi{};
    double step{};
 
public:
    Helix3D() = default;
    Helix3D(const Point3D& center, double radius, double step_z)
        : Shape3D(center), radi{ radius }, step{ step_z } {}
 
    virtual ~Helix3D() {}
 
    virtual Point3D curve_point(double t) const override
    {
        return Point3D
        {
            radi * t * std::cos(t) + c.x,
            radi * t * std::sin(t) + c.y,
            step * t + c.z
        };
    }
    virtual Vector3D curve_vector(double t) const override
    {
        return Vector3D
        {
            radi * (std::cos(t) - t * std::sin(t)),
            radi * (std::sin(t) + t * std::cos(t)),
            step
        };
    }
};
//===============================================================>
using PShape = std::shared_ptr<Shape3D>; // псевдоним типа - умный указатель на базовый класс
 
class Shape_generator   // генератор объектов - потомков Shape3D
{
    enum shape_t{ circle_t, ellipse_t, helix_t };   // типы генерируемых объектов
 
    static std::random_device rd;
 
    std::uniform_real_distribution<double> udd{ -1, 1 };    // генератор случайных вещественных чисел(ГСВЧ)
    std::uniform_int_distribution<> usd{ circle_t, helix_t };   // генератор случайных типов объектов
 
public:
 
    void set_diapason(double min, double max)   // если нужно изменить диапазон
    {
        if ((std::abs(max) + std::abs(min)) < 2 * eps)  // если значения диапазона одновременно слишко близки к нулю,
            return; // ничего не меняем
        udd = decltype(udd){ min, max }; // меняем параметры ГСВЧ
    }
 
    PShape circle()
    {   // метод генерирует и размещает в динамической памяти объект класса Circle3D
        // и возвращает умный указатель на базовый класс
        double radius{};
        while (radius < eps)    // проверяем, что бы радиус был не слишком маленьким
            radius = std::abs(udd(rd)); // и > 0
 
        return std::make_shared<Circle3D>(Point3D{ udd(rd), udd(rd) }, radius);
    }
 
    PShape ellipse()
    {   // метод генерирует и размещает в динамической памяти объект класса Ellipse3D
        // и возвращает умный указатель на базовый класс
        double radius_x{};
        while (radius_x < eps)  // проверяем, что бы первый радиус был не слишком маленьким
            radius_x = std::abs(udd(rd));   // и > 0
 
        double radius_y{};
        while (radius_y < eps)  // проверяем, что бы второй радиус был не слишком маленьким
            radius_y = std::abs(udd(rd));   // и > 0
 
        return std::make_shared<Ellipse3D>(Point3D{ udd(rd), udd(rd) }, radius_x, radius_y);
    }
 
    PShape helix()
    {   // метод генерирует и размещает в динамической памяти объект класса Helix3D
        // и возвращает умный указатель на базовый класс
        double radius{};
        while (radius < eps)    // проверяем, что бы радиус был не слишком маленьким
            radius = std::abs(udd(rd)); // и > 0
 
        double step{};
        while (std::abs(step) < eps)    // проверяем, что бы шаг был не слишком маленьким
            step = udd(rd);
 
        return std::make_shared<Helix3D>(Point3D{ udd(rd), udd(rd), udd(rd) }, radius, step);
    }
 
    PShape random_shape()
    {   // метод генерирует случайную фигуру из доступного набора
        switch (usd(rd))
        {
        case circle_t:
            return circle();
        case ellipse_t:
            return ellipse();
        case helix_t:
            return helix();
        default:
            return circle(); // мало ли что
        }
    }
};
//---------------------------------------------------------------
std::random_device Shape_generator::rd;
//===============================================================>
int main()
{
    constexpr size_t sz = 10;   // размер первого массива
    const double pi = std::acos(-1);    // пи****
    
    std::vector<PShape> shape_vec;  // массив указателей на объекты базового класса
 
    {
        Shape_generator s_gen;  // генератор
        s_gen.set_diapason(-10, 10);    // инициализируем диапазон
        for (size_t i{}; i < sz; ++i)
            shape_vec.emplace_back(s_gen.random_shape());   // заполняем массив
    }
    
    using PCircle = std::shared_ptr<Circle3D>;  // псевдоним типа - умный указатель на Circle3D
 
    std::vector<PCircle> circle_vec;    // массив указателей на Circle3D из первого контейнера
 
    double radius_sum{};    // сумма радиусов Circle3D
 
    for (auto& ps : shape_vec)
    {
        const std::type_info& ti{ typeid(*ps) };    // информация о типе объекта, на который указывает ps из первого контейнера
 
        std::cout << ti.name() << ' '   // выводим имя типа
                  << ps->curve_point(pi/4) << ' '   // точку кривой, заданную параметром
                  << ps->curve_vector(pi/4) << std::endl;   // вектор(первая производная - касательная) в предыдущей точке
 
        if (ti.hash_code() == typeid(Circle3D).hash_code()) // если текущий объект - указатель на Circle3D
        {
            circle_vec.emplace_back(std::dynamic_pointer_cast<Circle3D>(ps));   // кастим его к указателю на Circle3D
            radius_sum += circle_vec.back()->radius();  // плюсуем радиус
            std::cout << "to another vector -->\n"; // debug (можно удалить эту строку)
        }
        std::cout << std::endl;
    }
    std::sort(circle_vec.begin(), circle_vec.end(), [](const auto& lh, const auto& rh)  // сортируем по радиусу
    {
        return lh->radius() < rh->radius();
    });
 
    for (auto& pc : circle_vec) // демонстрируем отсортированное
        std::cout << pc->radius() << std::endl;
    std::cout << "sum = " << radius_sum << std::endl;   // и сумму радиусов всех Circle3D
}


Тут можно запустить:
https://rextester.com/DTQM11204
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.06.2019, 11:50
Помогаю со студенческими работами здесь

HELP!!! движение геометрических фигур
Нужна помощь в написании программы движения круга на экране хотя бы чтоб двигался туда сюда по одной линии, использование методов...

Иерархия геометрических фигур в ООП
Здравствуйте уважаемые формучани, нужна ваша помощь ибо я уже не знаю что делать. В общем задание построить иерархию геометрических фигур...

Вычисление площадей геометрических фигур
Программа на языке C++. Вводятся длины сторон прямоугольника, найти его площадь и периметр. Эта программа находит площадь и периметр....

Графика - построение геометрических фигур
Я что-то вообще не могу понять, как выполнять это задание. Считать данные не проблема, а как построить да ещё и с заданными углами...

Вывод на экран геометрических фигур
Дали курсач. Задание: разработать программу, обеспечивающую изображение на экране дисплея определенного набора плоских и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru