C #. Программа рисования графика функции двух переменных z = f (x, y)

  1. Разработка программы рисования графика функции двух переменных z = f (x, y) В работе описывается...

Разработка программы рисования графика функции двух переменных z = f (x, y)

В работе описывается разработка программы построения графика функции двух переменных

z = f (x, y)

или 3D графика.

В качестве примера, выбрано функцию

z = sin (x) + cos (y)

Используя данный пример, можно создавать собственные программы для построения графиков других функций.

содержание

Условие задачи

Задано формулу функции двух переменных z = sin (x) + cos (y). Разработать приложение, которое рисует график этой функции в отдельной форме.

Дополнительно реализовать поворот графику влево, вправо, вверх, вниз. Также нужно выводить оси OX, OY, OZ.

Математическая постановка задачи

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

График функции двух переменных z (x, y) строится в параллелепипеде с размерами (xx1, xx2), (yy1, yy2), (zz1, zz2).

Для использования поворота системы в 3-мерном пространстве возникает понятие точки (x0, y0, z0), относительно которой происходит поворот системы координат.

Также возникает понятие углов:

Оползень в точку (x0, y0, z0) с учетом поворота на углы Оползень в точку (x0, y0, z0) с учетом поворота на углы   и   описывается известными соотношениями и описывается известными соотношениями

После перемножения матриц получаем формулу для вычисления:

По этой формуле будет происходить преобразование системы координат и масштабирование (рисунок 1).

Рис. 1. Смещение и поворот системы координат

Необходимо определиться, в какой плоскости монитора будут лежать оси координат OX, OY, OZ. Принимаем, что в плоскости монитора лежат оси OX и OY. А вот OZ перпендикулярна экрану.

Координаты рассчитываемый точки (x, y) прижимаются к точке (0, 0) по формулам:

где A, a - коэффициенты перспективы, которые подбираются экспериментально в зависимости от функции.

выполнение

1. Создать проект как Windows Forms Application

Создать проект как Windows Forms Application. Детальный пример создания проекта по шаблону Windows Forms Application описывается здесь . Автоматически создается главная форма программы с именем Form1. Имя исходного модуля основной формы "Form1.cs".

2. Построение формы Form 1.

Создать форму по образцу, как показано на рисунке 2.

Рис. 2. Показать основной формы программы

Настроить такие свойства компонент и формы:

  • в форме Form1 свойство Text = "График функции двух переменных";
  • в форме Form1 свойство MaximizeBox = False;
  • в форме Form1 свойство StartPosition = "CenterScreen";
  • в компоненте button1 свойство Text = "Показать график функции ...".

3. Создание формы Form2.

Создать новую форму. Детальный процесс создания новой формы описывается здесь .

Имена файлов формы "Form2.cs" и "Form2.Designer.cs".

Разместить на форме четыре компонента типа Button. Автоматически создается четыре объекта с именами button1, button2, button3, button4.

Настроить свойства компонент и формы следующим образом:

  • в форме Form2 свойство StartPosition = "CenterScreen";
  • в форме Form2 свойство Text = "График функции z = f (x, y)";
  • в компоненте button1 свойство Text = "^";
  • в компоненте button2 свойство Text = "v";
  • в компоненте button3 свойство Text = "<";
  • в компоненте button4 свойство Text = ">".

Примерный вид формы Form2 показано на рисунке 3.

Рис. 3. Вид Form2 приложении

4. Ввод внутренних переменных в форму Form2.

Все внутренние переменные, используемые для организации вывода графику, размещаются в форме Form2. Поэтому, сначала надо активизировать модуль (файл) «Form2.cs».

В модуль формы Form2 вводятся следующие внутренние переменные с классом видимости private:

  • xx1, xx2, yy1, yy2 - отвечают координатам точек отображаемых на экране монитора;
  • массивы xx и yy которые предназначены для вывода плоскости с 4-х точек. Область определения функции z = f (x, y) разбивается на прямоугольники, на каждом из которых функция экстраполируется с ребрами четырехугольника.

Как общедоступные, типа public, вводятся:

  • переменные X_min, Y_min, X_max, Y_max действительного типа, соответствующих реальным координатам параллелепипеда, в котором выводится график функции. Эти переменные заполняются основной формы Form1 экспериментальным путем;
  • переменные alfa, beta действительного типа, отражающие углы наблюдения за графиком функции. Заполняются основной формы Form1;
  • переменные x0, y0, z0 действительного типа. Отражают величины с основной формулы вычисления (см. Математическую постановку задачи)
  • переменная A действительного типа является коэффициентом перспективы и подбирается экспериментально;
  • переменная f_show логического типа используется для указания, что нужно перерисовать график, в случае изменения положения углов alfa и beta.

После введения переменных в текст программы, фрагмент класса формы Form2 имеет вид:

... public partial class Form2: Form {private int xx1, xx2, yy1, yy2; private int [] xx = new int [4]; private int [] yy = new int [4]; private int left; private int top; private int width; private int height; public double X_min, Y_min, X_max, Y_max; public double alfa, beta; public double x0, y0, z0; public double A; public bool f_show; public Form2 () {InitializeComponent (); }} ...

Переменные, имеют идентификатор доступа public, заполняются формы Form1.

5. Программирование внутренних методов в форме Form2.

В текст класса Form2 вводятся три дополнительные методы:

  • функцию преобразования системы координат и масштабирование Zoom_XY ();
  • функцию func () для которой выводится график;
  • функцию рисования графика функции Show_Graphic ().

Листинг метода преобразования системы координат следующий:

private void Zoom_XY (double x, double y, double z, out int xx, out int yy) {double xn, yn, zn; double tx, ty, tz; tx = (x - x0) * Math .Cos (alfa) - (y - y0) * Math .Sin (alfa) ty = ((x - x0) * Math .Sin (alfa) + (y - y0) * Math .Cos (alfa)) * Math .Cos (beta) - (z - z0) * Math .Sin (beta) tz = ((x - x0) * Math .Sin (alfa) + (y - y0) * Math .Cos (alfa)) * Math .Sin (beta) + (z - z0) * Math .Cos (beta) xn = tx / (tz / A + 1); yn = ty / (ty / A + 1); xx = (int) (width * (xn - X_min) / (X_max - X_min)) yy = (int) (height * (yn - Y_max) / (Y_min - Y_max)) }

Листинг метода func () следующий.

private double func (double x, double y) {double res; res = Math .Sin (x) + Math .Cos (y) return res; }

В этом методе вместо строки

res = Math .Sin (x) + Math .Cos (y)

можно сделать вставку собственной функции.

Непосредственное вывода графика функции реализованы в методе Show_Graphic (). Листинг метода Show_Graphic () следующий.

private void Show_Graphic (PaintEventArgs e) {const double h = 0.1; const double h0 = 0 int i, j; Rectangle r1 = new Rectangle (left, top, left + width, top + height) Pen p = new Pen (Color.Black) e.Graphics.DrawRectangle (p, r1) // Создать шрифт Font font = new Font ( "Courier New", 12 FontStyle .Bold) SolidBrush b = new SolidBrush (Color.Blue) // рисования осей // ось X Zoom_XY (0, 0, 0, out xx1, out yy1) Zoom_XY (1.2, 0, 0, out xx2, out yy2) e.Graphics.DrawLine (p, xx1, yy1, xx2, yy2) e.Graphics.DrawString ( "X", font, b, xx2 + 3, yy2) // ось Y Zoom_XY (0, 0, 0, out xx1, out yy1) Zoom_XY (0, 1.2, 0, out xx2, out yy2) e.Graphics.DrawLine (p, xx1, yy1, xx2, yy2) e.Graphics.DrawString ( "Y", font, b, xx2 + 3, yy2) // ось Z Zoom_XY (0, 0, 0, out xx1, out yy1) Zoom_XY (0, 0, 1.2, out xx2, out yy2) e.Graphics.DrawLine (p, xx1, yy1, xx2, yy2) e.Graphics.DrawString ( "Z", font, b, xx2 + 3, yy2 - 3); // рисования поверхности p.Color = Color .Red; p.Width = 1; for (j = 0; j <= 9; j ++) for (i = 0; i <= 9; i ++) {Zoom_XY (h0 + h * i, h0 + h * j, func (h0 + h * i, h0 + h * j), out xx [0] out yy [0]); Zoom_XY (h0 + h * i, h + h * j, func (h0 + h * i, h + h * j), out xx [1], out yy [1]); Zoom_XY (h + h * i, h + h * j, func (h + h * i, h + h * j), out xx [2], out yy [2]); Zoom_XY (h + h * i, h0 + h * j, func (h + h * i, h0 + h * j), out xx [3], out yy [3]); e.Graphics.DrawLine (p, xx [0] yy [0] xx [1], yy [1]); e.Graphics.DrawLine (p, xx [1], yy [1], xx [2], yy [2]); e.Graphics.DrawLine (p, xx [2], yy [2], xx [3], yy [3]); e.Graphics.DrawLine (p, xx [3], yy [3], xx [0] yy [0]); }}

Поясним некоторые фрагменты кода в методе Show_Graphic ().

Область определения функции z = f (x, y) разбивается на прямоугольники, на каждом из которых функция экстраполируется с ребрами четырехугольника. Построение четырехугольников на экране реализуется с помощью метода DrawLine ().

После очистки канвы происходит рисования осей координат и методом DrawLine () выводятся фрагменты поверхности.

При рисовании поверхности по методу Show_Graphic () вызывается метод Zoom_XY (), который осуществляет преобразование и масштабирование из реальных координат в экранные координаты.

6. Программирование события Paint формы Form2

Чтобы получить объект Graphics, нужно запрограммировать событие Paint формы Form2. детальный пример программирования события в MS Visual Studio - C # описывается здесь .

Обработчик события Form2_Paint () получает два параметра. Первый параметр типа System.Object, второй параметр типа PaintEventArgs.

Параметр типа PaintEventArgs содержит объект Graphics, необходимый для прорисовування на поверхности формы.

Событие Paint возникает, когда окно становится «грязным» (dirty) - то есть, когда меняется его размер, когда оно перестает закрывать (частично или полностью) другое окно или когда оно было свернуто а затем развернуто. Во всех этих случаях - то есть когда форму необходимо перерисуваты, платформа .NET автоматически вызывает событие Paint.

Листинг обработчика события Form2_Paint () следующий.

private void Form2_Paint (object sender, PaintEventArgs e) {Show_Graphic (e) }

7. Программирование обработчиков событий клика на кнопках button1, button2, button3, button4

Вращения графику происходит в момент, когда пользователь делает клик на одной из кнопок, расположенных на форме Form2 (элементы управления button1, button2, button3, button4).

Отображение графика зависит от внутренних переменных alfa и beta. Переменная alfa содержит угол поворота относительно оси OZ. Переменная beta содержит значение угла поворота вокруг оси OX.

Поэтому, в обработчиках событий происходит изменение значений alfa и beta на некоторую величину. По желанию, можно установить собственную величину изменения alfa и beta.

Листинг обработчиков событий приведен ниже.

private void button1_Click (object sender, EventArgs e) {beta = beta + 0.1; Invalidate (); } Private void button2_Click (object sender, EventArgs e) {beta = beta - 0.1; Invalidate (); } Private void button3_Click (object sender, EventArgs e) {alfa = alfa + 0.1; Invalidate (); } Private void button4_Click (object sender, EventArgs e) {alfa = alfa - 0.1; Invalidate (); }

В вышеприведенных обработчиках событий, событие Paint генерируется явным образом с помощью унаследованного метода Invalidate (). Этот метод делает перерисовки всей клиентской области программным образом.

Метод Invalidate () имеет несколько перегруженных вариантов. Например, если нужно обновить заданный прямоугольник, то нужно создать такой код:

Rectangle r = new Rectangle (0, 0, 50, 50); Invalidate (r)

8. Программирование обработчиков событий MouseDown, MouseMove и MouseUp

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

Если нажать клавишу мыши и удерживать ее нажатой над формой Form2 а затем отпустить, то генерируются такие события (рисунок 4):

  • MouseDown - генерируется, когда пользователь делает клик мышкой на форме Form2;
  • MouseMove - генерируется, когда пользователь перемещает мышь над формой Form2 (независимо, нажата одна из кнопок мышки)
  • MouseUp - генерируется, когда пользователь отпускает кнопку мыши при нажатии.

MouseDown - генерируется, когда пользователь делает клик мышкой на форме Form2;   MouseMove - генерируется, когда пользователь перемещает мышь над формой Form2 (независимо, нажата одна из кнопок мышки)   MouseUp - генерируется, когда пользователь отпускает кнопку мыши при нажатии

Рис. 4. События MouseDown, MouseMove, MouseUp

private void Form2_MouseDown (object sender, MouseEventArgs e) {f_show = true; } Private void Form2_MouseUp (object sender, MouseEventArgs e) {f_show = false; } Private void Form2_MouseMove (object sender, MouseEventArgs e) {double a, b; if (f_show) {a = eX - (int) (width / 2); b = eY - (int) (height / 2); if (a! = 0) alfa = Math .Atan (b / a) else alfa = Math .PI / 2; beta = Math .Sqrt (Math .Pow (a / 10, 2) + Math .Pow (b / 10, 2)); Invalidate (); }}

9. Листинг модуля «Form2.cs»

Ниже приведен полный текст файла "Form2.cs", который соответствует форме Form2.

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 {public partial class Form2: Form {private int xx1, xx2, yy1, yy2; private int [] xx = new int [4]; private int [] yy = new int [4]; public int left; public int top; public int width; public int height; public double X_min, Y_min, X_max, Y_max; public double alfa, beta; public double x0, y0, z0; public double A; public bool f_show; public Form2 () {InitializeComponent (); } Private void Zoom_XY (double x, double y, double z, out int xx, out int yy) {double xn, yn, zn; double tx, ty, tz; tx = (x - x0) * Math .Cos (alfa) - (y - y0) * Math.Sin (alfa) ty = ((x - x0) * Math .Sin (alfa) + (y - y0) * Math .Cos (alfa)) * Math .Cos (beta) - (z - z0) * Math .Sin (beta) tz = ((x - x0) * Math .Sin (alfa) + (y - y0) * Math .Cos (alfa)) * Math .Sin (beta) + (z - z0) * Math .Cos (beta) xn = tx / (tz / A + 1); yn = ty / (ty / A + 1); xx = (int) (width * (xn - X_min) / (X_max - X_min)) yy = (int) (height * (yn - Y_max) / (Y_min - Y_max)) } Private double func (double x, double y) {double res; res = Math .Sin (x) + Math .Cos (y) return res; } Private void Show_Graphic (PaintEventArgs e) {const double h = 0.1; const double h0 = 0 int i, j; Rectangle r1 = new Rectangle (left, top, left + width, top + height) Pen p = new Pen (Color .Black) e.Graphics.DrawRectangle (p, r1) // Создать шрифт Font font = new Font ( "Courier New", 12 FontStyle .Bold) SolidBrush b = new SolidBrush (Color .Blue) // рисования осей // ось X Zoom_XY (0, 0, 0, out xx1, out yy1) Zoom_XY (1.2, 0, 0, out xx2, out yy2) e.Graphics.DrawLine (p, xx1, yy1, xx2, yy2) e.Graphics.DrawString ( "X", font, b, xx2 + 3, yy2) // ось Y Zoom_XY (0, 0, 0, out xx1, out yy1) Zoom_XY (0, 1.2, 0, out xx2, out yy2) e.Graphics.DrawLine (p, xx1, yy1, xx2, yy2) e.Graphics.DrawString ( "Y", font, b, xx2 + 3, yy2) // ось Z Zoom_XY (0, 0, 0, out xx1, out yy1) Zoom_XY (0, 0, 1.2, out xx2, out yy2) e.Graphics.DrawLine (p, xx1, yy1, xx2, yy2) e.Graphics.DrawString ( "Z", font, b, xx2 + 3, yy2 - 3); // рисования поверхности p.Color = Color.Red; p.Width = 1; for (j = 0; j <= 9; j ++) for (i = 0; i <= 9; i ++) {Zoom_XY (h0 + h * i, h0 + h * j, func (h0 + h * i, h0 + h * j), out xx [0] out yy [0]); Zoom_XY (h0 + h * i, h + h * j, func (h0 + h * i, h + h * j), out xx [1], out yy [1]); Zoom_XY (h + h * i, h + h * j, func (h + h * i, h + h * j), out xx [2], out yy [2]); Zoom_XY (h + h * i, h0 + h * j, func (h + h * i, h0 + h * j), out xx [3], out yy [3]); e.Graphics.DrawLine (p, xx [0] yy [0] xx [1], yy [1]); e.Graphics.DrawLine (p, xx [1], yy [1], xx [2], yy [2]); e.Graphics.DrawLine (p, xx [2], yy [2], xx [3], yy [3]); e.Graphics.DrawLine (p, xx [3], yy [3], xx [0] yy [0]); }} Private void Form2_Paint (object sender, PaintEventArgs e) {Show_Graphic (e) } Private void button1_Click (object sender, EventArgs e) {beta = beta + 0.1; Invalidate (); } Private void button2_Click (object sender, EventArgs e) {beta = beta - 0.1; Invalidate (); } Private void button3_Click (object sender, EventArgs e) {alfa = alfa + 0.1; Invalidate (); } Private void button4_Click (object sender, EventArgs e) {alfa = alfa - 0.1; Invalidate (); } Private void Form2_MouseDown (object sender, MouseEventArgs e) {f_show = true; } Private void Form2_MouseUp (object sender, MouseEventArgs e) {f_show = false; } Private void Form2_MouseMove (object sender, MouseEventArgs e) {double a, b; if (f_show) {a = eX - (int) (width / 2); b = eY - (int) (height / 2); if (a! = 0) alfa = Math .Atan (b / a) else alfa = Math .PI / 2; beta = Math .Sqrt (Math .Pow (a / 10, 2) + Math .Pow (b / 10, 2)); Invalidate (); }}}}

10. Программирование события клика на кнопке button 1 формы Form 1 (вызов формы рисования графика функции)

При клике на кнопке button1 из формы Form1 имеет выводиться график функции.

Обработчик события клика на кнопке Button1 имеет вид.

private void button1_Click (object sender, EventArgs e) {Form2 form2 = new Form2 (); // Прямоугольник, в котором будет выводиться график функции form2.left = 20; form2.top = 20; form2.width = 300; form2.height = 300; form2.f_show = false; form2.x0 = 0 form2.y0 = 0 form2.z0 = 0 form2.A = -8; form2.alfa = 10; form2.beta = 12; form2.X_min = 3; form2.X_max = 3; form2.Y_min = 3; form2.Y_max = 3; form2.ShowDialog (); }

11. Запуск программы

После запуска программы на выполнение, форма графика функции является изображенная на рисунке 5.

Рис Рис. 5. Результат выполнения программы

Похожие

Программа Лизинг - Деловые программы - InsERT
Просмотр Мы предлагаем вам привлекательное предложение, которое мы подготовили в сотрудничестве с Европейским лизинговым фондом. Аренда наших программ - чрезвычайно выгодное решение как для предпринимателей, которые только что начали свой бизнес, так и для тех, кто
Как запрограммировать журнал температуры с помощью Arduino Uno?
В последнем руководстве мы показали, как создать устройство для измерения температуры и влажности с помощью Arduino. Теперь мы расширим его функцией записи данных на SD-карту и записи времени каждого измерения. Нам понадобится накладка на SD-карту и часы реального времени. Дисплей может остаться на обложке Grove. Если вы хотите использовать регистратор
Онлайн антивирусные сканеры
... ye-skanery-1.png" alt="Онлайн сканеры имеют много преимуществ"> Онлайн сканеры имеют много преимуществ. Это бесплатные программы, которые требуют только для сохранения легких файлов на вашем компьютере. В отличие от традиционных антивирусов, вам не нужно устанавливать большие файлы или регистрироваться на сайтах производителей. Это программное обеспечение имеет основные функции базовой защиты от интернет-угроз. Чаще всего он основан на технологических решениях и базах данных сигнатур, созданных
Домашняя страница фирмы Байт
... xe"> Скачать программу для удаленной помощи Программа будет работать в демонстрационном режиме с определенными ограничениями около 30 дней! После завершения данного срока без решения вопроса легализации программа ХЕППИ-БУХ работать НЕ БУДЕТ! Внимание!
ИТ-безопасность: антивирус и брандмауэр
... ftung Warentest снова и снова в своих тестах , более Обновлять антивирусную защиту постоянно
AVG - быстрый, эффективный и простой в использовании
Проверьте, как антивирусная программа AVG обеспечит вам безопасность AVG Antivirus может обеспечить полную безопасность вашего компьютера и данных, собранных на нем. Выбирая его, вы не только заботитесь о своей
Стоит начинать бизнес в социальных сетях?
Перед каждым предпринимателем встает вопрос: стоит переносить свой бизнес в плоскость социальных сетей? Специалисты утверждают: однозначно - стоит! Более того: из соцсетей можно даже начинать собственное дело. Стоит предупредить вас заранее: не стоит ожидать молниеносных результатов. Вполне возможно, что в течение нескольких месяцев вам придется лишь вкладывать силы и финансы без существенной отдачи. Но не надо опускать руки. При правильно построенной стратегии и профессионального подхода
Linksys WRT54GL скачать инструкцию по эксплуатации
... y-policy Справа вы найдете инструкцию Linksys WRT54GL . Эта услуга абсолютно бесплатна. Если у вас есть какие-либо вопросы о вашей точке доступа, пожалуйста, сообщите нам об этом внизу этой
Обзор Lenovo Y50-70 Touch
... x 2160 пикселей к Y50 шасси. Чтобы еще больше оправдать повышение цен, Lenovo модернизировала процессор и хранилище, что приводит к небольшому увеличению производительности. Все это хорошо, но, как и его братья серии Y, Y50-70 имеет громоздкую раму и короткое время автономной работы, что не позволяет ему быть реально портативным. статья продолжена ниже Смотрите наш список любимых ноутбуков
Adobe Flash Player 11 Beta с поддержкой 64-бит
... Flash Player 11 Beta. Отличие этого выпуска в том, что он также выпущен для долгожданной 64-битной технологии. Flash Player 11 все еще находится в стадии бета-тестирования, но Adobe планирует выпустить финальную версию к концу этого года. Функции, включенные в Flash Player 11 Flash Player 64-битный Самая большая и самая ожидаемая особенность - поддержка 64-бит. Если вы хотите загрузить и запустить 64-разрядную версию Flash Player 11, вам потребуется 64-разрядный
Бесплатные программы от CodeTwo
Проверьте наши бесплатные программы. Скачивайте и используйте их без ограничений. Они не содержат рекламы! Фотографии CodeTwo Active Directory Active Directory Photos - это бесплатное приложение, используемое для простого и прозрачного импорта и управления фотографиями пользователей

Комментарии

Является ли целью оценка или разработка полного, широкого цикла закупок или отдельной системы?
Является ли целью оценка или разработка полного, широкого цикла закупок или отдельной системы? Touchpoint и каналы. Карта должна совмещать точки взаимодействия (время, когда действующий субъект на карте фактически взаимодействует с компанией) и каналы (методы коммуникации или доставки услуг, такие как веб-сайт или физическое хранилище) с целями и действиями пользователя. Эти элементы заслуживают особого внимания, потому что они часто встречаются там, где обнаруживаются
Поможет ли вам какое-либо изменение инструментов на работе или, скорее, затруднит?
Поможет ли вам какое-либо изменение инструментов на работе или, скорее, затруднит? Посмотрите на вашу рабочую среду: вы работаете с другими? Если да, то какие инструменты они используют? Сможете ли вы сотрудничать с ними после смены платформы? Мои ответы на эти вопросы выглядят так: Мне нужен компьютер обслуживающий 90% время для стационарной работы. Суточная нагрузка состоит в основном из: много часов написания и редактирования
Какие функции вы хотели бы видеть приложение добавить в будущем?
Какие функции вы хотели бы видеть приложение добавить в будущем? Дайте нам знать, комментарий в форме отверстия ниже.
Две сети ледогенераторов / куломатов из двух серьезных групп, за которыми стоят серьезные партнеры?
Две сети ледогенераторов / куломатов из двух серьезных групп, за которыми стоят серьезные партнеры? Польские потребители, вероятно, не могли придумать лучшего сценария. Читайте также: В этом году вы сможете заказать еду онлайн и получить ее в холодильнике.

Перед каждым предпринимателем встает вопрос: стоит переносить свой бизнес в плоскость социальных сетей?
Является ли целью оценка или разработка полного, широкого цикла закупок или отдельной системы?
Поможет ли вам какое-либо изменение инструментов на работе или, скорее, затруднит?
Посмотрите на вашу рабочую среду: вы работаете с другими?
Если да, то какие инструменты они используют?
Сможете ли вы сотрудничать с ними после смены платформы?
Какие функции вы хотели бы видеть приложение добавить в будущем?
Две сети ледогенераторов / куломатов из двух серьезных групп, за которыми стоят серьезные партнеры?
Две сети ледогенераторов / куломатов из двух серьезных групп, за которыми стоят серьезные партнеры?