Приветствую 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); }
|
Заведомо благодарен! |