Форум программистов, компьютерный форум, киберфорум
C++/CLI Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 11.06.2016
Сообщений: 4

Сжатие графика косинуса

11.06.2016, 15:53. Показов 1201. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Итак, мне нужно было сделать программу на форме, рисующую график функции 2х переменных, выбор пал на косинус f(a,x)=a*cos(x), параметр a вводится пользователем в textBox. Программа работает, график рисуется, однако при a>1 график "вылезает" за форму. Как сделать так, чтобы максимальное значение функции всегда оставалось на форме, а график лишь сужался по оси OY? Помогите пожалуйста.

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
#pragma once
#include <math.h>
#define M_PI       3.14159265358979323846
 
namespace Проект1 {
 
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
 
    /// <summary>
    /// Сводка для MyForm
    /// </summary>
    public ref class MyForm : public System::Windows::Forms::Form
    {
    public:
        MyForm(void)
        {
            InitializeComponent();
            //
            //TODO: добавьте код конструктора
            //
            p = gcnew array <Point>(500);
        }
 
    protected:
        /// <summary>
        /// Освободить все используемые ресурсы.
        /// </summary>
        ~MyForm()
        {
            if (components)
            {
                delete components;
            }
        }
 
    protected:
    private: System::Windows::Forms::TextBox^  textBox1;
    private: System::Windows::Forms::Label^  label1;
 
 
 
 
 
 
 
 
    protected:
 
    private:
        /// <summary>
        /// Обязательная переменная конструктора.
        /// </summary>
        System::ComponentModel::Container ^components;
 
#pragma region Windows Form Designer generated code
        /// <summary>
        /// Требуемый метод для поддержки конструктора — не изменяйте 
        /// содержимое этого метода с помощью редактора кода.
        /// </summary>
        void InitializeComponent(void)
        {
            this->textBox1 = (gcnew System::Windows::Forms::TextBox());
            this->label1 = (gcnew System::Windows::Forms::Label());
            this->SuspendLayout();
            // 
            // textBox1
            // 
            this->textBox1->Location = System::Drawing::Point(627, 25);
            this->textBox1->Multiline = true;
            this->textBox1->Name = L"textBox1";
            this->textBox1->Size = System::Drawing::Size(141, 20);
            this->textBox1->TabIndex = 1;
            this->textBox1->TextChanged += gcnew System::EventHandler(this, &MyForm::MyForm_Resize);
            this->textBox1->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &MyForm::textBox1_KeyPress);
            // 
            // label1
            // 
            this->label1->AutoSize = true;
            this->label1->Location = System::Drawing::Point(624, 9);
            this->label1->Name = L"label1";
            this->label1->Size = System::Drawing::Size(169, 13);
            this->label1->TabIndex = 2;
            this->label1->Text = L"Введите значение параметра а:";
            // 
            // MyForm
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(815, 535);
            this->Controls->Add(this->label1);
            this->Controls->Add(this->textBox1);
            this->MaximumSize = System::Drawing::Size(831, 574);
            this->MinimumSize = System::Drawing::Size(831, 574);
            this->Name = L"MyForm";
            this->Text = L"График функции f(a,x)=a*cos(x)";
            this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &MyForm::MyForm_Paint);
            this->Resize += gcnew System::EventHandler(this, &MyForm::MyForm_Resize);
            this->ResumeLayout(false);
            this->PerformLayout();
 
        }
#pragma endregion
    private: array <Point> ^p;
    private: System::Void textBox1_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) {
        if (Char::IsControl(e->KeyChar))
            return;
        if (textBox1->Text->Length >= 4)
        {
            e->Handled = true;
            return;
        }
        if (e->KeyChar == '.')  e->KeyChar = ',';
 
        if (e->KeyChar == ',')
        {
            if ((((TextBox^)sender)->Text->IndexOf(',') != -1) || (((TextBox^)sender)->Text->Length == 0))
                e->Handled = true;
            return;
        }
        if (Char::IsDigit(e->KeyChar))
            return;
        e->Handled = true;
    }
    private: System::Void MyForm_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
        System::Drawing::Graphics^ g = e->Graphics;
        System::Drawing::Font ^hFont = gcnew System::Drawing::Font("Arial", 17, FontStyle::Regular);                    ("Tahoma", 14, FontStyle::Regular);
        
        int sx = 0, sy = 0; //Поля области
        int W = this->ClientSize.Width; //Ширина 
        int H = this->ClientSize.Height; //Высота 
 
        
                                             
        int prev_x = 0;
        int prev_yc = 0;
        double a;
        
        if (textBox1->Text->Length != 0)
            a = Convert::ToDouble(textBox1->Text);
        else a=1;
        
        int s = 10; //Разметка 
 
        g->FillRectangle(System::Drawing::Brushes::White, sx, sy / 2, W - 2 * sx, H); 
        for (int i = 0; i < H; i += s)
            g->DrawLine(Pens::LightBlue, sx, i + sy / 2, W - sx, i + sy / 2); // В
        for (int j = 0; j < W - 2 * sx; j += s)
            g->DrawLine(Pens::LightBlue, sx + j, sy / 2, sx + j, H + sy / 2);  // Г
        for (int k = 0; k <= W - 2; k++)
        {
            double X = k * 4 * M_PI / W;
            double Y = a*cos(X); 
            double py = H - (Y + 1)*(H / 2); 
            g->DrawLine(Pens::Blue, prev_x, prev_yc, k, py);
            prev_x = k;
            prev_yc = py;
        }
    }
    private: System::Void MyForm_Resize(System::Object^  sender, System::EventArgs^  e) {
        if (textBox1->Text->Length != 0)
            if (Convert::ToDouble(textBox1->Text) != 0)
                this->Refresh();
    }
};
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.06.2016, 15:53
Ответы с готовыми решениями:

Расчёт косинуса угла по значению в градусах
Добрый день! Как сделать так, чтобы вводить значение угла в градусах, и программа будет считать косинус?

Создание графика косинуса
Создание графика косинуса

Построение графика косинуса
Здравствуйте, уважаемые форумчане. Помогите, пожалуйста, решить проблему. Пытаюсь построить график косинуса по формуле cos(2*pi*f*t+fi)....

7
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
11.06.2016, 17:20
Делаете два массива: расчет, график.
Расчет:
В массив “расчет” считаете координаты точек для графика X,Y от формулы.
Находите в этом массиве max в X, max в Y.
График:
Теперь создаете пропорцию 100% это ваш maxX, пересчитываете всем X значениям из “расчет” координаты в процентах и находите координаты точки для рисования зная пределы поля рисования. Тоже для Y с maxY.
В итоге любой график будет входить в пределы поля рисования.
0
0 / 0 / 0
Регистрация: 11.06.2016
Сообщений: 4
11.06.2016, 19:32  [ТС]
А зачем создавать массив? Нельзя просто найти максимум, перед прорисовкой графика?
И не совсем понятно с "пересчетом" в процентах, можете по-подробнее объяснить?
0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
11.06.2016, 19:48
Цитата Сообщение от pokem Посмотреть сообщение
Нельзя просто найти максимум, перед прорисовкой графика?
Если известен. Обычно так не бывает.
Цитата Сообщение от pokem Посмотреть сообщение
не совсем понятно с "пересчетом" в процентах
Проценты нужны чтобы график попадал в пределы окна графики и занимал всю его область.
0
0 / 0 / 0
Регистрация: 11.06.2016
Сообщений: 4
11.06.2016, 20:34  [ТС]
Подскажите, что не так. Вроде сначала вводится параметр a, просчитываю в цикле максимумы и минимумы (минимумы не нужны, потом удалю), потом в другом цикле просчитываю соотношение от максимума Х, дальше вроде как по У
Извините, если вопросы совсем тупые.
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
private: System::Void MyForm_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
        System::Drawing::Graphics^ g = e->Graphics;
        System::Drawing::Font ^hFont = gcnew System::Drawing::Font("Arial", 17, FontStyle::Regular);                    ("Tahoma", 14, FontStyle::Regular);
        
        int sx = 0, sy = 0; //Поля области
        int W = this->ClientSize.Width; //Ширина 
        int H = this->ClientSize.Height; //Высота 
 
        
                                             
        int prev_x = 0;
        int prev_yc = 0;
        double a;
        
        if (textBox1->Text->Length != 0)
            a = Convert::ToDouble(textBox1->Text);
        else a=1;
        
        int s = 10; //Разметка 
 
        g->FillRectangle(System::Drawing::Brushes::White, sx, sy / 2, W - 2 * sx, H); 
        for (int i = 0; i < H; i += s)
            g->DrawLine(Pens::LightBlue, sx, i + sy / 2, W - sx, i + sy / 2); // В
        for (int j = 0; j < W - 2 * sx; j += s)
            g->DrawLine(Pens::LightBlue, sx + j, sy / 2, sx + j, H + sy / 2);  // Г
        double maxX = -9999;
        double minX = 9999;
        double minY = 9999;
        double maxY = -9999;
        for (int k = 0; k <= W - 2; k++)
        {
            double X = k * 4 * M_PI / W;
            double Y = a*cos(X);
            if (X < minX)
                minX = X;
            if (X > maxX)
                maxX = X;
            if (Y > maxY)
                maxY = Y;
            if (Y < minY)
                minY = Y;
        }
        double prc, finprc;
        for (int k = 0; k <= W - 2; k++)
        {
            double X = k * 4 * M_PI / W;
            prc = maxX / 100;
            double Y = a*cos(X); 
            finprc =( Y / prc ) / 100;
            double py = H - (Y + 1)*(H / 2);
            py = py*finprc;
            g->DrawLine(Pens::Blue, prev_x, prev_yc, k, py);
            prev_x = k;
            prev_yc = py;
        }
    }
    private: System::Void MyForm_Resize(System::Object^  sender, System::EventArgs^  e) {
        if (textBox1->Text->Length != 0)
            if (Convert::ToDouble(textBox1->Text) != 0)
                this->Refresh();
    }
};
}
0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
11.06.2016, 20:40
Могу только посоветовать выводить переменные например в консоль и смотреть их, давно не кодил =).
Вот в общем идея такя:
Формула возвращает например неизвестные числа. Нужно чтобы максимальное число которое она вернет попадало в интервал доступных координат рисования. Поэтому нужно найти\взять макс значение и найти ему координаты на форме рисования.
Например maxY из всех значений массива в формуле 750, найти координаты для числа 356 доступны координаты от 0 до 230 рисования.
750 это 100% значит 356 это: (356*100)/750= 47,6 %
Теперь находим координаты для графика от 0 до 230.Нужны 47,6 %
Значит y=(47,6*230)/100=109.
0
0 / 0 / 0
Регистрация: 11.06.2016
Сообщений: 4
12.06.2016, 11:03  [ТС]
Принцип понятен, а вот с реализацией проблемы. Может кто-нибудь укажет на ошибки в коде, хотя бы какую строчку менять надо.
0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
12.06.2016, 12:48
Это и есть 90% времени программирования на начальных этапах– отладка =)).
Сохраните код в другом месте, уберите все строки до минимум функционала, будет работать правильно добавите код, гляньте что находит в цикле. Я выводил в консоль значения проверяемых переменных, контролировал в циклах, сколько входов в цикл, что на выходе и т.д. Постепенно найдете ошибку.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
12.06.2016, 12:48
Помогаю со студенческими работами здесь

Сжатие звука с потерями и обратно (или иное сжатие с потерями)
Доброго всем времени суток. Столкнулся с такой проблемой, есть канал связи с маленькой скоростью на одном конце SDR приемник (дает...

Закон косинуса
Всем доброго времени суток. Вопрос скорее простой, но в гугле я так и не смог найти примеров реализации переменной, которая с течением...

Вычисление косинуса
Всем здраствуйте! Я делаю пп функцию которая расчитывает косинус, и сравнивает с стандартной функцией косинуса паскаля, вроде все сделал,...

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

Таблица косинуса
Не могу разобраться. Кто понимает о чем здесь речь - отзовитесь.


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru