void calc_sphere(t_obj *obj, t_calc *calc, t_coor *coor) { float my_delta; t_my_c my_c; float k0; k0 = -1; calc_trans(calc, &my_c, obj); my_delta = (my_c.b * my_c.b) - (4 * my_c.a * my_c.c); if (my_delta == 0) k0 = (-1 * (my_c.b)) / (2 * my_c.a); else if (my_delta > 0) calc_d_spher(&my_c, my_delta, &k0); if (k0 > 0 && k0 < calc->val) change_to_sphere(coor, obj, &k0, calc); replace_point_sph(calc, obj); }
/* * return value(ans only 1*1) should be treated as int, Error */ Matrix* calc_rank(Matrix *p) { Matrix *oldAns = ans; int i, j, k; int count = 0; if (p == NULL) { //Error return NULL; } ans = NULL; if (p->m > p->n) { if (!calc_trans(p)) { //Error return NULL; } } else { if (!stor_createAns(p->m, p->n)) { //Error return NULL; } if (!stor_assign(ans, p)) { //Error return NULL; } } if (ans == NULL) { //Error return NULL; } for (i = 0; i < ans->m; i++) { k = count; while (k < ans->n && util_isZero(*stor_entry(ans, i, k))) k++; if (k >= ans->n) { continue; } if (k != count) { swapColum(ans, count, k); } if (util_isZero(*stor_entry(ans, i, count))) { //Error return NULL; } mulRow(ans, i, (double)1.0 / *stor_entry(ans, i, count)); if (!ans) { //Error return NULL; } for (j = i + 1; j < ans->m; j++) { addRow(ans, j, i, -*stor_entry(ans, j, count)); } count++; } if (!stor_createAns(1, 1)) { //Error return NULL; } *stor_entry(ans, 0, 0) = count; stor_freeMatrix(oldAns); return ans; }
/* * the eigvalue, 有可能在数学上出问题(虚数) Error */ Matrix* calc_eig(Matrix* p) { Matrix *oldAns = ans, *oldAns2; Matrix *temp = NULL,*temp2 = NULL; Matrix *v = NULL; double r1; int i, j, k = 0; if (p == NULL) { //Error return NULL; } if (p->m != p->n) { //Error return NULL; } if (!stor_createMatrix(&v, p->m, 1)) { //Error return NULL; } if (!stor_createMatrix(&temp, p->m, p->n)) { //Error return NULL; } if (!stor_createMatrix(&temp2, p->m, p->n)) { //Error return NULL; } if (!stor_assign(temp, p)) { //Error return NULL; } for (i = 0; i < p->n - 2; i++) { for (j = 0; j < p->m; j++) { *stor_entry(v, j, 0) = *stor_entry(temp, j, i); } if (!householder(v, i + 1)) { //Error return NULL; } oldAns2 = ans; ans = NULL; if (!calc_mul(calc_mul(oldAns2, temp), oldAns2)) //H*A*H { //Error return NULL; } stor_freeMatrix(temp); temp = ans; ans = NULL; stor_freeMatrix(oldAns2); } //temp is 拟三角阵 while (k<=500 && !isUpTrian(temp))//最多500次迭代 { k++; ans = NULL; if (!(temp2 = calc_eye(p->n))) { //Error return NULL; } ans = NULL; for (i = 0; i < p->n - 1; i++) { if (!calc_eye(p->n)) { //Error return NULL; } r1 = sqrt(*stor_entry(temp, i, i) * *stor_entry(temp, i, i) + *stor_entry(temp, i + 1, i)* *stor_entry(temp, i + 1, i)); if (util_isZero(r1)) { //Error return NULL; } *stor_entry(ans, i, i) = *stor_entry(temp, i, i) / r1; *stor_entry(ans, i + 1, i + 1) = *stor_entry(temp, i, i) / r1; *stor_entry(ans, i + 1, i) = -*stor_entry(temp, i + 1, i) / r1; *stor_entry(ans, i, i + 1) = *stor_entry(temp, i + 1, i) / r1; oldAns2 = ans; ans = NULL; if (!calc_mul(temp2, calc_trans(oldAns2)))//Q { //Error return NULL; } stor_freeMatrix(temp2); temp2 = ans; ans = NULL; if (!calc_mul(oldAns2, temp))//R { //Error return NULL; } stor_freeMatrix(temp); temp = ans; ans = NULL; stor_freeMatrix(oldAns2); } if (!calc_mul(temp, temp2)) { //Error return NULL; } stor_freeMatrix(temp); temp = ans; } //优化迭代, 好像可以证明RQ一定是拟上三角阵 for (i = 0; i < p->m; i++) { for (j = 0; j < p->n; j++) { if (i != j) *stor_entry(ans, i, j) = 0; } } return ans; }
/* * H*x will make [c+2~m] zero, c is script, Error */ static Matrix* householder(Matrix *v, int c) { Matrix* oldAns = ans; Matrix* oldAns2; Matrix* temp = NULL; int i; double norm; int k; if (v == NULL) { //Error return NULL; } if (v->n != 1) { //Error return NULL; } ans = NULL; if (!stor_createMatrix(&temp, v->m, 1)) { //Error return NULL; } if (!stor_assign(temp, v)) { //Error return NULL; } for (i = 0; i < c; i++) { *stor_entry(temp, i, 0) = 0; } if (!calc_norm(temp))//NULL { //Error return NULL; } norm = *stor_entry(ans, 0, 0); k = c; *stor_entry(temp, k, 0) += norm; if (!calc_norm(temp)) { //Error return NULL; } norm = *stor_entry(ans, 0, 0); if (util_isZero(norm)) { //Error return NULL; } if (!calc_numMul(calc_mul(temp, calc_trans(temp)),(double)2.0/(norm*norm))) { //Error return NULL; } oldAns2 = ans; ans = NULL; if (!calc_sub(calc_eye(temp->m), oldAns2)) { //Error return NULL; } stor_freeMatrix(oldAns2); stor_freeMatrix(oldAns); return ans; }
void Master::Run() { // Event loop while(_exitFlag == false) { // Wait for a new connection from _userInterfaceServer.Accept(); // Client error int error = USER_INTERFACE_SERVER_OK; // Loop getting commands from user as long as a client is connected while (error != USER_INTERFACE_SERVER_ERROR) { // Get command from client error = _userInterfaceServer.GetCommand(); // If client received a command call barrier if (error == USER_INTERFACE_SERVER_OK) { _communicator -> Barrier(); } #ifdef SAGE // SAGE message sageMessage msg; // Check for SAGE message if (_sageInf.checkMsg(msg, false) > 0) { // Get SAGE message data char* data = (char*) msg.getData(); // Determine message switch(msg.getCode()) { // Quit case APP_QUIT: // Send exit command to UI _userInterfaceServer.SendCommandExit(); // Send exit command UpdateCommandExit(); // Stop this loop error = USER_INTERFACE_SERVER_ERROR; break; // Click event case EVT_CLICK: { // Click event x and y location normalized to size of window float clickX, clickY; // Ckick device Id, button Id, and is down flag int clickDeviceId, clickButtonId, clickIsDown, clickEvent; // Parse message sscanf(data, "%d %f %f %d %d %d", &clickDeviceId, &clickX, &clickY, &clickButtonId, &clickIsDown, &clickEvent); // If down event for EVT_PAN if (clickIsDown && clickEvent == EVT_PAN) { // Set initial position of click event _translatePosition[0] = clickX; _translatePosition[1] = clickY; } // If down event for EVT_ZOOM if (clickIsDown && clickEvent == EVT_ZOOM) { // Set initial position of click event _scalePosition[0] = clickX; _scalePosition[1] = clickY; // Calculate the location of the device in world space float initX = (_scalePosition[0] * (_totalDisplayFrustum[1] - _totalDisplayFrustum[0])) + _totalDisplayFrustum[0]; float initY = (_scalePosition[1] * (_totalDisplayFrustum[3] - _totalDisplayFrustum[2])) + _totalDisplayFrustum[2]; // Calculate the location of the device with respect to the // untransfomred object in world space initX -= _worldTranslate[0]; initY -= _worldTranslate[1]; initX /= _worldScale[0]; initY /= _worldScale[1]; // Keep these values _scalePositionUntransformed[0] = initX; _scalePositionUntransformed[1] = initY; } // If down event for EVT_ROTATE if (clickIsDown && clickEvent == EVT_ROTATE) { // Set inital position _rotatePosition[0] = clickX; _rotatePosition[1] = clickY; // Normalize object's translation to (-1.0, 1.0) float nTx = (_worldTranslate[0] - _totalDisplayFrustum[0]) / (_totalDisplayFrustum[1] - _totalDisplayFrustum[0]); nTx = (nTx * 2.0) - 1.0; float nTy = (_worldTranslate[1] - _totalDisplayFrustum[2]) / (_totalDisplayFrustum[3] - _totalDisplayFrustum[2]); nTy = (nTy * 2.0) - 1.0; // Normalize puck's position to (-1.0, 1.0) float nXpos = (clickX * 2.0) - 1.0; float nYpos = (clickY * 2.0) - 1.0; // Start trackball _eventTrackball.Start(nXpos - nTx, nYpos - nTy); } // If up event if (clickIsDown == 0) { // Force the renderer to update UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); } // Done with EVT_CLICK case break; } // Pan event case EVT_PAN: { // Pan event properties int panDeviceId; // Pan event x and y location and change in x, y and z direction // normalized to size of window float panX, panY, panDX, panDY, panDZ; sscanf(data, "%d %f %f %f %f %f", &panDeviceId, &panX, &panY, &panDX, &panDY, &panDZ); // Print event //fprintf(stderr, // "PAN MESSAGE: %f %f %f %f %f\n", // panX, panY, panDX, panDY, panDZ); // Calculate amount the device has moved in world space since it // was clicked. float deltaT[2] = {((_translatePosition[0]- (_translatePosition[0] + panDX)) * (_totalDisplayFrustum[1] - _totalDisplayFrustum[0])), ((_translatePosition[1]- (_translatePosition[1] + panDY)) * (_totalDisplayFrustum[3] - _totalDisplayFrustum[2]))}; // Add the offset _worldTranslate[0] -= deltaT[0]; _worldTranslate[1] -= deltaT[1]; // Determine translation matrix float T[16]; calc_trans(T, _worldTranslate[0], _worldTranslate[1], 0.0); // Send translation matrix to UI _userInterfaceServer.SendTranslationMatrix(T); // Set the translation matrix UpdateTranslationMatrix(T); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); // Update translate device position _translatePosition[0] += panDX; _translatePosition[1] += panDY; // Done with EVT_PAN case break; } // Zoom event case EVT_ZOOM: { // Zoom event properties int zoomDeviceId; // Zoom event x and y location and change in x, y and z direction // normalized to size of window float zoomX, zoomY, zoomDX, zoomDY, zoomDZ; sscanf(data, "%d %f %f %f %f %f", &zoomDeviceId, &zoomX, &zoomY, &zoomDX, &zoomDY, &zoomDZ); // Print event //fprintf(stderr, // "ZOOM MESSAGE: %f %f %f %f %f\n", // zoomX, zoomY, zoomDX, zoomDY, zoomDZ); // Calcualte amount the device has moved float deltaZ[2] = {-zoomDX, -zoomDY}; // Update world scale by delta _worldScale[0] *= 1.0 - (deltaZ[0] + deltaZ[1]); _worldScale[1] *= 1.0 - (deltaZ[0] + deltaZ[1]); _worldScale[2] *= 1.0 - (deltaZ[0] + deltaZ[1]); // Don't let world scale go below 1.0 if (_worldScale[0] < 1.0) _worldScale[0] = 1.0; if (_worldScale[1] < 1.0) _worldScale[1] = 1.0; if (_worldScale[2] < 1.0) _worldScale[2] = 1.0; // Determine scale matrix float S[16]; calc_scale(S, _worldScale[0], _worldScale[1], _worldScale[2]); // Calculate the initial location of the device in world space float initX = (zoomX * (_totalDisplayFrustum[1] - _totalDisplayFrustum[0])) + _totalDisplayFrustum[0]; float initY = (zoomY * (_totalDisplayFrustum[3] - _totalDisplayFrustum[2])) + _totalDisplayFrustum[2]; // Determine new translation based on scale _worldTranslate[0] = initX - (_scalePositionUntransformed[0] * _worldScale[0]); _worldTranslate[1] = initY - (_scalePositionUntransformed[1] * _worldScale[1]); // Determine new translation matrix float T[16]; calc_trans(T, _worldTranslate[0], _worldTranslate[1], 0.0); // Send scale matrix to UI _userInterfaceServer.SendScaleMatrix(S); // Send translation matrix to UI _userInterfaceServer.SendTranslationMatrix(T); // Set the scale and translation matrices UpdateScaleMatrix(S); _communicator -> Barrier(); UpdateTranslationMatrix(T); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); // Done with EVT_ZOOM case break; } // Rotate event case EVT_ROTATE: { // Rotate event properties int rotateDeviceId; // Rotate event x and y location and change in x, y and z direction // normalized to size of window float rotateX, rotateY, rotateDX, rotateDY, rotateDZ; sscanf(data, "%d %f %f %f %f %f", &rotateDeviceId, &rotateX, &rotateY, &rotateDX, &rotateDY, &rotateDZ); //fprintf(stderr, "EVT_ROTATE: %f %f %f %f %f\n", // rotateX, rotateY, rotateDX, rotateDY, rotateDZ); // Normalize object's translation to (-1.0, 1.0) float nTx = (_worldTranslate[0] - _totalDisplayFrustum[0]) / (_totalDisplayFrustum[1] - _totalDisplayFrustum[0]); nTx = (nTx * 2.0) - 1.0; float nTy = (_worldTranslate[1] - _totalDisplayFrustum[2]) / (_totalDisplayFrustum[3] - _totalDisplayFrustum[2]); nTy = (nTy * 2.0) - 1.0; // Normalize puck's position to (-1.0, 1.0) float nXpos = (_rotatePosition[0] * 2.0) - 1.0; float nYpos = (_rotatePosition[1] * 2.0) - 1.0; // Update trackball _eventTrackball.Update(nXpos - nTx, nYpos - nTy); // Get rotation from trackball float R[16]; _eventTrackball.GetRotationMatrix(R); // Send rotation matrix to UI _userInterfaceServer.SendRotationMatrix(R); // Set the rotation matrix UpdateRotationMatrix(R); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); UpdateCommandRender(); _communicator -> Barrier(); _rotatePosition[0] += rotateDX; _rotatePosition[1] += rotateDY; // Done with EVT_ZOOM case break; } } } #endif } } // One last barrier _communicator -> Barrier(); }