Модераторы: Rickert

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Движок на пальцах "От" и "До", Часть #1 
:(
    Опции темы
Rickert
Дата 19.10.2008, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 6
Всего: 52



Цитата
Итак, мы начинаем балл!

Сегодня мы поработаем над парой базовых классов для нашего проекта. А именно:
  • Класс  строки
  • Вектора
  • Двусвязанного списка
Сразу хочется сказать, что файлы реализации (*.cpp) мы будем ложить в директорию "cpp", а файлы описания в "inc", обе папки лежат в одной директории.
Я советую вам создать пустой “win32 console” проект и в нём время от времени дебажить некие маленькие алгоритмы. В частности, сейчас будем писать класc  строки.
Называйте, как хотите, а у меня это класс “aString”. Что должен будет уметь наш класс?
  •  Хранить данные как в wchar_t, так и char
  •  Складывать две строки
  •  Сравнивать две строки
  •  Искать строку до опред. символа
  •  Искать строку после опред. символа
Итак содаём файл описания класса (astring.h):
Код
//=============================================================================

#ifndef ASTRING_H
  #define ASTRING_H

//=============================================================================

#include <windows.h>

//=============================================================================

class aString
{
  public:
    aString();//конструктор всех видов
    aString(const wchar_t* str);
    aString(const char* str);
    aString(const aString& str);

    inline size_t asGetLength()const          {return m_Length;}
    inline const wchar_t* asGetString()const  {return m_pData;}
    inline const char* asGetStringChar()const {return m_pCharData;}
    inline UINT asGetCodePage()const          {return codePage;}
    inline size_t asGetCharSize()const        {return charSize;}

    bool operator==(const aString& str);
    bool operator==(const wchar_t* str);
    bool operator==(const char* str);
    bool operator!=(const aString& str);
    bool operator!=(const wchar_t* str);
    bool operator!=(const char* str);
    const aString operator=(const aString& str);
    const aString operator=(const wchar_t* str);
    const aString operator=(const char* str);
    const aString operator+=(const aString str);
    const aString operator+=(const wchar_t* str);
    const aString operator+=(wchar_t chr);

    aString asFindBefore(wchar_t chr, bool include);//вернуть строку до опред. символа
    aString asFindAfter(wchar_t chr, bool include);//вернуть строку после опред. символа
    void asClear();//отчистить строку

    ~aString();

  private:
    size_t m_Length;
    wchar_t* m_pData;
    char* m_pCharData;
    const size_t charSize;
    UINT codePage;
    UINT codePageW;
};

//=============================================================================

#endif

//=============================================================================

Вообщем – то здесь всё прозрачно и ясно. Конкретная реализация идёт дальше: тут вам придётся поработать самим в некоторых местах.
astring.cpp
Код
//=============================================================================

#include <string.h>
#include "../inc/aString.h"

//=============================================================================

aString::aString() : charSize(sizeof(wchar_t))//частенько используется размер wchar_t: думаю логично было бы его зафиксировать. Char = 1
{
  m_Length = 0;
  m_pData = 0;
  m_pCharData = 0;
  codePage = CP_UTF8;//код для преобразования из wchar_t в char
  codePageW = CP_UTF8;//наоборот
}

//=============================================================================

aString::aString(const wchar_t* str) : charSize(sizeof(wchar_t))
{
  m_Length = 0;
  m_pData = 0;
  m_pCharData = 0;
  codePage = CP_UTF8;
  codePageW = CP_UTF8;

  if (!str)
    return;

  size_t strLen = wcslen(str);
  
  m_pData = new wchar_t[strLen + 1];
  m_pCharData = new char[strLen + 1];
  memcpy(m_pData, str, strLen*charSize);
  m_pData[strLen] = 0;

  //здесь должна быть функция преобразования wchar_t в char. Покумекайте сами, найдите описание и научитесь использовать. Все данные у вас есть.

  m_pCharData[strLen] = 0;

  m_Length = strLen;
}

//=============================================================================

aString::aString(const char* str) : charSize(sizeof(wchar_t))
{
  m_Length = 0;
  m_pData = 0;
  m_pCharData = 0;
  codePage = CP_UTF8;
  codePageW = CP_UTF8;

  if (!str)
    return;

  size_t strLen = strlen(str);
  
  m_pData = new wchar_t[strLen + 1];
  m_pCharData = new char[strLen + 1];
  memcpy(m_pCharData, str, strLen);
  m_pCharData[strLen] = 0;

  //здесь должна быть функция преобразования char в wchar_t. Покумекайте сами, найдите описание и научитесь использовать. Все данные у вас есть.

  m_pData[strLen] = 0;

  m_Length = strLen;
}

//=============================================================================

aString::aString(const aString& str) : charSize(sizeof(wchar_t))
{
  m_Length = 0;
  m_pData = 0;
  m_pCharData = 0;
  codePage = CP_UTF8;
  codePageW = CP_UTF8;

  if (str.asGetLength() <= 0)
    return;

  const wchar_t* tmpPointer = str.asGetString();
  size_t strLen = wcslen(tmpPointer);
  
  m_pData = new wchar_t[strLen + 1];
  m_pCharData = new char[strLen + 1];
  memcpy(m_pData, tmpPointer, strLen*charSize);
  m_pData[strLen] = 0;

  //здесь должна быть функция преобразования wchar_t в char. Покумекайте сами, найдите описание и научитес использовать. Все данные у вас есть.

  m_pCharData[strLen] = 0;

  m_Length = strLen;
}

//=============================================================================

bool aString::operator==(const aString& str)
{
  if (str.asGetLength() != m_Length)
    return 0;

  wchar_t* tmpPointer = m_pData;
  const wchar_t* tmpPointer2 = str.asGetString();
  
  while(*tmpPointer != L'\0')
  {
    if (*tmpPointer++ != *tmpPointer2++)
      return 0;
  }

  return 1;
}

//=============================================================================

bool aString::operator==(const wchar_t* str)
{
  if (!str)
    return 0;

  if (wcslen(str) != m_Length)
    return 0;

  wchar_t* tmpPointer = m_pData;
  
  while(*tmpPointer != L'\0')
  {
    if (*tmpPointer++ != *str++)
      return 0;
  }

  return 1;
}


//=============================================================================

bool aString::operator==(const char* str)
{
  if (!str || !m_pCharData)
    return 0;

  if (strlen(str) != m_Length)
    return 0;

  char* tmpPointer = m_pCharData;
  
  while(*tmpPointer != L'\0')
  {
    if (*tmpPointer++ != *str++)
      return 0;
  }

  return 1;
}

//=============================================================================

bool aString::operator!=(const aString& str)
{
  if (str.asGetLength() != m_Length)
    return 1;

  wchar_t* tmpPointer = m_pData;
  const wchar_t* tmpPointer2 = str.asGetString();
  
  while(*tmpPointer != L'\0')
  {
    if (*tmpPointer++ != *tmpPointer2++)
      return 1;
  }

  return 0;
}

//=============================================================================

bool aString::operator!=(const wchar_t* str)
{
  if (!str)
    return 1;

  if (wcslen(str) != m_Length)
    return 1;

  wchar_t* tmpPointer = m_pData;
  const wchar_t* tmpPointer2 = str;
  
  while(*tmpPointer != L'\0')
  {
    if (*tmpPointer++ != *tmpPointer2++)
      return 1;
  }

  return 0;
}

//=============================================================================

bool aString::operator!=(const char* str)
{
  if (!str)
    return 1;

  if (strlen(str) != m_Length)
    return 1;

  wchar_t* tmpPointer = m_pData;
  
  while(*tmpPointer != L'\0')
  {
    if (*tmpPointer++ != *str++)
      return 1;
  }

  return 0;
}

//=============================================================================

const aString aString::operator=(const aString& str)
{
  if (str.asGetLength() <= 0)
    return (*this);

  const wchar_t* tmpPointer = str.asGetString();
  size_t strLen = wcslen(tmpPointer);
  
  m_pData = new wchar_t[strLen + 1];
  m_pCharData = new char[strLen + 1];
  memcpy(m_pData, tmpPointer, strLen*charSize);
  m_pData[strLen] = 0;

  //здесь должна быть функция преобразования wchar_t в char. Покумекайте сами, найдите описание и научитесь использовать. Все данные у вас есть.

  m_pCharData[strLen] = 0;

  m_Length = strLen;

  return (*this);
}

//=============================================================================

const aString aString::operator=(const wchar_t* str)
{
  if (!str)
    return (*this);

  size_t strLen = wcslen(str);
  
  m_pData = new wchar_t[strLen + 1];
  m_pCharData = new char[strLen + 1];
  memcpy(m_pData, str, strLen*charSize);
  m_pData[strLen] = 0;

  //здесь должна быть функция преобразования wchar_t в char. Покумекайте сами, найдите описание и научитесь использовать. Все данные у вас есть.

  m_pCharData[strLen] = 0;

  m_Length = strLen;

  return (*this);
}

//=============================================================================

const aString aString::operator=(const char* str)
{
  if (!str)
    return (*this);

  size_t strLen = strlen(str);
  
  m_pData = new wchar_t[strLen + 1];
  m_pCharData = new char[strLen + 1];
  memcpy(m_pCharData, str, strLen);
  m_pData[strLen] = 0;

  //здесь должна быть функция преобразования char в wchar_t. Покумекайте сами, найдите описание и научитесь использовать. Все данные у вас есть.

  m_Length = strLen;

  return (*this);
}

//=============================================================================

const aString aString::operator+=(const aString str)
{
  if (str.asGetLength() <= 0)
    return (*this);

  size_t newLength = str.asGetLength() + m_Length;
  wchar_t* newData = new wchar_t[newLength + 1];
  char* newData2 = new char[newLength + 1];

  memcpy(newData, m_pData, m_Length*charSize);
  memcpy(&newData[m_Length], str.asGetString(), str.asGetLength()*charSize);
  newData[newLength] = 0;
  
  delete [] m_pData;
  delete [] m_pCharData;

  //здесь должна быть функция преобразования wchar_t в char. Покумекайте сами, найдите описание и научитесь использовать. Все данные у вас есть.

  newData2[newLength] = 0;

  m_pData = newData;
  m_pCharData = newData2;
  m_Length = newLength;

  return (*this);
}

//=============================================================================

const aString aString::operator+=(const wchar_t* str)
{
  if (!str)
    return (*this);

  size_t tmpLength = wcslen(str);

  if (tmpLength <= 0)
    return (*this);

  size_t newLength = tmpLength + m_Length;
  wchar_t* newData = new wchar_t[newLength + 1];
  char* newData2 = new char[newLength + 1];

  memcpy(newData, m_pData, m_Length*charSize);
  memcpy(&newData[m_Length], str, tmpLength*charSize);
  newData[newLength] = 0;
  
  delete [] m_pData;
  delete [] m_pCharData;

  //здесь должна быть функция преобразования wchar_t в char. Покумекайте сами, найдите описание и научитесь использовать. Все данные у вас есть.

  newData2[newLength] = 0;

  m_pData = newData;
  m_pCharData = newData2;
  m_Length = newLength;

  return (*this);
}

//=============================================================================

const aString aString::operator+=(wchar_t str)
{
  size_t newLength = m_Length + 1;
  wchar_t* newData = new wchar_t[newLength + 1];

  memcpy(newData, m_pData, m_Length*charSize);
  memcpy(&newData[m_Length], &str, charSize);
  newData[newLength] = 0;
  
  if (m_Length > 0)
    delete [] m_pData;

  m_pData = newData;
  m_Length = newLength;

  return (*this);
}

//=============================================================================

aString aString::asFindBefore(wchar_t chr, bool include)
{
  wchar_t* tmpPointer = m_pData;
  aString res;

  while(*tmpPointer != L'\0')
  {
    if (*tmpPointer != chr)
      res += *tmpPointer++;
    else
    {
      if (include)
        res += *tmpPointer;

      break;
    }
  }

  return res;
}

//=============================================================================

aString aString::asFindAfter(wchar_t chr, bool include)
{
  wchar_t* tmpPointer = m_pData;
  aString res;
  bool find = 0;

  while(*tmpPointer != L'\0')
  {
    if ((*tmpPointer == chr) && (!find))
    {
      find = 1;
      if (!include)
      {
        ++tmpPointer;

        continue;
      }
    }

    if (find)
      res += *tmpPointer;

    ++tmpPointer;
  }

  return res;
}

//=============================================================================

void aString::asClear()
{
  if (m_pData)
  {
    delete [] m_pData;

    m_pData = 0;
  }
  if (m_pCharData)
  {
    delete [] m_pCharData;

    m_pCharData = 0;
  }
  m_Length = 0;
}

//=============================================================================

aString::~aString()
{
  asClear();
}

//=============================================================================

Получается, что в первой нашей части теории практической никакой нет: просто отрабатываем общие принципы создания классов и включаем воображалку.
Идём дальше. Двусвязанный список
Он состоит из одного файла описания, потому что будет основан на шаблонах.
aList.h
Код
//==============================================================================

#ifndef ALIST_H
  #define ALIST_H

//==============================================================================

template <class TypeItem> class aItem
{
  public:
    aItem<TypeItem>()
    {
      next = 0;
      prev = 0;
    };
    ~aItem<TypeItem>()
    {
    };
    
    aItem* next;
    aItem* prev;
    TypeItem data;
};//класс – элемент нашего списка.

//==============================================================================

template <class Type> class aList
{
  public:
    inline aItem<Type>* alGetLastItem() const     {return last;}
    inline aItem<Type>* alGetFirstItem() const    {return items;}
    inline int alGetCount() const                 {return count;}

    aList()
    {
      items = 0;
      last = 0;
      count = 0;
    }
    ~aList()
    {
      alRemoveItems();
    }

    aItem<Type>* alAddItem()
    {
      if (!items)
      {
        items = new aItem<Type>;
        last = items;
        ++count;
    
        return items;
      }
  
      aItem<Type>* tmpItem = this->alGetLastItem();

      tmpItem->next = new aItem<Type>;
      tmpItem->next->prev = tmpItem;

      last = tmpItem->next;
      ++count;
  
      return last;
    }
    void alRemoveItems()
    {
      if (!items)
        return;

      aItem<Type>* tmpItem = alGetLastItem();
      aItem<Type>* tmpItem2 = 0;
  
      while(1)
      {
        tmpItem2 = tmpItem->prev;
    
        delete tmpItem;
    
        if (tmpItem2)
          tmpItem = tmpItem2;
        else
          break;
      }
      items = 0;
      last = 0;
      count = 0;
    }
    void alRemoveLastItem()
    {
      if (items)
      {
        if (last->prev)
        {
          last->prev = 0;

          delete last;
        }
        else
        {
          delete items;
          
          items = 0;
        }
        last = 0;
        --count;
      }
    }
    void alRemoveItem(aItem<Type>* it)
    {
      //а вот тут помучайтесь и напиши функцию, которая будет удалять любой элемент нашего списка. Не забывайте про исключительные ситуации и проверить находится ли этот элемент вообще в нашем списке.
    }
    
  private:
    bool alFoundItem(aItem<Type>* it)//функция проверяет: есть ли такой объект в нашем списке.
    {
      //тоже подумайте как написать
    }

  private:
    aItem<Type>* items;
    aItem<Type>* last;
    int count;
};

//==============================================================================

#endif

//==============================================================================

Помните: чем больше исключений вы обработаете и отбросите – тем стабильнее будет ваш код. В идеале, программист должен уметь предусмотреть абсолютно все варианты, которые могут привести к крушению приложения.
Дальше, по программе – чай с сахаром, а затем маленький класс вектора, который будет использован для больших деяний ;-)
avector.h
Код
//=============================================================================

#ifndef AVECTOR_H
  #define AVECTOR_H

//=============================================================================

#include <math.h>

//=============================================================================

class aVector
{
  public:
      inline const aVector& operator=(const aVector& vec)
      {
        this->x = vec.x;
        this->y = vec.y;
        this->z = vec.z;

        return (*this);
      }
      inline bool operator==(const aVector& vec)
      {}//реализуйте самостоятельно сравнение двух векторов. Помните что напрямую сравнить два float числа вы не можете: работа над числами с плавующей точкой весьма бажна. Шустри гуглом, думайте: это не сложно.
      inline bool operator==(const aVector& vec)const
      {}
      inline bool operator!=(const aVector& vec)
      {}
      inline bool operator!=(const aVector& vec)const
      {}
      inline const aVector operator+(const aVector& vec)const
      {
        aVector tmpVector((*this));

        tmpVector.x += vec.x;
        tmpVector.y += vec.y;
        tmpVector.z += vec.z;

        return tmpVector;
      }
      inline const aVector operator-(const aVector& vec)const
      {
        aVector tmpVector((*this));

        tmpVector.x -= vec.x;
        tmpVector.y -= vec.y;
        tmpVector.z -= vec.z;

        return tmpVector;
      }
      inline const aVector operator+=(const aVector& vec)
      {
        this->x += vec.x;
        this->y += vec.y;
        this->z += vec.z;

        return (*this);
      }
      inline const aVector operator-=(const aVector& vec)
      {
        this->x -= vec.x;
        this->y -= vec.y;
        this->z -= vec.z;

        return (*this);
      }
      inline const aVector operator*(float num)const
      {
        aVector tmpVector((*this));

        tmpVector.x *= num;
        tmpVector.y *= num;
        tmpVector.z *= num;

        return tmpVector;
      }
      inline const aVector operator/(float num)const
      {
        aVector tmpVector((*this));

        tmpVector.x /= num;
        tmpVector.y /= num;
        tmpVector.z /= num;

        return tmpVector;
      }
      inline const aVector operator*=(float num)
      {
        this->x *= num;
        this->y *= num;
        this->z *= num;

        return (*this);
      }
      inline const aVector operator/=(float num)
      {
        this->x /= num;
        this->y /= num;
        this->z /= num;

        return (*this);
      }

    aVector();
    aVector(float, float, float);
    aVector(const aVector&);
      void avSet(float, float, float);
    ~aVector();

  public:
    float x, y, z;
};

//=============================================================================

#endif

//=============================================================================

Ну и файл реализации (avector.cpp):
Код
//=============================================================================

#include "../inc/aVector.h"

//=============================================================================

aVector::aVector()
{
  this->x = 0;
  this->y = 0;
  this->z = 0;
}

//=============================================================================

aVector::aVector(float xx, float yy, float zz)
{
  this->x = xx;
  this->y = yy;
  this->z = zz;
}

//=============================================================================

aVector::aVector(const aVector& vec)
{
  this->x = vec.x;
  this->y = vec.y;
  this->z = vec.z;
}

//=============================================================================

void aVector::avSet(float xx, float yy, float zz)
{
  this->x = xx;
  this->y = yy;
  this->z = zz;
}

//=============================================================================

aVector::~aVector()
{
}

//=============================================================================

Слов и аналитики мало, потому что тут голые и незамороченные факты.
Спрашивайте, пишите, подскажу, если что ;-)

Да прибудет с вами великая сила!

Добавлено @ 15:11
Поиграйтесь с классами, поищите баги у меня в коде, предложите свои улучшения, научитесь всем пользоваться: вы большие мальчики/девочки - сможете.

Это сообщение отредактировал(а) Rickert - 20.10.2008, 03:45


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
AntonN
Дата 19.10.2008, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: нет
Всего: 18



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



--------------------
user posted image
PM MAIL WWW   Вверх
Lazin
Дата 19.10.2008, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: нет
Всего: 154



для чего нужны строки, или списки? ну и тем более совсем непонятно для чего в графическом движке может пригодится класс вектор smile 
для танкистов: это была ирония
PM MAIL Skype GTalk   Вверх
AntonN
Дата 19.10.2008, 22:56 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: нет
Всего: 18



Lazin, хоть и ирония - выскажусь smile
Не списки - а двусвязные списки. И почему списки (и разница в односвязном и двусвязном), а не массивы, чем отличаются, что где лучше применять.
Зачем нужен вектор, что это вообще такое. Почему нет примера его использования (это ведь "на пальцах" "От и До") smile
Да и про "графический" ничего не сказано.

PS Автор сам сказал "спрашивайте, пишите" smile

Это сообщение отредактировал(а) AntonN - 19.10.2008, 22:57


--------------------
user posted image
PM MAIL WWW   Вверх
Lazin
Дата 19.10.2008, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: нет
Всего: 154



Цитата(AntonN @  19.10.2008,  22:56 Найти цитируемый пост)
Зачем нужен вектор, что это вообще такое

это точка, в 3-х мерном пространстве(разве названия переменных - x, y, z не вызвали поозрений?), правда у Rickert-а он реализован неканоничъно smile 
PM MAIL Skype GTalk   Вверх
AntonN
Дата 19.10.2008, 23:40 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: нет
Всего: 18



Lazin, не обязательно в трехмерном. Я знаю что такое вектор (в контексте геймдевелопмента), я про то, что в статье "движок на пальцах От и До" ожидалось объяснения, что такое вектор и чем он лучше хотя бы "обычных" переменных углов и значения скорости, и хотя бы внятный пример использования.


--------------------
user posted image
PM MAIL WWW   Вверх
Rickert
Дата 20.10.2008, 03:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 6
Всего: 52



  • Если человек не знает что такое вектор и аналитическая геометрия - ему нечего делать в компьютерной графике. Пусть сначала получит хотя бы среднее образование.
  • Извините, но я не собираюсь устраивать дошкольный кружок, а предполагаю, что человек уже знаком с C++. Как уже говорил в своей "нулевой" статьей: часть материала я буду умышленно оставлять на размышлении читателя - чтобы шевелил мозгами. Это не детский сад, где вам будут ложить в рот кашу. Моей главной задачей стоит хорошо объяснить структуру движка и основные алгоритмы типа скелетной анимации и прочего. А элементарщину и вопросы типа "а зачем строка/списка, если есть stl?" - оставьте для холиваров.
  • Смысла вопроса "а зачем нужны векторы?" вообще не понимаю.
  • Думаю куда главнее читателю будет понять геометрический смысл перемножения матриц на векторы, в скелетной анимации, или понять почему же всё-таки жёсткое ограничение на кол-во fps - это путь для настоящих джедаев и ценителлей честных правил игры.
Цитата(Lazin @  19.10.2008,  23:33 Найти цитируемый пост)
это точка, в 3-х мерном пространстве(разве названия переменных - x, y, z не вызвали поозрений?), правда у Rickert-а он реализован неканоничъно

Неканонично - это как? smile

Цитата(AntonN @  19.10.2008,  23:40 Найти цитируемый пост)
Lazin, не обязательно в трехмерном. Я знаю что такое вектор (в контексте геймдевелопмента), я про то, что в статье "движок на пальцах От и До" ожидалось объяснения, что такое вектор и чем он лучше хотя бы "обычных" переменных углов и значения скорости, и хотя бы внятный пример использования. 

Что значит "в контексте геймдевелопмента"? Что в контексте стереометрии или анал. геом. вектор - другое существо?

Это сообщение отредактировал(а) Rickert - 20.10.2008, 04:25


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Lazin
Дата 20.10.2008, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: нет
Всего: 154



Цитата(Rickert @  20.10.2008,  03:41 Найти цитируемый пост)
Неканонично - это как?

Обычно, для преобразования координат используют матрицы, для двухмерного случая, сам вектор должен быть 3х мерным
|x, y, 1|'  а матрица описывающая преобразования ад ним должна быть размерности 3х3, в этом случае любое преобразование над координатами можно получить умножением вектора на соответствующую матрицу, помимо этого такие матрицы можно перемножать, это очень удобно, так как не нужно писать ф-ю поворачивающую вектор на нужный угол, ф-ю смещающую по х и по у и тд.. к тому-же если действий много, достаточно просто перемножить матрицы которыми эти действия описываются, а потом с помощью полученой матрицы преобразовать координаты вершин
http://www.compgraphics.info/3D/3d_definitions.php
PM MAIL Skype GTalk   Вверх
Rickert
Дата 20.10.2008, 08:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 6
Всего: 52



Lazin, и как это связано с нашим классом вектора? В чём неканоничность - я слова этого понять не могу?
Да, для преобразований большенство использует умножение на матрицу (кстати не понимая что происходит с геометрической точки зрения), но что нам мешает применить матрицу к нашему вектору?
Я это проделываю, и мы будем это проделывать без каких - либо проблем.

Это сообщение отредактировал(а) Rickert - 20.10.2008, 08:27


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Lazin
Дата 20.10.2008, 08:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: нет
Всего: 154



Цитата(Rickert @  20.10.2008,  08:26 Найти цитируемый пост)
В чём неканоничность - я слова этого понять не могу?

мне это слово нравится smile 
просто в этом классе нет метода для умножения на матрицу, что не очень удобно, вот поэтому я так и сказал...
PM MAIL Skype GTalk   Вверх
Rickert
Дата 20.10.2008, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 6
Всего: 52



Вопрос того надо ли подобные методы прописывать в класс, или держите в спец. синглтоне обсуждался ни один раз. Тогда все вместе пришли к выводы, что вместо того чтобы забивать память под одну и туже процедуру тысячи раз, лучше написать единожды.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
noKEmoH
Дата 30.10.2008, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 30.10.2008

Репутация: нет
Всего: нет



Если движок уже существует и находится в режиме отладки или оптимизации то, ничего...

а если он на стадии разработки то я бы предложил в векторе место x y z использовать массив на 3 элемента, тогда не возникнет проблем прохождения массива векторов указателями.

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


Это сообщение отредактировал(а) noKEmoH - 31.10.2008, 01:34
PM MAIL   Вверх
Rickert
Дата 31.10.2008, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 6
Всего: 52



Цитата(noKEmoH @  30.10.2008,  23:14 Найти цитируемый пост)
а если он на стадии разработки то я бы предложил в векторе место x y z использовать массив на 3 элемента, тогда не возникнет проблем прохождения массива векторов указателями.

А зачем и чем это лучше?


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
noKEmoH
Дата 1.11.2008, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 30.10.2008

Репутация: нет
Всего: нет



у меня массив структур
Код

struct vect
{
  int x,y,z;
};
vect v_mas[3];

неполучилось связать с функциями glVertexPointer ... glDrawElements, а 
Код

struct vect
{
  int m[3];
};

заработало без проблем
PM MAIL   Вверх
Rickert
Дата 1.11.2008, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 6
Всего: 52



noKEmoH, а зачем его связывать? Модель (то что ты отображаешь), по определению состоит из вершин, а не векторов. Мухи - отдельно, котлеты - отдельно.

Это сообщение отредактировал(а) Rickert - 1.11.2008, 12:12


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование игр, графики и искуственного интеллекта"
Rickert

НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.

  • Литературу, связанную с программированием графики, обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы связанные с программированием графики и мультимедии на языках С++ и Delphi
  • Вопросы по реализации алгоритмов рассматриваются здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема »


 




[ Время генерации скрипта: 0.1112 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.