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 возвращается только тогда, когда решения действительно нет.
Екатерина
Мади
Работа выполнена досрочно. С подробным описанием решения. Огромное спасибо!!
Лариса
ТУСУР
Все супер, задания выполнены в срок, оценены преподавателем на максимальный балл, всем рек...
Полина
МГИМО
Ксения - отличный автор. Обращаюсь к ней уже 2ой раз, вся работа выполнена прекрасно. Советую
Серафим
ВУЗ
Работа выполнена очень качественно! Очень грамотный специалист, рекомендую! Обращаюсь не в...