В споре рождается истина

- А я так не думаю!

Архив Июль 2010

Как нарисовать стрелку

оставьте комментарий »

Лично у меня такая задача возникала не один раз, поэтому придется посвятить ей целый пост.

Итак, даны координаты начала и конца вектора, надо нарисовать стрелку.

Результат будет вот такой:

А теперь к тому, как собственно рисуется стрелка. Чертеж, сделанный в paint (кликабельно):

Пусть исходный отрезок AB.

Повернем точку B вокруг точки A на alpha и на -alpha.  Укоротим полученные векторы так, чтобы их длина составляла M (M <= 1) от длины вектора AB. Тогда получим векторы AC и AD.

Соединим точки A и B, B и C, B и D отрезками – стрелка нарисована.

Теперь как это выглядит конкретно на C++ и SFML:

void RotatePoint(double &x, double &y, double ox, double oy, double alpha)
{
  double xn, yn;
  xn = ox + (x-ox)*cos(alpha) - (y-oy)*sin(alpha);
  yn = oy + (x-ox)*sin(alpha) + (y-oy)*cos(alpha);
  x = xn;
  y = yn;
}

void DecreaseVector(double x1, double y1, double &x_n1, double &y_n1)
{
  double dx = (x_n1 - x1)*0.9;
  double dy = (y_n1 - y1)*0.9;
  x_n1 = x1 + dx;
  y_n1 = y1 + dy;
}

void SFMLVizualizer::DrawArrow(int x1, int y1, int x2, int y2, int icolor)
{
  int red, green, blue;
  blue = icolor%255;
  icolor/=255;
  green = icolor%255;
  icolor/=255;
  red = icolor;
  sf::Color color = sf::Color(red, green, blue);

  int line_width = 1;
  w->Draw(sf::Shape::Line(x1, y1, x2, y2, line_width, color));

  double x_n1, y_n1, x_n2, y_n2;
  x_n1 = x_n2 = x2;
  y_n1 = y_n2 = y2;

  RotatePoint(x_n1, y_n1, x1, y1, pi/48);
  RotatePoint(x_n2, y_n2, x1, y1, -pi/48);
  DecreaseVector(x1, y1, x_n1, y_n1);
  DecreaseVector(x1, y1, x_n2, y_n2);

  w->Draw(sf::Shape::Line(x_n1, y_n1, x2, y2, line_width, color));
  w->Draw(sf::Shape::Line(x_n2, y_n2, x2, y2, line_width, color));
}

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

Написано jtimv

26.07.2010 в 03:44

Опубликовано в Программирование, Проекты

Отмечено как ,

Debug me!

с одним комментарием

Вы же знаете, что такое Crack me? Ну, я уверен, что все даже игрались когда-то. Как там, берем Crack me #2 (потому что #1 уже одолели), открываем в IDA Pro Disassembler и вперед…  Исправляем JNE на JNZ или что-то в таком духе.

А недавно я видел человека, который писал игру “Дурак” на C++ с использованием классов.

И все было бы прекрасно, если бы не один глюк.

Сначала кажется, что глючим мы – когда пишем код. Но потом мы ищем ошибку и не находим ее. Потом ищем еще раз – и опять не находим! Очевдно, что глючим не мы. Глючит компилятор, операционка, клавиатура, все, что угодно – только не мы. Потому что код просмотрен и проверен уже 100 раз!

На этот раз глючила колода. Я не шучу. Не помню деталей, но по-моему колода имела метод


Card Deck::GetCard()

который возвращал из колоды карту.

Удивительно, но после раздачи 6 карт компьютеру и 6 карт человеку в колоде оставалось то 24, то 23 карты. Причем чаще 24.

Отладка происходила довольно тупым способом. Сперва повесили printf()’ы сразу после { и перед }, в которых выводили все, что могло принести какую-то пользу: количество карт в колоде, карты на руках у игроков.

Потом додумались до “инварианта цикла”, круто?

Прям в лучших традициях Кормэна! Суть в том, что deck.cards_count() + player1.cards_count() + player2.cards_count() == 36 всегда.

Таким образом повесив if (…) мы дали программе возможность самой определять, произошла ли ошибка.

Потом пришлось все-таки делать обертки из printf()’ов еще для нескольких фукнций. В итоге определилось место ошибки (точно функцию не помню, но смысл такой же) :

bool Card::Exists()
{
  return this->num > 0;
}

Ошибка в num > 0 (надо было num >= 0).
По-моему, очень глупая ошибка. Связанная с невнимательностью и нетривиальной задумкой по поводу хранения карт в колоде.
Нет бы сделать List <Card> или Vector <Card>, так нет блин… )))

Но сам процесс отладки лично мне доставил удовольствие и вот, что я подумал.
А вдруг, кто-то, найдя очередную подобную ошибку, не просто исправит ее, а запишет, запомнит и потом на основе ее сделает “Debug me!”.
Да и вообще, сделать бы сайт для программистов. Куча мелких программ, в каждой какая-то ошибка, которую надо исправить! Вау.
Идея утопическая, конечно, потому что дай только такому сайту появиться – сразу студенты запостят свои лабы.

Написано jtimv

09.07.2010 в 22:18

Опубликовано в Дамп мыслей

Follow

Get every new post delivered to your Inbox.