Автор работы: Пользователь скрыл имя, 15 Марта 2012 в 18:44, отчет по практике
В работе изложен взгляд на проблему оптимизации работы сотрудников подразделения института “Библиотека АМТИ ”, сделана постановка задачи на разработку АСУ подразделения. Рассмотрены возможности проектирования трёхмерного изображения твердого тела, преобразования графических объектов в пространстве. Выполнены практические задания: трёхмерное изображение сложного твёрдого тела и его проекции в среде AutoCAD 2000; разработана программа в среде С++ Builder, выполняющая преобразования графических объектов пространстве, использующая объект имидж, Open GL, API функции. Реализован алгоритм удаления невидимых линий.
Введение 5
1 AutoCAD 2000 – мощный инструмент проектирования трёхмерных объектов 6
2 Исследование работы подразделения «Библиотека АМТИ» 8
3 Программирование трёхмерных объектов в среде C++ Builder 10
4 Алгоритм преобразования объектов в пространстве 12
5 Алгоритмы удаления невидимых линий 13
6 Листинг программы 14
Заключение 33
Литература
Для автоматизации решения задач подразделения «Библиотека АМТИ» следует предпринять:
Для решения задач 1 и 3:
- организация поиска книг по аннотации
- разделение базы данных по дисциплинам
- внесение в базу данных содержания книги
- установка сетевой версии MarcSQL для предоставления студентам возможности самостоятельного поиска книг
- расширение существующей электронной библиотеки изданиями, находящимися в библиотеке в единственном экземпляре
Для решения задачи 5:
- необходимо разработать программу, в которую бы вносился код каждой выданной и принятой книги, которая сортировала бы книги по дисциплинам и выводила отчет о том, сколько книг по каждой конкретной дисциплине принято и выдано, в заданной форме.
- следует установить электронную картотеку, которая следила бы за сроками выдачи, сдачи книг, формировала бы списки задолжников, автоматически добавляла поступивших студентов и удаляла отчисленных и окончивших институт.
3 Программирование трёхмерных объектов в среде C++ Builder
Программирование трёхмерных объектов в среде C++ Builder возможно с применением различных методологических подходов: с помощью графического инструментария C++ Builder, с помощью инструментария api – функций и с помощью графической библиотеки OpenGL.
Рассмотрим свойства и методы графического инструментария C++ Builder, применённые в программе для рисования многогранника:
Для изменения цвета пера:
Form1->Image1->Canvas->Pen->Co
Для изменения толщины линий:
Form1->Image1->Canvas->Pen->
Для изменения стиля линий:
Form1->Image1->Canvas->Pen->St
Для установки курсора в заданную позицию:
Form1->Image1->Canvas->MoveTo(
Для рисования линии из точки с текущими координатами в заданную точку:
Form1->Image1->Canvas->LineTo(
При рисовании многогранника средствами API функций использовано следующее:
MoveToEx – эта функция перемещает графический курсор в точку с заданными координатами
LineTo – эта функция рисует линию текущим стилем и цветом пера из текущей точки в точку с указанными координатами.
Рисование многогранника средствами OpenGL в программе реализовано следующим образом:
Положение вершины определяются заданием их координат в двух- ,трех-, или четырехмерном пространстве (однородные координаты). Это реализуется с помощью нескольких версий команды glVertex:
void glVertex[2 3 4][s i f d] (type coords)
void glVertex[2 3 4][s i f d]v (type *coords)
Для задания текущего цвета вершины используются команды
void glColor[3 4][b s i f] (GLtype components)
void glColor[3 4][b s i f]v (GLtype components)
Для того, чтобы задать какую-нибудь фигуру, одних координат вершин недостаточно, и эти вершины надо объединить в одно целое, определив необходимые свойства. Для этого в OpenGL используется понятие примитивов, к которым относятся точки, линии, связанные или замкнутые линии, треугольники и так далее. Задание примитива происходит внутри командных скобок:
void glBegin (GLenum mode);
void glEnd (void);
Параметр mode определяет тип примитива, который задается внутри и в разработанной программе принимает значение: GL_POLYGON последовательно задаются вершины выпуклого многоугольника.
Для проведения операций видовых преобразованиям, к которым относятся перенос, поворот и изменение масштаба вдоль координатных осей в OpenGL существуют следующие функции:
glTranlsate..() производит перенос объекта, прибавляя к координатам его вершин значения своих параметров.
glRotate..() производит поворот объекта против часовой стрелки на угол angle (измеряется в градусах) вокруг вектора (x,y,z).
glScale..() производит масштабирование объекта (сжатие или растяжение), домножая соответствующие координаты его вершин на значения своих параметров.
С помощью следующей команды можно изменить положение точки наблюдения.
void gluLookAt (GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz)
4 Алгоритм преобразования объектов в пространстве
Алгоритм преобразования координат трёхмерного объекта в программе реализован в процедуре void Pereshot(int ff2)
Преобразования заданы в матричной форме.
Матрица отражения от оси OXZ:
float m1[4][4]={{1,0,0,0},
{0,-1,0,0},
{0,0,1,0},
{0,0,0,1}};
Матрица растяжения:
float m2[4][4]={
{k1,0,0,0},
{0,k1,0,0},
{0,0,k1,0},
{0,0,0,1}};
Матрица сдвига:
float m3[4][4]={
{1,0,0,dx1},
{0,1,0,dy1},
{0,0,1,dz1},
{0,0,0,1}};
Для того, чтобы получить результирующее преобразование необходимо перемножить вышеуказанные матрицы.
Первые 3 строки матрицы результирующего преобразования задают преобразование для трёх координат точки преобразуемого объекта:
Для того, чтобы получить новые координаты x точек многогранника необходимо в цикле перемножить матрицу старых координат на первую строку матрицы преобразования.
Для проведения операций видовых преобразованиям в OpenGL существуют следующие функции:
glTranlsate..() производит перенос объекта, прибавляя к координатам его вершин значения своих параметров.
glRotate..() производит поворот объекта против часовой стрелки на угол angle (измеряется в градусах) вокруг вектора (x,y,z).
glScale..() производит масштабирование объекта (сжатие или растяжение), домножая соответствующие координаты его вершин на значения своих параметров.
5 Алгоритмы удаления невидимых линий
Для удаления невидимых линий в программе использован следующий алгоритм:
- определяется вектор нормали к каждой грани многогранника
Если векторы заданы координатами точек начала и конца
(x1,y1,z1)(x2,y2,z2) и (x1,y1,z1)(x3,y3,z3),
то координату z нормали можно вычислить по формуле:
Zn=-(x3-x1)*(y2-y1)+(x2-x1)*(
- если координата z вектора нормали положительная, то грань видима, если отрицательна – невидима.
Чтобы реализовать удаление невидимых линий в OpenGL достаточно одной функции:
glEnable(GL_DEPTH_TEST);
Эта функция включает механизм z- буфера, который в OpenGL носит название буфера глубины.
Таким образом реализация удаления невидимых линий в OpenGL осуществляется проще и эффективней, чем с применением других средств.
6 Листинг программы
//----------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "all.h"
//----------------------------
#pragma resource "*.dfm"
#include <math.h>
#include <gl\gl.h>
#include <gl\glu.h>
TForm1 *Form1;
HWND H;
HDC hdc;
HGLRC hglrc;
//Исходные координаты фигуры
int XYZ[3][11];
int dx,dy,dz;
float k;
int XYZ2[3][11];
//----------------------------
//процедура преобразования координат вершин многогранника
//входные параметры: сдвиги по осям, коофициент растяжения
void Pereshot(int dx1, int dy1, int dz1, float k1){
//матрица отражения от оси OXZ
float m1[4][4]={{1,0,0,0},
{0,-1,0,0},
{0,0,1,0},
{0,0,0,1}};
//матрица растяжения
float m2[4][4]={
{k1,0,0,0},
{0,k1,0,0},
{0,0,k1,0},
{0,0,0,1}};
//матрица сдвига
float m3[4][4]={
{1,0,0,dx1},
{0,1,0,dy1},
{0,0,1,dz1},
{0,0,0,1}};
//Матрица результирующего преобразования
float m5[4][4];
float m4[4][4];
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
m4[i][j]=m1[i][0]*m2[0][j]+m1[
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
m5[i][j]=m3[i][0]*m4[0][j]+m3[
//преобразование координат
for (int i=0; i<11; i++)
XYZ2[0][i]=m5[0][0]*XYZ[0][i]+
for (int i=0; i<11; i++)
XYZ2[1][i]=m5[1][0]*XYZ[0][i]+
} // конец процедуры преобразования координат
//----------------------------
//процедура рисования многогранника по заданным точкам средствами С++
void MyF(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int x5, int y5, int x6, int y6, int x7, int y7, int x8, int y8, int x9, int y9, int x10, int y10){
//вычисляем координаты центра
int x0=(Form1->Image1->Width)/2;
int y0=(Form1->Image1->Height)/2;
//устанавливаем цвет пера
Form1->Image1->Canvas->Pen->
//вычисляем нормаль к грани и анализируем её направление
float Zn1=-(x5-x1)*(y2-y1)+(x2-x1)*(
//если координата z нормали положительна - грань видима
if (Zn1>0){
// устанавлимаем жирный и спложной тип линии
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
else {
//иначе грань невидима устанавливаем пунктирную линию
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
//рисуем грань линиями от вершины к вершине
Form1->Image1->Canvas->MoveTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
//вычисляем нормаль к грани и анализируем её направление
Zn1=-(x9-x8)*(y7-y8)+(x7-x8)*(
//если координата z нормали положительна - грань видима
if (Zn1>0){
// устанавлимаем жирный и спложной тип линии
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
else {
//иначе грань невидима устанавливаем пунктирную линию
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
//рисуем грань линиями от вершины к вершине
Form1->Image1->Canvas->MoveTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
//вычисляем нормаль к грани и анализируем её направление
Zn1=-(x10-x6)*(y1-y6)+(x1-x6)*
//если координата z нормали положительна - грань видима
if (Zn1>0){
// устанавлимаем жирный и спложной тип линии
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
else {
//иначе грань невидима устанавливаем пунктирную линию
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
//рисуем грань линиями от вершины к вершине
Form1->Image1->Canvas->MoveTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
//вычисляем нормаль к грани и анализируем её направление
Zn1=-(x4-x3)*(y8-y3)+(x8-x3)*(
//если координата z нормали положительна - грань видима
if (Zn1>0){
// устанавлимаем жирный и спложной тип линии
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
else {
//иначе грань невидима устанавливаем пунктирную линию
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
//рисуем грань линиями от вершины к вершине
Form1->Image1->Canvas->MoveTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
//вычисляем нормаль к грани и анализируем её направление
Zn1=-(x2-x7)*(y8-y7)+(x8-x7)*(
//если координата z нормали положительна - грань видима
if (Zn1>0){
// устанавлимаем жирный и спложной тип линии
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
else {
//иначе грань невидима устанавливаем пунктирную линию
Form1->Image1->Canvas->Pen->
Form1->Image1->Canvas->Pen->
}
//рисуем грань линиями от вершины к вершине
Form1->Image1->Canvas->MoveTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
Form1->Image1->Canvas->LineTo(
//вычисляем нормаль к грани и анализируем её направление
Zn1=-(x1-x6)*(y7-y6)+(x7-x6)*(
//если координата z нормали положительна - грань видима
if (Zn1>0){
// устанавлимаем жирный и спложной тип линии
Информация о работе Отчет по практике в вычислительном центре АМТИ