Нарисуйте простой робот в C#

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

Основная идея состоит в том, чтобы рассматривать этапы руки один за другим и использовать преобразования для перехода от одного к другому.

Предположим, что три сегмента плеча имеют длины L1, L2 и L3, а углы поворота на трех стыках - A1, A2 и A3.

Первый шарнир поворачивает рычаг на угол A1 на фиксированном плече. Второе соединение переведено на расстояние L1 в направлении первого сегмента руки.

Второй шарнир поворачивает рычаг на угол A2 на «локте». Третий шарнир сдвинут расстояние L2 в направлении второго сегмента руки.

Третий шарнир поворачивает рычаг на угол A3 на «запястье». Конец рычага переведен на расстояние L3 в направлении третьего сегмента руки.

Эта программа использует следующий код для рисования руки робота.

private void DrawRobotArm(Graphics gr)
{
    const int UpperArmLength = 75;
    const int LowerArmLength = 50;
    const int WristLength = 20;

    gr.SmoothingMode = SmoothingMode.AntiAlias;
    gr.Clear(picCanvas.BackColor);

        
        float cx = picCanvas.ClientSize.Width / 2;
    float cy = picCanvas.ClientSize.Height / 2;
    gr.TranslateTransform(cx, cy);

            GraphicsState initial_state = gr.Save();

            Rectangle rect = new Rectangle(0, -2, 100, 5);

            gr.RotateTransform(-scrJoint1.Value, MatrixOrder.Prepend);

        rect.Width = UpperArmLength;
    gr.FillRectangle(Brushes.LightBlue, rect);
    gr.DrawRectangle(Pens.Blue, rect);

        gr.TranslateTransform(UpperArmLength, 0, MatrixOrder.Prepend);

        gr.RotateTransform(-scrJoint2.Value, MatrixOrder.Prepend);

        rect.Width = LowerArmLength;
    gr.FillRectangle(Brushes.LightBlue, rect);
    gr.DrawRectangle(Pens.Blue, rect);

        gr.TranslateTransform(LowerArmLength, 0, MatrixOrder.Prepend);

        gr.RotateTransform(-scrJoint3.Value, MatrixOrder.Prepend);

        rect.Width = WristLength;
    gr.FillRectangle(Brushes.LightBlue, rect);
    gr.DrawRectangle(Pens.Blue, rect);

            gr.Restore(initial_state);

        Rectangle joint_rect = new Rectangle(-4, -4, 9, 9);
    gr.FillEllipse(Brushes.Red, joint_rect);

            gr.RotateTransform(-scrJoint1.Value, MatrixOrder.Prepend);

        gr.TranslateTransform(UpperArmLength, 0, MatrixOrder.Prepend);

        gr.FillEllipse(Brushes.Red, joint_rect); 

        gr.RotateTransform(-scrJoint2.Value, MatrixOrder.Prepend);

        gr.TranslateTransform(LowerArmLength, 0, MatrixOrder.Prepend);

        gr.FillEllipse(Brushes.Red, joint_rect);
}

Код начинается с некоторой инициализации, а затем переводит центр координат в середину PictureBox.

Программа должна нарисовать суставы (плечо, локоть и запястье) сверху рук, поэтому метод тянет руку в два этапа. Сначала он рисует руки, а затем натягивает суставы сверху. Он использует один и тот же набор преобразований для каждого.

В коде применяется поворот A1 в плече и рисуется прямоугольник, представляющий первый сегмент руки. Здесь есть одна сложная проблема.

Вращение добавлено к предыдущему переводу, поэтому вращение происходит до перевода, который центрирует плечо. Представьте себе руку в своем собственном мире, координатное пространство с плечом в начале координат. Программа рисует горизонтальный прямоугольник в начале координат для представления первого сегмента руки. Затем преобразования поворачивают его под правильным углом и только затем переводят так, чтобы плечо было центрировано. Это помещает первый сегмент руки в правильное положение.

Затем код должен перейти в положение локтевого сустава. Для этого он добавляет перевод расстояния L1 в направлении X и 0 в направлении Y. Поскольку за этим следует предыдущее вращение, этот перевод происходит в направлении, которое указывает первый сегмент первого плеча. Это ставит начало рисунка в месте локтя. Рисунок переведен, повернут и переведен снова, поэтому он попадает в правильное положение.

Снова представим руку в мировом координатном пространстве и предположим, что вы рисуете локоть в начале координат. Новый перевод перемещает соединение в (L1, 0). Вращение угла A1 вращает сустав в соответствии с вращением первого сегмента плеча. Наконец, перевод плеча перемещает все это, поэтому основание первого сегмента руки центрируется в области рисования.

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

После того, как нарисованы все сегменты руки, код сбрасывает преобразование в исходное, которое центрирует плечо на PictureBox. Затем он снова проходит преобразования, на этот раз рисуя суставы.

Источник: http://csharphelper.com/blog/2016/06/draw-a-simple-robot-arm-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector