Example #1
0
bool Sum::CombineLikeOperands( void )
{
	for( OperandList::Node* nodeA = operandList->Head(); nodeA; nodeA = nodeA->Next() )
	{
		Operand* operandA = nodeA->data;

		for( OperandList::Node* nodeB = nodeA->Next(); nodeB; nodeB = nodeB->Next() )
		{
			Operand* operandB = nodeB->data;

			if( operandA->IsScalar() && operandB->IsScalar() )
			{
				Operand* scalar = AddScalars( operandA, operandB );
				if( scalar )
				{
					operandList->InsertAfter()->data = scalar;
					operandList->Remove( nodeA );
					operandList->Remove( nodeB );
					return true;
				}
			}
			else if( dynamic_cast< Vector* >( operandA ) && dynamic_cast< Vector* >( operandB ) )
			{
				Vector* vectorA = ( Vector* )operandA;
				Vector* vectorB = ( Vector* )operandB;

				if( 0 == strcmp( vectorA->GetName(), vectorB->GetName() ) )
				{
					Operand* scalarA = vectorA->GetScalar();
					Operand* scalarB = vectorB->GetScalar();

					vectorA->SetScalar( 0, false );
					vectorB->SetScalar( 0, false );

					if( !scalarA )
					{
						NumericScalar* numericScalar = new NumericScalar();
						numericScalar->SetReal( 1.0 );
						scalarA = numericScalar;
					}

					if( !scalarB )
					{
						NumericScalar* numericScalar = new NumericScalar();
						numericScalar->SetReal( 1.0 );
						scalarB = numericScalar;
					}

					Sum* scalar = new Sum();
					scalar->operandList->InsertAfter()->data = scalarA;
					scalar->operandList->InsertAfter()->data = scalarB;

					vectorB->SetScalar( scalar );
					operandList->Remove( nodeA );

					return true;
				}
			}
			else if( ( operandA->IsBlade() && operandB->IsBlade() ) ||
					( operandA->IsVersor() && operandB->IsVersor() ) )
			{
				Operation* operationA = ( Operation* )operandA;
				Operation* operationB = ( Operation* )operandB;

				if( OperationsAlike( operationA, operationB ) )
				{
					// Degenerates are removed well before we can get here, so this shouldn't happen.
					Vector* vector = operationB->FindLeadingVector();
					if( !vector )
					{
						Error* error = new Error();
						error->Format( "Sum expected to find a leading vector, but didn't." );
						throw error;
					}

					// An empty geometric product in either case will do fine.
					GeometricProduct* scalarA = operationA->StripScalars();
					GeometricProduct* scalarB = operationB->StripScalars();

					Sum* scalar = new Sum();
					scalar->operandList->InsertAfter()->data = scalarA;
					scalar->operandList->InsertAfter()->data = scalarB;

					vector->MarryWithScalar( scalar );
					operandList->Remove( nodeA );

					return true;
				}
			}
		}
	}

	return false;
}