Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/*
* 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;
}
Ejemplo n.º 3
0
/*
* 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;
}
Ejemplo n.º 4
0
/*
* 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;
}
Ejemplo n.º 5
0
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();

}