Создание компоненты, реализующей модель движущегося человека

Тип работы:
Контрольная
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

Создание компоненты, реализующей модель движущегося человека

1. Анализ предметной области. Выявление состава, структуры, и возможных состояний объекта

/

Физическая модель, движущегося в реальной жизни человека, очень трудна. У него много составных подвижных частей, который могут изменять свое положение в трех измерениях. При составлении математической модели, было принято решение выделить только основные части тела, характерные человеку. А так же ограничиться только двумя степенями свободы для вращающихся частей тела.

К вращающимся частям тела относятся руки, состоящие из плеч и предплечий, и ног состоящие соответственно из бедер и голеней. Они представляют собой отрезки с заданным началом (центром вращения), углом и длиной (более подробное описание составляющих встретится ниже). Так же в тело человека входят Голова, представленная окружностью, и туловище, отображаемое как прямая линия.

Класс вращающаяся часть тела

Вращающаяся часть тела, как говорилось ранние, представляет собой отрезок, положение которого задается углом, начальной точкой и длиной. Но для вращения так же характерно направление «положительного» движения: почасовой или против часовой стрелки (под «положительным» движение понимается движение, при котором конечная точка отрезка станет выше предыдущего положения ()). Это необходимо для того, чтобы при команде такой как «Поднять_часть_тела_вверх», части тела, принадлежащие левой стороне двигались по часовой стрелке (т.е. увеличивая угол б), а принадлежащие правой стороне, соответственно против часовой (т.е. уменьшая угол в) (см. рис. 2)

/

Любая вращающаяся часть тела имеет предельные углы: начальный и конечный, выход за которые не допустим. При этом учитывается направление «положительного» вращения. Иными словами, допустимый диапазон углов может быть разный при одинаковых начальном и конечном углах, но при разных направлениях. (см. рис. 3)

/

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

Основываясь на выше сказанном, класс должен иметь следующее:

Поля:

1. Начальный точка (центр вращения)

2. Текущий угол

3. Длина

4. Начальный угол

5. Конечный угол

6. Угловая скорость (общее поле для всех экземпляров)

7. Направление движения

8. Связанная часть тела (экз. такого же класса)

Свойства:

1. Чтение / Изменение начального угла

2. Чтение / Изменение конечного угла

3. Чтение / Изменение текущего угла (при изменении проверяется допустимый диапазон углов, а так же угол приводится к виду когда он всегда положительный (>= 0 и < =360))

4. Чтение начальной точки

5. Чтение / Изменение координат начальной точки

6. Чтение конечной точки (расчет на основе угла и длины)

7. Чтение / Изменение угловой скорости

Функции:

1. Обновление координат связанной части тела

2. Проверка принадлежности угла допустимому диапазону

3. Рисования части тела

4. Задание диапазона углов

5. Вращать по направлению «положительного» вращения

6. Вращать против направления «положительного» вращения

Класс голова

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

Класс Голова должна иметь:

Поля:

1. Радиус;

2. Центр;

И у нее должна быть следующая функция:

1. Функция рисования себя.

Класс человек

Как известно, у человека две руки и две ноги, каждые из которых состоят из двух связанных вращающихся частей тела (плечо и предплечье, бедро и голень). Итого таких частей всего 8. А так же голова, представленная отдельным классом, и туловище. В виду малой возложенной функциональности на туловище, было решено не выделять его как отдельный класс, а просто графически представить как элементарный отрезок.

Класс Человек состоит из:

Поля:

1. Координаты начальной точки туловища

2. Длина туловища

3. Цвет

4. Экземпляры класса Вращающаяся Часть Тела (8 шт.)

5. Экземпляр класса Голова

Функции: Рисование человека

2. Выбор и обоснование программного решения

Наша компонента наследуется от класса UserControl, который в свою очередь порождается от класса Control. Это означает, что мы имеем дело с элементом управления. UserControl предоставляет контекст графического устройства для рисования как Graphics.

Компонента наследуется от класса UserControl, но это не означает, что ее нельзя реализовать, унаследовав от другого класса. Например, можно воспользоваться готовым классом компоненты Component, содержащий «минимальный» интерфейс. Но данный класс не имеет собственного Graphics. То есть данный класс не может себя прорисовывать без помощи извне. А наш класс должен иметь пользовательский интерфейс (то есть являться визуальным).

Таким образом, можно заключить, что наследование от класса UserControl хоть и не является единственно верным путем к созданию компоненты, но в тоже время такой способ имеет право на существование.

Теперь перейдем непосредственно к разработке.

Наша компонента будет состоять из простейших геометрических фигур: окружностей и прямых.

Создаваемая компонента представляет собой класс, порождённый от UserControl и включающий в себя иерархию классов, показанную выше.

3. Разработка интерфейса и состава необходимых средств в виде свойств, событий и методов

Для отрисовки компоненты используем обработчик события private void ManControl_Paint (object sender, PaintEventArgs e) предоставленный в классе UserControl специально для воспроизведения изображения оконных компонент.

Для взаимодействия с пользователем используются следующие функции:

public void GetLeftArmUp () — поднять левую руку

public void GetLeftLegUp () — поднять левую ногу

public void GetRigthLegUp () — поднять правую ногу

public void GetRightArmUp () — поднять правую руку

public void GetLeftArmDown () — опустить левюу руку

public void GetLeftLegDown () — опустить левую ногу

public void GetRigthLegDown () — опустить правую ногу

public void GetRightArmDown () — опустить правую руку

Свойства:

public double dAngle — задает угловую скорость вращения

public Color Color - задает цвет отображаемого человека

Добавление иконки к компоненте, описания к компоненте, добавление компоненты на Палитру элементов.

Добавление иконки компоненты

Чтобы добавить иконку к компоненте, нужно:

1. Сначала нужно нарисовать значок размером 16×16, палитра 16 цветов и формата BMP или ICO. Сохранить его нужно в папке, где написан наш проект.

2. Так как значок должен храниться внутри *. dll компоненты, то соответствующий файл нужно добавить к проекту (меню Project/Add Existing Item).

3. В свойствах файла иконки параметру Build Action нужно установить в значение Embedded Resource (Внедренный ресурс).

модель человек движущийся программа

4. Добавить атрибуты, указывающие как найти значок, перед объявлением класса компоненты (мы указываем тип, к которому добавляем иконку, а так же название рисунка для иконки):

[ToolboxBitmap (typeof (ManControl), «Man. bmp»)]

public partial class ManControl: UserControl // класс компоненты

Добавление описания компоненты.

Чтобы добавить описание, нужно добавить следующий атрибут перед объявлением класса компоненты:

[Description («Двжущийся человек»)]

public partial class ManControl: UserControl // класс компоненты

Он будет виден в сплывающей подсказке, при наведении курсора на компонент в Панели компонентов.

Добавление компоненты на палитру

Чтобы наша компонента была доступна в любых оконных разрабатываемых приложениях, нужно добавить ее на Палитру компонентов. Для этого нужно выполнить следующие действия:

1. Выбрать команду Choose Items (Выбрать элементы) в контекстном меню панели Toolbox (Инструменты) в нужной группе компонент.

2. Появится диалоговое окно, предлагающие выбрать компоненты (*. dll), которые будут отображаться в этой группе компонент. Если мы не находим нужную нам в предложенном списке, мы можем подгрузить её самостоятельно, нажав кнопку Browse и выбрать путь к файлу < Название компоненты>. dll

3. После этого компоненты появится в списке. Выбираем ее и закрываем диалоговое окно. Компонент < Название компоненты> появится в палитре компонентов. Так же, как и картинка, и описание.

Текст программы Rotary. cs

using System;

using System. Collections. Generic;

using System. Linq;

using System. Text;

using System. Drawing;

namespace ManComponent

{

enum RotateDir

{

ClockWise, // по часовой стрелки

CounterClockWise // против часовой стрелки

}

// класс описывающий вращающюся часть тела, относительно его центра

class Rotary

{

// ПОЛЯ

PointF pos; // начальная точка (центр вращения)

double angle; // угол

float length; // длина

double minAngle; // начальный угол

double maxAngle; // конечный угол — углы задают пределы вращения

public RotateDir dir; // положительное направление вращения

Rotary child; // другая вращ. часть тела, нач, точка которой совпадает с конечной

// стачичная переменая класса — «общая» для всех

static double da = Math. PI / 20d; // угловая скорость вращения

// СВОЙСТВА

public double MaxAngle {get {return maxAngle;} set {maxAngle = value; }}

public double MinAngle {get {return minAngle;} set {minAngle = value; }}

public double Angle

{

get {return angle; }

set

{ // преобразуем новый угол, если он отрицательный или больше чем 360 градусов

double a = value;

if (value >= 2 * Math. PI)

a = value — Math. PI * 2;

else if (value < 0)

a = 2 * Math. PI + value;

// если новый угол попадает в заданый диапозон (между min и max)

if (IsAbleToRotate (a))

{

angle = a;

UpdateChild ();

return;

}

// если угол находится радом с границей заданного диапазона

else if (Math. Abs (maxAngle — value) < da)

angle = maxAngle;

else if (Math. Abs (minAngle — value) < da)

angle = minAngle;

UpdateChild ();

}

}

public PointF Pos {get {return pos; }}

public PointF EndPoint {get {return new PointF (X + (float) Math. Cos (angle) * length, Y + (float) Math. Sin (angle) * length); }}

public float X {get {return pos. X;} set {pos.X = value; }}

public float Y {get {return pos. Y;} set {pos.Y = value; }}

// стачиное свойства да переменой da

public static double dAngle {get {return da;} set {if (value >= 0 & & value < Math. PI * 2) da = value; }}

void Initialize (float x, float y, float len, int ang, RotateDir direction)

{

pos = new PointF ((float) x, (float) y);

dir = direction;

angle = (double) ang/180d*Math. PI; length = len;

child = null;

minAngle = 0; maxAngle = 2 * Math. PI;

}

public Rotary (float x, float y, float len, int ang, RotateDir direction, Rotary ch)

{

Initialize (x, y, len, ang, direction);

child = ch;

child. dir = dir;

UpdateChild ();

}

public Rotary (float x, float y, float len, int ang, RotateDir direction)

{

Initialize (x, y, len, ang, direction);

}

public Rotary (float len, int ang)

{

Initialize (0, 0, len, ang, RotateDir. ClockWise);

}

void UpdateChild ()

{

if (child≠ null)

{

child.X = X + (float) Math. Cos (angle) * length;

child.Y = Y + (float) Math. Sin (angle) * length;

}

}

public void Draw (Graphics g, Color color)

{

g. DrawLine (new Pen (color, 5), pos, EndPoint);

if (child≠ null)

child. Draw (g, color);

g. FillEllipse (new SolidBrush (color), EndPoint. X-5f, EndPoint. Y -5f, 10,10);

}

bool IsAbleToRotate (double a)

{

double lb = minAngle; // нижняя граница

double ub = maxAngle; //

if (dir ==RotateDir. CounterClockWise)

{

ub = minAngle;

lb = maxAngle;

}

if (ub > lb)

if (a >= lb & & a <= ub) return true;

else return false;

else if ((a >= lb & & a < Math. PI * 2) || (a >= 0 & & a < ub))

return true;

else return false;

}

public void SetRange (int min, int max)

{

minAngle = (double) min/180d*Math. PI;

maxAngle = (double) max/180d*Math. PI;

}

public void RotateUp () // вращать по направлению

{

if (dir == RotateDir. CounterClockWise)

Angle -= da;

else Angle += da;

}

public void RotateDown () // вращать против направления

{

if (dir == RotateDir. CounterClockWise)

Angle += da;

else Angle -= da;

}

}

Man. cs

using System;

using System. Collections. Generic;

using System. Linq;

using System. Text;

using System. Drawing;

namespace ManComponent

{

class Head

{

const int r = 25;

int x, y;

public Head (int X, int Y)

{

x = X; y = Y;

}

public void Draw (Graphics g, Color color) {g. FillEllipse (new SolidBrush (color), x-r/2, y-r/2, r, r); }

}

class Man

{

int x, y, len;

public Color color;

public Rotary lArm, lElbow, rArm, rElbow, lLeg, lKnee, rLeg, rKnee;

public Head head;

public Man (int X, int Y, int length)

{ // положение человечка центр головы, длина туловища

x = X; y = Y; len = length;

color = Color. Blue;

lElbow = new Rotary (30,90); // левый локоть (предплечее)

lElbow. SetRange (90,270);

lArm = new Rotary (x, y+length*0. 2f, 30, 135, RotateDir. ClockWise, lElbow); // левая рука

lArm. SetRange (135,225);

lKnee = new Rotary (35, 90);

lKnee. SetRange (90, 180);

lLeg = new Rotary (x, y + len, 35, 135, RotateDir. ClockWise, lKnee);

lLeg. SetRange (125, 180);

rElbow = new Rotary (30, 90); // правый локоть

rElbow. SetRange (90,270);

rArm = new Rotary (x, y + length * 0. 2f, 30, 45, RotateDir. CounterClockWise, rElbow); // правая рука

rArm. SetRange (45, 315);

rKnee = new Rotary (35, 90);

rKnee. SetRange (90, 0);

rLeg = new Rotary (x, y + len, 35,45, RotateDir. CounterClockWise, rKnee);

rLeg. SetRange (45, 0);

head = new Head (x, y);

}

public void Draw (Graphics g)

{

lArm. Draw (g, color); // левая рука

rArm. Draw (g, color); // правая рука

lLeg. Draw (g, color); // левая нога

rLeg. Draw (g, color); // правая нога

head. Draw (g, color); // голова

g. DrawLine (new Pen (color, 5), x, y, x, y + len);

}

}

ManControl. cs

using System;

using System. Collections. Generic;

using System. ComponentModel;

using System. Drawing;

using System. Data;

using System. Linq;

using System. Text;

using System. Windows. Forms;

namespace ManComponent

{

[ToolboxBitmap (typeof (ManControl), «Man. bmp»)]

[Description («Двжущийся человек»)]

public partial class ManControl: UserControl

Man man;

[Category («Движущийся человек»), Description («Угловая скорость»), Browsable (true)]

public double dAngle {get {return Rotary. dAngle;} set {if (value >= 0 & & value < Math. PI * 2) Rotary. dAngle = value; }}

[Category («Движущийся человек»), Description («Цвет человека»), Browsable (true)]

public Color Color {get {return man. color;} set {man. color = value; Refresh (); }}

public ManControl ()

InitializeComponent ();

man = new Man (Width/2,40,80);

Color = Color. Black;

}

private void ManControl_Paint (object sender, PaintEventArgs e)

{

man. Draw (this. CreateGraphics ());

}

man. lArm. RotateUp ();

man. lElbow. RotateUp ();

Refresh ();

}

public void GetLeftLegUp ()

{

man. lLeg. RotateUp ();

man. lKnee. RotateUp ();

Refresh ();

}

public void GetRigthLegUp ()

{

man. rLeg. RotateUp ();

man. rKnee. RotateUp ();

Refresh ();

}

public void GetRightArmUp ()

{

man. rArm. RotateUp ();

man. rElbow. RotateUp ();

Refresh ();

}

public void GetLeftArmDown ()

{

man. lArm. RotateDown ();

man. lElbow. RotateDown ();

Refresh ();

}

public void GetLeftLegDown ()

{

man. lLeg. RotateDown ();

man. lKnee. RotateDown ();

Refresh ();

}

public void GetRigthLegDown ()

{

man. rLeg. RotateDown ();

man. rKnee. RotateDown ();

Refresh ();

}

public void GetRightArmDown ()

{

man. rArm. RotateDown ();

man. rElbow. RotateDown ();

Refresh ();

}

}

}

ПоказатьСвернуть
Заполнить форму текущей работой