Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Ошибка: expression can't be evaluated


Автор: student0511 4.8.2007, 09:29
Приветствую ALL!
Пишу программку эмуляции движения шариков в 2D в окне Windows, понадобилось передать в одну из функций элементы массива структур по ссылке. Всё бы ничего, но  обращение к полям структуры  не выполняется, т.к. выдаёт ошибку  expession cannot bу evaluated, т.е. все данные потерянные, так ли это понимать? 
Вот отрывок кодв:

Описание структуры:
Код

struct Ball
{
 POINT pt[NUM];
 int xc, yc, R, x1, y1, x2, y2;
 double angle;
 };


Прототипы некоторых функций:

Код

bool CrossBS (HDC, Ball, Ball);//Определяет пересечение окружностей
/////////////////////////////////////////////////
void PillPoints(Ball&);///Вычисляет координаты точек, принадлежащих окружности, от 0 - 360 градусов 
////////////////////////////
void EntailBS(HDC, Ball&, Ball&);///Если окружности через шаг пересекутся, то эта функция огранизует сближение окружностей к границы соприкосновения .
//////////////////////////////////////////////////////////////////////////////////////
void coordEBS(Ball, Ball, const int, const int, double, POINT*&, POINT*&);//Вычисляет координаты точек,  в которых окружности должны столкнуться


А вот обработка сообщения WM_PAINT:
Код

case WM_PAINT:
      hdc = BeginPaint(hwnd, &ps);
      for(i = 0; i<2; i++)
            for(j = 0; j<2 && !f; j++)
                  if(i != j)
                    {
                      f = CrossBS(hdc, *(BS+i), *(BS+j));///Проверяет на пересечение  
                     if(f)
                         EntailBS(hdc, *(BS+i), *(BS+j));
                     }
      for(i = 0; i<2; i++)
      {       
       Ellipse(hdc, BS[i].x1, BS[i].y1, BS[i].x2, BS[i].y2);///Рисует окружности
       TextOut(hdc, BS[i].xc, BS[i].yc, buffer, sprintf(buffer, "%d", i));
      }

      if(!f)
      {
       for(i = 0; i<2; i++)
           CalcCoord(hdc, BS[i], cxClient, cyClient, BS[i].count1, BS[i].count2, BS[i].X, BS[i].fl);///Определяет текущие координаты
      }

     EndPaint(hwnd, &ps);

Описание функции CrossBS
Код

bool CrossBS(HDC hdc, Ball BS1, Ball BS2)
{
 CalcCoord(hdc, BS1, cxClient, cyClient, BS1.count1, BS1.count2, BS1.X, BS1.fl, f);///Заранее определяем столкновение двух
 CalcCoord(hdc, BS2, cxClient, cyClient, BS2.count1, BS2.count2, BS2.X, BS2.fl, f);///окружностей
 PillPoints(BS1);///Определяет координаты точек, принадлежащие окружностям BS1, BS2,  
 PillPoints(BS2);///для этого служит массив POINT pt[NUM](NUM = 360) 
 for(int i = 0; i<NUM; i++)
       for(int j = 0; j<NUM; j++)
            if(((*((BS1.pt) + i)).x == (*((BS2.pt)+j)).x) 
              &&
              ((*((BS1.pt) + i)).y == (*((BS2.pt)+j)).y))
                return (true);///окружности пересеклись
return (false);///нет
}

А вот и сама проблема - это функция void Entail(HDC, Ball&, Ball&)
Код

void EntailBS(HDC hdc, Ball& BS1, Ball& BS2)
{
 int Xc2 = 0, Yc2 = 0;
  POINT *A= new POINT, *B = new POINT;///Точки пересечния прямой с окружностями, проведеённая из цетра первой к цетру второй. 
  double Ta = 0;///угол, под которым наклонена данная прямая относительно горизонтали
 if(BS1.xc > BS2.xc && BS1.yc > BS2.yc)///вторая окружность находится в левом верхнем углу относительно первой
 {
  Xc2 = BS2.xc + 2*(BS1.xc - BS2.xc);
  Yc2 = BS2.yc;
  Ta = (double)atan((BS1.yc - Yc2)/(Xc2 - BS1.xc));
  coordEBS(BS1, BS2, Xc2, Yc2, Ta, A, B);
  BS2.xc+=(B->x - A->x);
  BS2.yc+=(A->y - B->y);
 }
 else
     if(BS1.xc > BS2.xc && BS1.yc < BS2.yc)///вторая окружность находится в левом нижнем углу относительно первой
     {
      Xc2 = BS2.xc + 2*(BS1.xc - BS2.xc);
      Yc2 = BS2.yc - 2*(BS2.yc - BS1.yc);
      Ta = (double)atan((BS1.yc - Yc2)/(Xc2 - BS1.xc));
      coordEBS(BS1, BS2, Xc2, Yc2, Ta, A, B);
      TextOut(hdc, 300, 300, "2", sizeof('2')-1);
      BS2.xc+=(B->x - A->x);
      BS2.yc-=(A->y - B->y);
     }
     else
         if(BS1.xc < BS2.yc && BS1.yc < BS2.yc)///вторая окружность находится в правом нижнем углу относительно первой
         {
          Xc2 = BS2.xc;
          Yc2 = BS2.yc - 2*(BS2.yc - BS1.yc);
          Ta = (double)atan((BS1.yc - Yc2)/(Xc2 - BS1.xc));
          coordEBS(BS1, BS2, Xc2, Yc2, Ta, A, B);
          BS2.xc-=(B->x - A->x);
          BS2.yc-=(A->y - B->y);
          TextOut(hdc, 300, 300, "3", sizeof('3')-1);
         }
         else
             if(BS1.xc < BS2.xc && BS1.yc > BS2.yc)//вторая окружность находится в правом верхнем углу относительно первой
             {
              Xc2 = BS2.xc;
              Yc2 = BS2.yc;
              Ta = (double)atan((BS1.yc - Yc2)/(Xc2 - BS1.xc));
              coordEBS(BS1, BS2, Xc2, Yc2, Ta, A, B);
              BS2.xc-=(B->x - A->x);
              BS2.yc+=(A->y - B->y);
              TextOut(hdc, 300, 300, "4", sizeof('4')-1);
             }
             else
                 TextOut(hdc, 300, 300, "5***", sizeof("5***")-1);///Эт ещё не все случаи, конечно, а код всё равно не пашет как надо :-(
 delete A;
 delete B;
 BS2.x1 = BS2.xc - BS2.R;
 BS2.y1 = BS2.yc - BS2.R;
 BS2.x2 = BS2.xc + BS2.R;
 BS2.y2 = BS2.yc + BS2.R;
}

Вообщем, чтобы было более понятно, как работает кодик: за основу я беру окружность находящуюся в правом верхнем углу, далее с пом. симметрии вычисляю центр этой окружности, т.е. фактически перемещаю второй "шар" в данный угол, если он расположён в любом другом. А потом вычисляю координаты точек пересечения прямой с первой окружностью и воображаемым "кругом", затем, зная их координаты,  легко вычислить модули проекции вектора, берущего своё начало из точки пересечения прямой с первой окружностью, заканчиваясь в точке пересечения со второй. А дальше совсем просто: перемещаю центр второй "реальной" окружности по модулям соответствующих проекций в зависимости от расположения. 
Функция void coordEBS(Ball, Ball, const int, const int, double, POINT*&, POINT*&);
Код

void coordEBS(Ball BS1, Ball BS2, const int Xc2, const int Yc2, double Ta, POINT*& A, POINT*& B)
{
 A->x = BS1.xc + BS1.R*cos(Ta); 
 A->y = BS1.yc + BS1.R*sin(Ta/);
 
 B->x = BS2.xc + BS2.R*cos(Ta + PI); 
 B->y = BS2.yc + BS2.R*sin(Ta + P);
}

Заведомо благодарен!

Автор: Dov 4.8.2007, 11:23
Так, глубоко не ходил. Чисто визуально. В ф-ции EntailBS в строке 20 и в строке 31 в if`ах лишние закрывающие скобки... Проверь пока это, дальше будет видно.  smile 

Автор: student0511 4.8.2007, 13:34
Эт опечатка. В коде всё нормул, а ошибка вылизает уже после запуска программки, указывая на 16 строку ф-ции EntailBS и другие аналог. строки. В окне Debug'a напротив всех полей при этом появляется надпись error: expession cannot bу evaluated, а что за ошибка такая? В каких случаях вылизает?

Автор: student0511 5.8.2007, 08:40
Я отредактировал первое сообщение, а именно код, там некоторые явные проблемы с логикой были  smile  , возможно, они и остались, но пока больше ничего не нашёл. И всё равно программа на данном этапе своём работает правильно только в 3-ем случае smile, и то, если угол Ta составляет 45 гр  smile  , а  во всех остальных случаях он почему-то принимает значение нуль(0.00000).  Вообщем,  мне очень интересно закончить программку, но никак не могу найти ошибку или коренной глюк в логике . Буду благодарен в решении данной проблемс  smile . И ещё раз повторюсь, что за ошибка error: expession cannot bу evaluated? В каких случаях чаще всего встречается?

Автор: Daevaorn 5.8.2007, 12:22
Цитата(student0511 @  5.8.2007,  09:40 Найти цитируемый пост)
 . И ещё раз повторюсь, что за ошибка error: expession cannot bу evaluated? В каких случаях чаще всего встречается? 

Уже бы давно посмотрел в документации к своему компилятору, а?)

Автор: student0511 6.8.2007, 08:31
На что указывает ошибка понятно даже без док, из перевода  smile  , но вот причина для меня остаётся неясна. Ещё обнаружил странное обстоятельство: при выполнении деления в строках
Код
Ta = (double)atan((BS1.yc - Yc2)/(Xc2 - BS1.xc)); 
 аргумент обратной тригонометрической функции всегда принимает значение нуль, проверил отдельно, присвоив результат отношения отдельной переменной, всё равно 0. Менял типы: float, double - тот же результат. Написал аналогичное выражение, только, используя функцию pow, выходит нормальный результат:
Код

Ta = (double)atan((BS1.yc - Yc2)*(pow((Xc2 - BS1.xc), (-1))));

 smile 
Эт что? Шутки компилятора (MSV C++ 6.0).
Библиотеки
Код

#include <iostream>
using namespace std;
#include <windows.h>
#include <math.h>



Автор: ksili 6.8.2007, 09:02
Цитата(student0511 @  6.8.2007,  13:31 Найти цитируемый пост)
аргумент обратной тригонометрической функции всегда принимает значение нуль

int делишь на int - получается int. попробуй так:
Код

 Ta = atan(((double)(BS1.yc) - Yc2)/((double)(Xc2) - BS1.xc));  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)