/** TODO: avoid recalculating when nothing changed */
	Matrix44 Entity2D::GetCenterTransformationMatrix()
	{
		Matrix44 matrix = Matrix44::Identity;
		matrix.Scale(Vector3::Create(m_vScale.X, m_vScale.Y, 1.0f));
		matrix.Rotate(Vector3::Create(0.0f, 0.0f, m_fRotation*Math::DegToRadFactor));		
		matrix.Translate(Vector3::Create(m_vPosition.X, m_vPosition.Y, 0.0f));

		// TODO: use type checking at initialization time in AddChild() and only use static_cast here		
		if(Entity2D* pEntity2D = GetAncestor<Entity2D>())
		{
			matrix *= pEntity2D->GetTransformationMatrix();
		}
		
		return matrix;
	}
Example #2
0
	//! returns true if the button is touched
	bool Button::IsTouched() const
	{
		Matrix44 transformation = Matrix44::Identity;
		transformation.Translate(-Vector3::Create(m_vCenter.X, m_vCenter.Y, 0.0f));
		transformation.Scale(Vector3::Create(m_vScale.X, m_vScale.Y, 1.0f));
		transformation.Rotate(Vector3::Create(0.0f, 0.0f, m_fRotation*Math::DegToRadFactor));		
		transformation.Translate(Vector3::Create(m_vOriginalPosition.X, m_vOriginalPosition.Y, 0.0f));
		if(Entity2D* p2DEntity = GetAncestor<Entity2D>())
		{
			transformation *= p2DEntity->GetTransformationMatrix();
		}

		Matrix44 inverse;
		if(transformation.GetInverse(inverse))
		{
			Vector2 vTouchPos = InputManager::Instance()->GetTouchState().vPosition;
			Vector3 invTouchPos3D = inverse.TransformVect(Vector3::Create(vTouchPos.X, vTouchPos.Y, 0.0f));
			Vector2 vInvTouchPos(invTouchPos3D.X, invTouchPos3D.Y);
			return GetBoundingBox().Contains(vInvTouchPos);
		}

		return false;
	}
Example #3
0
// Evolve rNode a specific time 
void Tree::Evolve(Node &rNode, double dTime)
{
	dTime = fabs(dTime);
	if(dTime < DBL_EPSILON)
		return; // Nothing to evolve
	
	//advance branch color
	branchColor += Nucleotide::ColorInc;
	
	// Substitutions
	unsigned int uNuc = 0;
	for(vector<Sequence>::iterator it = rNode.m_vSections.begin(); it != rNode.m_vSections.end(); ++it)
	{
		for(Sequence::iterator jt = it->begin(); jt != it->end(); ++jt)
		{
			// Skip any position that is a deletion
			if(jt->IsDeleted())
				continue;
			// Total Evolution Rate for the position
			double dTemp = dTime*jt->GetRate();
			if(dTemp < DBL_EPSILON)
				continue; // Invariant Site
			// if dTemp is different from the previous one, recalculate probability matrix
			if(dTemp != m_dOldTime)
			{
				m_dOldTime = dTemp;
				Vector4  vec;
				vec[0] = exp(dTemp*m_vecL[0]);
				vec[1] = exp(dTemp*m_vecL[1]);
				vec[2] = exp(dTemp*m_vecL[2]);
				vec[3] = exp(dTemp*m_vecL[3]);
				Matrix44 mat; mat.Scale(vec, m_matU);
				m_matSubst.Multiply(m_matV, mat);
				for(Matrix44::Pos i=0;i<4;++i)
				{
					m_matSubst(i,1) += m_matSubst(i,0);
					m_matSubst(i,2) += m_matSubst(i,1);
					//m_matSubst(i,3) = 1.0;
				}
			}
			// get the base of the current nucleotide and pick new base
			unsigned int uBase = jt->GetBase();
			dTemp = rand_real();
			if(dTemp < m_matSubst(uBase, 0))
				jt->SetBase(0);
			else if(dTemp < m_matSubst(uBase, 1))
				jt->SetBase(1);
			else if(dTemp < m_matSubst(uBase, 2))
				jt->SetBase(2);
			else
				jt->SetBase(3);

			++uNuc; // Increase position
		}
	}
	// Indel formation via Gillespie Algorithm

	// Check whether Indels are off
	if(m_dLambdaDel+m_dLambdaIns < DBL_EPSILON)
		return;

	// Get current length
	Sequence::size_type uLength = rNode.SeqLength();
	double dLength = (double)uLength;
	double dW = 1.0/m_funcRateSum(dLength);

	// Do indels
	for(double dt = rand_exp(dW); dt <= dTime; dt += rand_exp(dW))
	{
		// insertion or deletion
		if(rand_bool(m_funcRateIns(dLength)*dW))
		{
			//Insertion 
			Sequence::size_type ul = m_pInsertionModel->RandSize();
			Sequence::size_type uPos = (Sequence::size_type)rand_uint((uint32_t)uLength); // pos is in [0,L]
			// Construct sequence to be inserted
			Sequence seq;
			for(unsigned int uc = 0; uc < ul; ++uc)
			{
				Nucleotide nuc = RandomNucleotide(uc);
				nuc.SetColor(branchColor);
				seq.push_back(nuc);
			}
			// Find Position of Insertion
			Node::iterator itPos = rNode.SeqPos(uPos);
			if(itPos.first == rNode.m_vSections.end())
			{
				// Insert at end of sequence
				uLength += rNode.m_vSections.back().Insertion(
					rNode.m_vSections.back().end(), seq.begin(), seq.end());
			}
			else
			{
				// Insert inside sequence
				uLength += itPos.first->Insertion(itPos.second, seq.begin(), seq.end());
			}
		}
		else if(uLength > 0)
		{
			// Deletion
			// Draw random size and random pos and rearrange
			Sequence::size_type ul = m_pDeletionModel->RandSize();
			Sequence::size_type uPos = rand_uint((uint32_t)(uLength+ul-2));
			Sequence::size_type uB = max(ul-1, uPos); 
			Sequence::size_type uSize = min(ul-1+uLength, uPos+ul)-uB;
			
			// If GapLimits are on, only process deletion if it is completely inside the acceptance
			// region as defined by the GapLimit.  Check points are at sequence positions 0-uKeepFlank and 
			// uLength-1+uKeepFlank.  These become 0-uKeepFlank+ul-1 and uLength-1+uKeepFlank+ul-1,
			// when shifted to "deletion space".
			if(m_uKeepFlank == 0	|| ( (ul-1) < uPos+m_uKeepFlank && uPos < uLength-1+m_uKeepFlank ) ) {
				uB -= (ul-1);
				// Find deletion point
				Node::iterator itPos = rNode.SeqPos(uB);
				Sequence::size_type uTemp = uSize;
				uTemp -= itPos.first->Deletion(itPos.second, uTemp);
				// Delete uSize nucleotides begin sensitive to gaps that overlap sections
				for(++itPos.first; uSize && itPos.first != rNode.m_vSections.end(); ++itPos.first)
					uTemp -= itPos.first->Deletion(itPos.first->begin(), uTemp);
				uLength -= (uSize-uTemp);
			}
		}
		// update length
		dLength = (double)uLength;
		// new waiting time parameter
		dW = 1.0/m_funcRateSum(dLength);
	}
}