1. В первой задаче вам нужно по величине углов shoulder, elbow и wrist вычислить координаты соответствующих суставов.
Для этого в классе AnglesToCoordinatesTask реализуйте метод PointF[] GetJointPositions(double shoulder, double elbow, double wrist)
В том же файле в классе AnglesToCoordinatesTask_Tests напишите модульные тесты, покрывающие все принципиальные случаи.
Используйте константы UpperArm, Forearm и Palm из класса Manipulator в качестве размеров соответствующих частей манипулятора.
После выполнения этого задания, при запуске проекта, визуализация должна будет отражать положение манипулятора в зависимости от начальных значений.
2. В том же проекте доработайте файл VisualizerTask.cs, чтобы заработала визуализация.
В методе KeyDown сделайте, чтобы манипулятор реагировал на клавиши QASW таким образом:
по Q увеличивает угол Shoulder на небольшую величину, а по A — уменьшает;
по W увеличивает угол Elbow на небольшую величину, а по S — уменьшает;
при любых изменениях пересчитывает Wrist по формуле Wrist = - Alpha - Shoulder - Elbow;
В методе MouseMove менял бы X и Y в соответствии со значением из события — координатами мыши относительно окна. Имейте в виду, что ось Y в окне направлена вниз, а в математике — вверх. Поэтому координаты мыши нужно преобразовывать из оконной системы координат в логическую, а при отрисовке наоборот. X и Y в итоге должны хранить логические координаты указателя мыши, относительно shoulderPos — координат единственного неподвижного сустава. Преобразовать оконные координаты в логические и наоборот можно с помощью пары готовых функций ConvertMathToWindow и ConvertWindowToMath.
В методе MouseWheel добавить обработку прокрутки колеса мыши. Оно должно менять Alpha.
В методе UpdateManipulator вызвать ManipulatorTask.MoveManipulatorTo и обновить значения Shoulder, Elbow и Wrist (это понадобится в последней задаче). UpdateManipulator нужно вызывать после каждого изменения X, Y или Alpha, то есть в методах MouseMove и MouseWheel.
В методе DrawManipulator допишите рисование манипулятора. Нарисуйте каждый сегмент манипулятора отрезком прямой, а каждый сустав — окружностью. Координаты сустава получите методом AnglesToCoordinatesTask.GetJointPositions. Не забудьте преобразовать логические координаты в оконные.
При запуске проекта в результате вы сможете управлять углами сгиба суставов манипулятора с помощью клавиатуры. А после выполнения следующих заданий, манипулятор должен будет следовать за курсором мыши.
3. В том же проекте решите вспомогательную задачу на геометрию в классе TriangleTask.cs.
Реализуйте метод double GetABAngle(a, b, c). Он должен возвращать угол в радианах между сторонами a и b в треугольнике со сторонами a, b, c.
Естественно, для практических целей треугольник может быть вырожденным, то есть некоторые стороны могут иметь длину 0. При недопустимых аргументах или при невозможности определить угол в вырожденном треугольнике метод должен возвращать double.NaN.
В том же файле напишите модульные тесты, покрывающие все случаи. В том числе и особые, граничные случаи.
4. В том же проекте реализуйте метод MoveManipulatorTo в классе ManipulatorTask.
Он должен возвращать массив углов new[] {shoulder, elbow, wrist}, необходимых для приведения эффектора манипулятора в точку (x, y) относительно крепления манипулятора к столу, и с углом между последним суставом и горизонталью равному alpha в радианах.
Если это невозможно, то возвращайте массив из трех double.NaN.
Сверяйтесь с чертежом! Не перепутайте углы и их направления!
Рандомизированный тест
В том же файле напишите вместо нескольких тестов один рандомизированный.
Он должен в цикле генерировать случайные значения X, Y, Angle, вызывать MoveManipulatorTo, по углам вычислять позицию эффектора и проверять, что она совпадает с требуемой.
Среди сгенерированных X, Y, Angle иногда будут попадаться нерешаемые. Например, если требуемая точка (X, Y) расположена слишком далеко, то метод вернет NaN-ы. Однако несложно определить, для каких точек задача имеет решение, а для каких нет. Подсказку ищите в коде задачи о визуализации. Ваш рандомизированный тест должен проверять, что NaN возвращается только тогда, когда решения действительно нет.
Тамара
НГТУ
Очень оперативно выполнила задание. Замечания были незначительные, исполнитель их очень бы...
Евгений
Уральский Горный Университет
Все выполнено досрочно! Рекомендую данного исполнителя! Все сделано качественно! Спасибо ...
Алина
НГАТУ
Работа выполнена отлично, подробные и понятные объяснения. Большое спасибо
Наталья
Колледж РГСУ
Alex, спасибо! Сложная работа выполнена быстро и качественно! Благодарю!