Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.79/29: Рейтинг темы: голосов - 29, средняя оценка - 4.79
0 / 0 / 0
Регистрация: 04.06.2019
Сообщений: 16

Динамическое изображение: астроида

04.06.2019, 23:28. Показов 6121. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Я написал код для рисования графика астроиды. Может кто-то поможет дописать код, чтобы астроида рисовалась постепенно (зайдите на Википедию, страница "Астроида", справа есть gif-изображение). Нужно точно так же. Был бы очень благодарен, если для кого-то это пустяки, а то я даже примерно не представляю, как это сделать. Код графика прилагаю.

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
void __fastcall TForm3::Button2Click(TObject *Sender)
{
double R, x, y, fn, fk, t;
int x0, y0, m;
 
x0=(Image1->Width)/2;
y0=(Image1->Height)/2;
x=-x0;
Image1->Canvas->Pen->Color = clBlack;
Image1->Canvas->MoveTo(x0, 30);
Image1->Canvas->LineTo(x0, 570);
Image1->Canvas->MoveTo(30, y0);
Image1->Canvas->LineTo(570, y0);
 
R = StrToFloat(Form3->Edit1->Text);
 
fn=0;
fk=2*(M_PI);
x=-x0;
t=fn;
 
while (t<=fk)
{
x = 25*R*cos(t)*cos(t)*cos(t);
y = 25*R*sin(t)*sin(t)*sin(t);
 
Image1->Canvas->Pixels[x0+round(x)][y0-round(y)] = clGreen;
t=t+0.001;
}   
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.06.2019, 23:28
Ответы с готовыми решениями:

динамическое изображение маятника
напишите программу которая выводит динамическое изображение маятника,совершающее горманическое колебания ф=Аsin(wt) ф-угол между вертикалью...

Астроида
Помогите построить Астроиду: x2/3+y2/3=R2/3

При нажатие на динамическое изображение оно должно меняться на другое
Доброе время суток ! У меня возникла такая проблема: не могу с своем скрипте реализовать функцию в которой при нажатие на...

30
Модератор
 Аватар для D1973
9909 / 6446 / 2455
Регистрация: 21.01.2014
Сообщений: 27,364
Записей в блоге: 3
05.06.2019, 06:38
Цитата Сообщение от Allekk Посмотреть сообщение
зайдите на Википедию, страница "Астроида"
Могли бы и ссылку выложить на нужную страницу - в конце концов - это Вам надо, а не кому-то там еще...
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
05.06.2019, 11:44
Лучший ответ Сообщение было отмечено Allekk как решение

Решение

Набирал прямо здесь, так что извиняй, если что не так - ошибки, если будут, поправишь...

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
#include <Math.hpp>
 
// ...
 
const int BigR = 400 / 2;
const int SmallR = 4 * BigR / 5;
const int Diff = BigR - SmallR;
TPoint pts[361];
 
int Angle;
 
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    TPoint pt = Point(50 + BigR, 50 + BigR);
    double rAngle = DegToRad(1.0*Angle);
    double r3Angle = DegToRad(-3.0*Angle);
 
    TRect R = Rect(50, 50, 50 + 2 * BigR, 50 + 2 * BigR);
    Canvas->Pen->Color = clBlack;
    Canvas->Brush->Color = clBtnFace;
    Canvas->Brush->Style = bsSolid;
    Canvas->Ellipse(R);
 
    int px = pt.x + (int)(SmallR * cos(rAngle));
    int py = pt.y - (int)(SmallR * sin(rAngle));
 
    int lx = px + (int)(Diff * cos(r3Angle));
    int ly = py - (int)(Diff * sin(r3Angle));
 
    Canvas->Pen->Color = clBlack;
    Canvas->Ellipse(Rect(px - Diff, py - Diff, px + Diff, py + Diff));
    Canvas->MoveTo(px, py);
    Canvas->LineTo(lx, ly);
 
    Canvas->Pen->Color = clRed;
    Canvas->Brush->Color = clRed;
    Canvas->Brush->Style = bsSolid;
    for(int i = 0; i < Angle; i++)
    {
        if(!i) Canvas->MoveTo(pts[i].x, pts[i].y);
        else Canvas->LineTo(pts[i].x, pts[i].y);
    }
    pts[Angle] = Point(lx, ly);
    Angle = (Angle + 1) % 360;
}
 
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    Angle = 0;
    Timer->Interval = 25;
}
2
0 / 0 / 0
Регистрация: 04.06.2019
Сообщений: 16
05.06.2019, 14:55  [ТС]
Спасибо огромнейшее тебе, очень помог, теперь буду разбираться и немного корректировать под свои нужды. Можно пару вопросов. Можно ли каждый раз менять размерность, а радиус R вводить самому в Edit? Какая переменная отвечает за радиус R? И можно ли сделать так, чтобы он рисовал не сразу при открытии формы, а при введении радиуса в Edit и нажатии на кнопку Button?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
05.06.2019, 15:07
Сделал на XE4:
Вложения
Тип файла: 7z Astroida.7z (60.5 Кб, 18 просмотров)
1
0 / 0 / 0
Регистрация: 04.06.2019
Сообщений: 16
05.06.2019, 16:07  [ТС]
volvo, а вы случайно не знаете, что нужно изменить здесь, чтобы он рисовал кардиоиду, циклоиду и конхоиду. До этого я пользовался параметрическими уравнениями прямо в коде и просто изменял их каждый раз, а тут не совсем понятна зависимость этих углов для построения фигур.

C++
1
2
double rAngle = DegToRad(1.0*Angle);
double r3Angle = DegToRad(-3.0*Angle);
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
05.06.2019, 17:36
Цитата Сообщение от Allekk Посмотреть сообщение
что нужно изменить здесь, чтобы он рисовал кардиоиду, циклоиду и конхоиду.
Здесь - все. Мой код рисует только астроиду, которая описывается точкой окружности радиуса r, катящейся по внутренней стороне окружности радиуса R. Глупо было бы думать, что достаточно изменить одну цифру, и будет рисоваться кривая, которая образуется другими способами.
0
0 / 0 / 0
Регистрация: 04.06.2019
Сообщений: 16
05.06.2019, 18:46  [ТС]
volvo, ну ладно, буду пробовать разбираться
0
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
08.06.2019, 10:40
Отобразить на форме анимацию графика циклоиды
0
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
09.06.2019, 16:10
Кардиоида:
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
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const a = 50;
double inc = 0, difX = 250, difY = 175;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
  Timer1->Enabled = 1;
  Timer1->Interval = 10;
}
//---------------------------------------------------------------------------
double X (double t)
{
  return a*(2*cos(t)-cos(2*t));
}
//---------------------------------------------------------------------------
double Y (double t)
{
  return a*(2*sin(t)-sin(2*t));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  Refresh();
  Canvas->Pen->Color = clBlack;
  Canvas->Ellipse(difX-a, difY-a, difX+a, difY+a);
//  Canvas->Pen->Color = clGreen;
  Canvas->Ellipse(difX-a+cos(inc)*2*a, difY-a-sin(inc)*2*a, difX+a+cos(inc)*2*a, difY+a-sin(inc)*2*a);
  Canvas->Pen->Color = clBlue;
  Canvas->MoveTo(difX+X(inc), difY-Y(inc));
  Canvas->LineTo(difX+cos(inc)*2*a, difY-sin(inc)*2*a);
  for (double i = 0; i <= inc; i += 0.01)
    Canvas->Pixels[X(i)+difX][difY-Y(i)] = clRed;
  inc += 0.01;
  if (inc > 2*M_PI)
    inc = 0;
}
//---------------------------------------------------------------------------


Конхоиду прямой [Никомеда] попробуй построить сам, используя параметрическое представление (http://know.sernam.ru/dict_math.php?id=518):
https://www.cyberforum.ru/cgi-bin/latex.cgi?x = a + l * cos(\phi)<br />
y = a * tg(\phi) + l * sin(\phi)
Если же нужна конхоида окружности (улитка Паскаля - https://ru.wikipedia.org/wiki/... 0%BB%D1%8F), то она строится подобно кардиоиде (с некоторой поправкой).
1
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
09.06.2019, 20:13
Гипоциклоида https://ru.wikipedia.org/wiki/... 0%B4%D0%B0 (при k = 4 получаем астроиду):
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
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const R = 200, r = 50;
double inc = 0, difX, difY, k = 1. * R / r;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
  Timer1->Enabled = 1;
  Timer1->Interval = 10;
  difX = ClientWidth / 2;
  difY = ClientHeight / 2;
}
//---------------------------------------------------------------------------
double X (double t)
{
  return r * (k - 1) * (cos(t) + cos((k - 1) * t) / (k - 1));
}
//---------------------------------------------------------------------------
double Y (double t)
{
  return r * (k - 1) * (sin(t) - sin((k - 1) * t) / (k - 1));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  Refresh();
  Canvas->Pen->Color = clBlack;
  Canvas->Ellipse(ClientWidth / 2 - R, ClientHeight / 2 - R, ClientWidth / 2 + R, ClientHeight / 2 + R);
  Canvas->Pen->Color = clGreen;
  Canvas->Ellipse(difX - r + cos(inc) * (R - r), difY - r - sin(inc) * (R - r), difX + r + cos(inc) * (R - r), difY + r - sin(inc) * (R - r));
  Canvas->Pen->Color = clBlue;
  Canvas->MoveTo(difX + X(inc), difY - Y(inc));
  Canvas->LineTo(difX + cos(inc) * (R - r), difY - sin(inc) * (R - r));
  for (double i = 0; i <= inc; i += 0.01)
    Canvas->Pixels[difX + X(i)][difY - Y(i)] = clRed;
  inc += 0.01;
  if (inc > 10*M_PI)
    inc = 0;
}
//---------------------------------------------------------------------------
Ниже варианты для k = 7/4, 7/2 и 9 соответственно.
Миниатюры
Динамическое изображение: астроида   Динамическое изображение: астроида   Динамическое изображение: астроида  

1
0 / 0 / 0
Регистрация: 04.06.2019
Сообщений: 16
10.06.2019, 20:48  [ТС]
gunslinger, спасибо огромнейшее) Ну тут уж более понятней, тут по параметрическому уравнению строится) А то в прошлой программе надо полгода разбираться, а у меня нет ни времени, ни желания. Я уже плюнул и в GeoGebra сделал по туториалам с YouTube. Но сдать ещё не успел. Тем более конхоиду Никомеда я там не нашёл. Может попробую всё-таки в билдере сделать заново всё, теперь желание загорелось)

Добавлено через 2 часа 34 минуты
gunslinger, я написал код системы координат. Вставляю код в таймер ниже вашего кода, тогда система координат моргает постоянно. Это логично, ведь там стоит Refresh()
Но как сделать так, чтобы система координат не моргала и оставалась неподвижной, а таймер рисовал изображение как обычно. Чтобы даже внутри неподвижной окружности система координат была видна тоже и не моргала тоже. Куда нужно вставить мой код? Уже пробовал разные варианты. И в кнопку, по нажатию которой активируется таймер, вставлял. Но тогда она вообще не видна. И в FormPaint, и в FormActivate, и в FormCreate, тоже ничего. И до вашего кода и Refresh(), тоже толку ноль.

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
void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
Refresh();
  PaintBox1->Canvas->Pen->Color = clBlack;
 // Canvas->Ellipse(difX-a, difY-a, difX+a, difY+a);
PaintBox1->Canvas->Ellipse(300-a, 300-a, 300+a, 300+a);
//  Canvas->Pen->Color = clGreen;
PaintBox1->Canvas->Ellipse(300-a+cos(inc)*2*a, 300-a-sin(inc)*2*a, 300+a+cos(inc)*2*a, 300+a-sin(inc)*2*a);
PaintBox1->Canvas->Pen->Color = clBlue;
PaintBox1->Canvas->MoveTo(300+X(inc), 300-Y(inc));
PaintBox1->Canvas->LineTo(300+cos(inc)*2*a, 300-sin(inc)*2*a);
  for (double i = 0; i <= inc; i += 0.01)
    PaintBox1->Canvas->Pixels[X(i)+300][300-Y(i)] = clRed;
  inc += 0.01;
  if (inc > 2*M_PI)
    inc = 0;
 
 
 
double R, x, y, fn, fk, t;
int x0, y0, m;
 
x0=(PaintBox1->Width)/2;
y0=(PaintBox1->Height)/2;
//x=-x0;
PaintBox1->Canvas->Pen->Color = clBlack;
PaintBox1->Canvas->MoveTo(x0, 30);
PaintBox1->Canvas->LineTo(x0, 570);
PaintBox1->Canvas->MoveTo(30, y0);
PaintBox1->Canvas->LineTo(570, y0);
 
PaintBox1->Canvas->MoveTo(40, 290);
PaintBox1->Canvas->LineTo(40, 310);
 
PaintBox1->Canvas->MoveTo(60, 290);
PaintBox1->Canvas->LineTo(60, 310);
 
PaintBox1->Canvas->MoveTo(80, 290);
PaintBox1->Canvas->LineTo(80, 310);
 
PaintBox1->Canvas->MoveTo(100, 290);
PaintBox1->Canvas->LineTo(100, 310);
 
PaintBox1->Canvas->MoveTo(120, 290);
PaintBox1->Canvas->LineTo(120, 310);
 
PaintBox1->Canvas->MoveTo(140, 290);
PaintBox1->Canvas->LineTo(140, 310);
 
PaintBox1->Canvas->MoveTo(160, 290);
PaintBox1->Canvas->LineTo(160, 310);
 
PaintBox1->Canvas->MoveTo(180, 290);
PaintBox1->Canvas->LineTo(180, 310);
 
PaintBox1->Canvas->MoveTo(200, 290);
PaintBox1->Canvas->LineTo(200, 310);
 
PaintBox1->Canvas->MoveTo(220, 290);
PaintBox1->Canvas->LineTo(220, 310);
 
PaintBox1->Canvas->MoveTo(240, 290);
PaintBox1->Canvas->LineTo(240, 310);
 
PaintBox1->Canvas->MoveTo(260, 290);
PaintBox1->Canvas->LineTo(260, 310);
 
PaintBox1->Canvas->MoveTo(280, 290);
PaintBox1->Canvas->LineTo(280, 310);
 
PaintBox1->Canvas->MoveTo(320, 290);
PaintBox1->Canvas->LineTo(320, 310);
 
PaintBox1->Canvas->MoveTo(340, 290);
PaintBox1->Canvas->LineTo(340, 310);
 
PaintBox1->Canvas->MoveTo(360, 290);
PaintBox1->Canvas->LineTo(360, 310);
 
PaintBox1->Canvas->MoveTo(380, 290);
PaintBox1->Canvas->LineTo(380, 310);
 
PaintBox1->Canvas->MoveTo(400, 290);
PaintBox1->Canvas->LineTo(400, 310);
 
PaintBox1->Canvas->MoveTo(420, 290);
PaintBox1->Canvas->LineTo(420, 310);
 
PaintBox1->Canvas->MoveTo(440, 290);
PaintBox1->Canvas->LineTo(440, 310);
 
PaintBox1->Canvas->MoveTo(460, 290);
PaintBox1->Canvas->LineTo(460, 310);
 
PaintBox1->Canvas->MoveTo(480, 290);
PaintBox1->Canvas->LineTo(480, 310);
 
PaintBox1->Canvas->MoveTo(500, 290);
PaintBox1->Canvas->LineTo(500, 310);
 
PaintBox1->Canvas->MoveTo(520, 290);
PaintBox1->Canvas->LineTo(520, 310);
 
PaintBox1->Canvas->MoveTo(540, 290);
PaintBox1->Canvas->LineTo(540, 310);
 
PaintBox1->Canvas->MoveTo(560, 290);
PaintBox1->Canvas->LineTo(560, 310);
 
PaintBox1->Canvas->MoveTo(290, 40);
PaintBox1->Canvas->LineTo(310, 40);
 
 
 
 
 
}
//---------------------------------------------------------------------------
0
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
10.06.2019, 21:26
Про моргания я в курсе (мой код лишь набросок). Чтобы это как-то минимизировать, перерисовывать нужно не всю получающуюся кривую, а просто добавлять точки на "незатираемой" канве того же PaintBox-а и перерисовывать радиус-вектор. А движущуюся окружность рисовать не на канве, а использовать объект Shape и двигать его.
Когда кривая начинает повторяться, обновлять (затирать) изображение (и потом рисовать его снова). Например, очищать можно так (для Image; для PaintBox аналогично):
C++
1
  Image1->Canvas->FillRect(Image1->Canvas->ClipRect);
И систему координат можно рисовать в цикле, перерисовывая при необходимости.
Пример сетки:
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
  // рисуем оси
  Canvas->Pen->Color = clBlack;
  // ось X
  Canvas->MoveTo(Image->Left, Image->Top + Image->Height + dif);
  Canvas->LineTo(Image->Left + Image->Width, Image->Top + Image->Height + dif);
  for (int i = 0; i <= Image->Width; i += step)
  {
    Canvas->MoveTo(Image->Left + i, Image->Top + Image->Height + dif);
    Canvas->LineTo(Image->Left + i, Image->Top + Image->Height + 2*dif);
    Canvas->TextOut(Image->Left + i - dif, Image->Top + Image->Height + 2*dif, int(i * f * maxX / Image->Width));
  }
  // ось Y
  Canvas->MoveTo(Image->Left - dif, Image->Top);
  Canvas->LineTo(Image->Left - dif, Image->Top + Image->Height);
  for (int i = 0; i <= Image->Height; i += step)
  {
    Canvas->MoveTo(Image->Left - dif, Image->Top + i);
    Canvas->LineTo(Image->Left - 2*dif, Image->Top + i);
    Canvas->TextOut(Image->Left - 7*dif, Image->Top + i - dif, int((Image->Height / 2 - i) * f * maxY / (Image->Height / 2)));
  }
 
  Image->Canvas->FillRect(Image->Canvas->ClipRect);  // очищаем Image
 
  // строим сетку
  Image->Canvas->Pen->Color = clGreen;
  Image->Canvas->Pen->Width = 1;
  for (float a = 0; a <= Image->Width; a += Image->Width * 1.0 / scaleA)
  {
    // вертикальные линии
    Image->Canvas->MoveTo(a, 0);
    Image->Canvas->LineTo(a, Image->Height);
  }
  for (float b = 0; b <= Image->Height; b += Image->Height * 1.0 / scaleB)
  {
    // горизонтальные линии
    Image->Canvas->MoveTo(0, b);
    Image->Canvas->LineTo(Image->Width, b);
  }
 
  // горизонтальная линия (ноль по оси Y)
  Image->Canvas->Pen->Color = clBlack;
  Image->Canvas->MoveTo(0, Image->Height/2);
  Image->Canvas->LineTo(Image->Width, Image->Height/2);
Миниатюры
Динамическое изображение: астроида  
0
0 / 0 / 0
Регистрация: 04.06.2019
Сообщений: 16
10.06.2019, 23:21  [ТС]
gunslinger, ещё у вас код циклоиды немного неправильный. Он не рисует циклоиду, а рисует прямую линию. Окружность не катится по прямой, а просто плывёт.

Кликните здесь для просмотра всего текста
https://www.cyberforum.ru/attachment.php?attachmentid=1047193&stc= 1&d=1560192612


Добавлено через 1 час 30 минут
gunslinger, отбой, это я тупанул, забыл Math.hpp подключить
0
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
10.06.2019, 23:24
Нормально там рисуется.
А насчет решения проблемы мерцания (только в конце точки затираются линией, нужно подумать, как исправить):
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const a = 50;
double inc = 0, difX = 225, difY = 225, step = 0.01;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
  Timer1->Enabled = 1;
  Timer1->Interval = 10;
  Shape->Width = 2 * a;
  Shape->Shape = stCircle;
  Shape->Brush->Style = bsClear;
  Shape->Pen->Color = clGreen;
  Shape->BringToFront();
  Image->Canvas->Pen->Mode = pmCopy;
}
//---------------------------------------------------------------------------
double X (double t)
{
  return a*(2*cos(t)-cos(2*t));
}
//---------------------------------------------------------------------------
double Y (double t)
{
  return a*(2*sin(t)-sin(2*t));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
//  Refresh();
  Image->Canvas->Pen->Color = clBlack;
  Image->Canvas->Ellipse(difX-a, difY-a, difX+a, difY+a);
//  Canvas->Pen->Color = clGreen;
//  Canvas->Ellipse(difX-a+cos(inc)*2*a, difY-a-sin(inc)*2*a, difX+a+cos(inc)*2*a, difY+a-sin(inc)*2*a);
  Shape->Left = difX-a+cos(inc)*2*a;
  Shape->Top = difY-a-sin(inc)*2*a;
 
  Image->Canvas->Pen->Color = clWhite;
  Image->Canvas->MoveTo(difX+X(inc-step), difY-Y(inc-step));
  Image->Canvas->LineTo(difX+cos(inc-step)*2*a, difY-sin(inc-step)*2*a);
 
  Image->Canvas->Pen->Color = clBlue;
  Image->Canvas->MoveTo(difX+X(inc), difY-Y(inc));
  Image->Canvas->LineTo(difX+cos(inc)*2*a, difY-sin(inc)*2*a);
 
//  for (double i = 0; i <= inc; i += step)
  Image->Canvas->Pixels[X(inc-step)+difX][difY-Y(inc-step)] = clRed;
  inc += step;
  if (inc > 2*M_PI)
  {
    inc = 0;
    Image->Canvas->FillRect(Image->Canvas->ClipRect);
  }
}
//---------------------------------------------------------------------------
0
0 / 0 / 0
Регистрация: 04.06.2019
Сообщений: 16
11.06.2019, 00:45  [ТС]
Круто. Я ещё попробовал интервал увеличить. Немного помогло, почти не моргает.
А для эпициклоиды поможете пару значений поменять в коде в таймере. Сам код уже я подкорректировал уже. Вот он.

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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <Math.hpp>
#pragma hdrstop
 
#include "Unit8.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm8 *Form8;
int R, r;
double inc = 0, difX, difY, k;
//---------------------------------------------------------------------------
__fastcall TForm8::TForm8(TComponent* Owner)
    : TForm(Owner)
{
Timer1->Enabled = 1;
Timer1->Interval = 10;
difX = ClientWidth / 2;
difY = ClientHeight / 2;
}
//---------------------------------------------------------------------------
double X (double t)
{
  return r * (k + 1) * (cos(t) - cos((k + 1) * t) / (k + 1));
}
//---------------------------------------------------------------------------
double Y (double t)
{
  return r * (k + 1) * (sin(t) - sin((k + 1) * t) / (k + 1));
}
//---------------------------------------------------------------------------
void __fastcall TForm8::Button1Click(TObject *Sender)
{
r = StrToFloat(Edit1->Text);
R = StrToFloat(Edit2->Text);
k = StrToFloat(Edit3->Text);
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm8::Timer1Timer(TObject *Sender)
{
  Refresh();
  PaintBox1->Canvas->Pen->Color = clBlack;
  PaintBox1->Canvas->Ellipse(ClientWidth / 2 - R, ClientHeight / 2 - R, ClientWidth / 2 + R, ClientHeight / 2 + R);
  PaintBox1->Canvas->Pen->Color = clBlack;
  PaintBox1->Canvas->Ellipse(difX - R + cos(inc) * (R), difY - R - sin(inc) * (R), difX + R + cos(inc) * (R), difY + R - sin(inc) * (R));
  PaintBox1->Canvas->Pen->Color = clBlue;
  PaintBox1->Canvas->MoveTo(difX + X(inc), difY - Y(inc));
  PaintBox1->Canvas->LineTo(difX - cos(inc) * (R), difY - sin(inc) * (R));
  for (double i = 0; i <= inc; i += 0.01)
    PaintBox1->Canvas->Pixels[difX + X(i)][difY - Y(i)] = clRed;
  inc += 0.01;
  if (inc > 10*M_PI)
    inc = 0;
}
//---------------------------------------------------------------------------
И на конхоиду. Там должно по отрезку вроде быть. Тоже в таймере нужно.

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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <Math.hpp>
#pragma hdrstop
 
#include "Unit7.h"
#include "winuser.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm7 *Form7;
 
int a, l;
double inc = 0;
//---------------------------------------------------------------------------
__fastcall TForm7::TForm7(TComponent* Owner)
    : TForm(Owner)
{
Timer1->Interval = 40;
}
//---------------------------------------------------------------------------
double X (double t)
{
   return a + l * cos(t);
}
//---------------------------------------------------------------------------
double Y (double t)
{
  return a * tan(t) + l * sin(t);
}
//---------------------------------------------------------------------------
void __fastcall TForm7::Button1Click(TObject *Sender)
{
a = StrToFloat(Edit1->Text);
l = StrToFloat(Edit2->Text);
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm7::Timer1Timer(TObject *Sender)
{
Refresh();
Form7->DoubleBuffered=true;
PaintBox1->Canvas->Pen->Color = clBlack;
PaintBox1->Canvas->Ellipse(300 - R, 300 - R, 300 + R, 300 + R);
PaintBox1->Canvas->Pen->Color = clBlack;
PaintBox1->Canvas->Ellipse(300 - r + cos(inc) * (R - r), 300 - r - sin(inc) * (R - r), 300 + r + cos(inc) * (R - r), 300 + r - sin(inc) * (R - r));
PaintBox1->Canvas->Pen->Color = clBlue;
PaintBox1->Canvas->MoveTo(300 + X(inc), 300 - Y(inc));
PaintBox1->Canvas->LineTo(300 + cos(inc) * (R - r), 300 - sin(inc) * (R - r));
for (double i = 0; i <= inc; i += 0.01)
PaintBox1->Canvas->Pixels[300 + X(i)][300 - Y(i)] = clRed;
inc += 0.01;
if (inc > 2*M_PI)
inc = 0;
//---------------------------------------------------------------------------
Изображения
 
0
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
11.06.2019, 12:47
Ты все равно идешь своим путем... Как знаешь...
Тем не менее, подправил код, кардиоида не мерцает и рисуется полностью:
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const a = 50;
double inc = 0, difX = 225, difY = 225, step = 0.01;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
  Timer1->Enabled = 1;
  Timer1->Interval = 10;
  Shape->Width = 2 * a;
  Shape->Shape = stCircle;
  Shape->Brush->Style = bsClear;
  Shape->Pen->Color = clGreen;
  Shape->BringToFront();
}
//---------------------------------------------------------------------------
double X (double t)
{
  return a*(2*cos(t)-cos(2*t));
}
//---------------------------------------------------------------------------
double Y (double t)
{
  return a*(2*sin(t)-sin(2*t));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
//  Refresh();
  Image->Canvas->Pen->Color = clBlack;
  Image->Canvas->Ellipse(difX-a, difY-a, difX+a, difY+a);
//  Canvas->Pen->Color = clGreen;
//  Canvas->Ellipse(difX-a+cos(inc)*2*a, difY-a-sin(inc)*2*a, difX+a+cos(inc)*2*a, difY+a-sin(inc)*2*a);
  Shape->Left = difX-a+cos(inc)*2*a;
  Shape->Top = difY-a-sin(inc)*2*a;
 
  Image->Canvas->Pen->Color = clWhite;
  Image->Canvas->MoveTo(difX+X(inc-step), difY-Y(inc-step));
  Image->Canvas->LineTo(difX+cos(inc-step)*2*a, difY-sin(inc-step)*2*a);
 
  Image->Canvas->Pen->Color = clBlue;
  Image->Canvas->MoveTo(difX+X(inc), difY-Y(inc));
  Image->Canvas->LineTo(difX+cos(inc)*2*a, difY-sin(inc)*2*a);
 
  for (double i = 0; i <= inc; i += step)
    Image->Canvas->Pixels[X(i)+difX][difY-Y(i)] = clRed;
  inc += step;
  if (inc > 2*M_PI)
  {
    inc = 0;
    Image->Canvas->FillRect(Image->Canvas->ClipRect);
  }
}
//---------------------------------------------------------------------------
Эпициклоиду можно построить подобно гипоциклоиде на основе кода кардиоиды (и то, и другое уже имеется).
Нужно включить немного мозги. Достаточно понимания простейшей геометрии и тригонометрии.
попробуй сам прийти к подобному коду

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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const R = 100, r = 40;
double inc = 0, difX, difY, step = 0.01, k = 1. * R / r;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
  Timer1->Enabled = 1;
  Timer1->Interval = 10;
  Shape->Width = 2 * r;
  Shape->Height = 2 * r;
  Shape->Shape = stCircle;
  Shape->Brush->Style = bsClear;
  Shape->Pen->Color = clGreen;
  Shape->BringToFront();
  difX = ClientWidth / 2;
  difY = ClientHeight / 2;
}
//---------------------------------------------------------------------------
double X (double t)
{
  return r * (k + 1) * (cos(t) - cos((k + 1) * t) / (k + 1));
}
//---------------------------------------------------------------------------
double Y (double t)
{
  return r * (k + 1) * (sin(t) - sin((k + 1) * t) / (k + 1));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  Image->Canvas->Pen->Color = clBlack;
  Image->Canvas->Ellipse(difX - R, difY - R, difX + R, difY + R);
 
  Shape->Left = difX - r + cos(inc) * (R + r);
  Shape->Top = difY - r - sin(inc) * (R + r);
 
  Image->Canvas->Pen->Color = clWhite;
  Image->Canvas->MoveTo(difX + X(inc - step), difY - Y(inc - step));
  Image->Canvas->LineTo(difX + cos(inc - step) * (R + r), difY - sin(inc - step) * (R + r));
 
  Image->Canvas->Pen->Color = clBlue;
  Image->Canvas->MoveTo(difX + X(inc), difY - Y(inc));
  Image->Canvas->LineTo(difX + cos(inc) * (R + r), difY - sin(inc) * (R + r));
 
  for (double i = 0; i <= inc; i += step)
    Image->Canvas->Pixels[X(i) + difX][difY - Y(i)] = clRed;
  inc += step;
  if (inc > 20 * M_PI)
  {
    inc = 0;
    Image->Canvas->FillRect(Image->Canvas->ClipRect);
  }
}
//---------------------------------------------------------------------------


[Вангую] Следующим этапом тебе понадобится какая-нибудь [эпи] [гипо] трохоида? А потом еще что-нибудь?
Я, конечно, люблю "всякую ерунду" с помощью билдера рисовать, но стараюсь (не всегда успешно, к сожалению) этим сильно не злоупотреблять (когда нет спортивного интереса, делать полностью за других мне уже не так сильно хочется, как раньше).

А для твоей конхоиды, скорей всего, нужен другой поход. Насчет отрезка не знаю, еще по этому поводу не думал.
0
place status here
 Аватар для gunslinger
3186 / 2220 / 640
Регистрация: 20.07.2013
Сообщений: 6,013
11.06.2019, 14:01
В качестве примера: Построение конхоиды Никомеда по параметрическому представлению.
0
0 / 0 / 0
Регистрация: 04.06.2019
Сообщений: 16
11.06.2019, 19:01  [ТС]
gunslinger, нет, больше ничего не надо, к счастью. Всего 5 кривых надо. Спасибо большое ещё раз, вы мне очень помогли, я в принципе красиво оформил уже астроиду, кардиоиду и циклоиду, осталось только динамическое изображение эпициклоиды и конхоиды. Эпициклоиду сейчас я сделаю, осталась конхоида, надо её динамически как-то нарисовать.

P.S. Забавный факт, если делать одну программу (одно exe-приложение) с выбором кривой по кнопке на главной форме и переходом на другие формы, то астроида рисуется нормально, а вот кардиоида и циклоида не рисуются, а на форме происходит какая-то ерунда. Отрезки просто тянутся, кривые не рисуются. Но если делать отдельный проект для каждой кривой (для каждой кривой своё exe-приложение), то кривые рисуются нормально и как положено. Код везде абсолютно одинаковый, проверял несколько раз каждый символ в коде. Даже не знаю, с чем это может быть связано. Но я сделал разные приложения для каждой кривой, мне по сути не принципиально. Просто привык уже к первому варианту, а тут так получилось забавно. Хорошо, что додумался отдельно проверить, создав новый проект.
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
11.06.2019, 20:22
Цитата Сообщение от Allekk Посмотреть сообщение
на форме происходит какая-то ерунда
Возможно вы не учитываете того, что канва хранит все прививки свойств, поэтому выбор по кнопке (без приведения состояния канвы к "девственному") может дать свои эффекты, отличные от ожидаемых.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.06.2019, 20:22
Помогаю со студенческими работами здесь

Кривая астроида
помогите кто сможет: 1. Кривая астроида определяется следующим уравнением в параметрической форме: x=Rcos^3(φ),...

Напишите программу, которая выводит динамическое изображение маятника, совершающего колебания
Напишите программу, которая выводит динамическое изображение маятника, совершающего колебания Помогите срочно....

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

Opengl, Астроида (c++, delphi)
Всем доброго времени суток, такой вопрос, как можно нарисовать астроиду в opengl: x = {cos}^{3}(t) y = {sin}^{3}(t) в делфи...

График функции ”Астроида”
Что за линия и как её убрать? Помогите пожалуйста. procedure TForm1.Button1Click(Sender: TObject); const mash=100; Var r :...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru