00001
00023 #include <cmath>
00024 #include <iostream>
00025 #include <vector>
00026
00027 #include "popassert.h"
00028 #include "CVector3f.h"
00029 #include "compute.h"
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00048 CValue* CValue::GetNewAddition(CValue* pLeftOperand, CValue* pRightOperand)
00049 {
00050 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00051 POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00052
00053 float Number1, Number2;
00054 if (pLeftOperand->IsConstant(&Number1) &&
00055 pRightOperand->IsConstant(&Number2))
00056 {
00057 Number1 += Number2;
00058 delete pLeftOperand;
00059 delete pRightOperand;
00060 return new CNumber(Number1);
00061 }
00062
00063
00064 switch ( (pLeftOperand->IsAddNeutralElem() << 1) +
00065 (pRightOperand->IsAddNeutralElem() << 0) )
00066 {
00067 case ( (0 << 1) + (0 << 0) ):
00068 return (new CAddition(pLeftOperand, pRightOperand));
00069 break;
00070 case ( (1 << 1) + (0 << 0) ):
00071 delete pLeftOperand;
00072 return pRightOperand;
00073 break;
00074 case ( (0 << 1) + (1 << 0) ):
00075 delete pRightOperand;
00076 return pLeftOperand;
00077 break;
00078 default:
00079
00080 POP_ILLEGAL("Should not get here");
00081 return NULL;
00082 break;
00083 }
00084 }
00085
00086
00093 CValue* CValue::GetNewSubstraction(CValue* pLeftOperand, CValue* pRightOperand)
00094 {
00095 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00096 POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00097
00098 float Number1, Number2;
00099 if (pLeftOperand->IsConstant(&Number1) &&
00100 pRightOperand->IsConstant(&Number2))
00101 {
00102 Number1 -= Number2;
00103 delete pLeftOperand;
00104 delete pRightOperand;
00105 return (new CNumber(Number1));
00106 }
00107
00108
00109 switch ( (pLeftOperand->IsAddNeutralElem() << 1) +
00110 (pRightOperand->IsAddNeutralElem() << 0) )
00111 {
00112 case ( (0 << 1) + (0 << 0) ):
00113 return (new CSubstraction(pLeftOperand, pRightOperand));
00114 break;
00115 case ( (1 << 1) + (0 << 0) ):
00116 delete pLeftOperand;
00117 return (new COpposite(pRightOperand));
00118 break;
00119 case ( (0 << 1) + (1 << 0) ):
00120 delete pRightOperand;
00121 return pLeftOperand;
00122 break;
00123 default:
00124
00125 POP_ILLEGAL("Should not get here");
00126 return NULL;
00127 break;
00128 }
00129 }
00130
00131
00138 CValue* CValue::GetNewProduct(CValue* pLeftOperand, CValue* pRightOperand)
00139 {
00140 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00141 POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00142
00143 float Number1, Number2;
00144 if (pLeftOperand->IsConstant(&Number1)
00145 && pRightOperand->IsConstant(&Number2))
00146 {
00147 Number1 *= Number2;
00148 delete pLeftOperand;
00149 delete pRightOperand;
00150 return (new CNumber(Number1));
00151 }
00152
00153
00154 switch ( (pLeftOperand->IsConstant() << 1) +
00155 (pRightOperand->IsConstant() << 0) )
00156 {
00157 case ( (0 << 1) + (0 << 1) ):
00158 return (new CProduct(pLeftOperand, pRightOperand));
00159 break;
00160 case ( (1 << 1) + (0 << 0) ):
00161 if ( pLeftOperand->IsMultAbsorbElem() )
00162 {
00163 delete pLeftOperand;
00164 delete pRightOperand;
00165 return (new CNumber(0));
00166 }
00167 else if (pLeftOperand->IsMultNeutralElem())
00168 {
00169 delete pLeftOperand;
00170 return pRightOperand;
00171 }
00172 else
00173 {
00174 return (new CProduct(pLeftOperand, pRightOperand));
00175 }
00176 break;
00177 case ( (0 << 1) + (1 << 0) ):
00178 if ( pRightOperand->IsMultAbsorbElem() )
00179 {
00180 delete pLeftOperand;
00181 delete pRightOperand;
00182 return (new CNumber(0));
00183 }
00184 else if (pRightOperand->IsMultNeutralElem())
00185 {
00186 delete pRightOperand;
00187 return pLeftOperand;
00188 }
00189 else
00190 {
00191 return (new CProduct(pLeftOperand, pRightOperand));
00192 }
00193 break;
00194 default:
00195
00196 POP_ILLEGAL("Should not get here");
00197 return NULL;
00198 break;
00199 }
00200 }
00201
00202
00209 CValue* CValue::GetNewDivision(CValue* pLeftOperand, CValue* pRightOperand)
00210 {
00211 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00212 POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00213
00214 float Number1, Number2;
00215 if (pLeftOperand->IsConstant(&Number1) &&
00216 pRightOperand->IsConstant(&Number2))
00217 {
00218 if (Number2 == 0)
00219 throw;
00220
00221 Number1 /= Number2;
00222 delete pLeftOperand;
00223 delete pRightOperand;
00224 return (new CNumber(Number1));
00225 }
00226
00227
00228 switch ( (pLeftOperand->IsConstant() << 1) +
00229 (pRightOperand->IsConstant() << 0) )
00230 {
00231 case ( (0 << 1) + (0 << 1) ):
00232 return (new CDivision(pLeftOperand, pRightOperand));
00233 break;
00234 case ( (1 << 1) + (0 << 0) ):
00235 if ( pLeftOperand->IsMultAbsorbElem() )
00236 {
00237 delete pLeftOperand;
00238 delete pRightOperand;
00239 return (new CNumber(0));
00240 }
00241 else
00242 {
00243 return (new CDivision(pLeftOperand, pRightOperand));
00244 }
00245 break;
00246 case ( (0 << 1) + (1 << 0) ):
00247 if ( pRightOperand->IsMultAbsorbElem() )
00248 {
00249 throw;
00250 }
00251 else if (pRightOperand->IsMultNeutralElem())
00252 {
00253 delete pRightOperand;
00254 return pLeftOperand;
00255 }
00256 else
00257 {
00258 return (new CDivision(pLeftOperand, pRightOperand));
00259 }
00260 break;
00261 default:
00262
00263 POP_ILLEGAL("Should not get here");
00264 return NULL;
00265 break;
00266 }
00267 }
00268
00269
00276 CValue* CValue::GetNewOpposite(CValue* pLeftOperand)
00277 {
00278 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00279
00280 float Number;
00281 if (pLeftOperand->IsConstant(&Number))
00282 {
00283 delete pLeftOperand;
00284 return (new CNumber(-Number));
00285 }
00286 else
00287 {
00288 return (new COpposite(pLeftOperand) );
00289 }
00290 }
00291
00298 CValue* CValue::GetNewSqrt(CValue* pLeftOperand)
00299 {
00300 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00301
00302 float Number;
00303 if (pLeftOperand->IsConstant(&Number))
00304 {
00305 delete pLeftOperand;
00306
00307 if (Number < 0)
00308 throw;
00309
00310 return (new CNumber(sqrtf(Number)));
00311 }
00312 else
00313 {
00314 return (new CSqrt(pLeftOperand));
00315 }
00316 }
00317
00324 CValue* CValue::GetNewSin(CValue* pLeftOperand)
00325 {
00326 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00327
00328 float Number;
00329 if (pLeftOperand->IsConstant(&Number))
00330 {
00331 delete pLeftOperand;
00332 return (new CNumber(sinf(Number)));
00333 }
00334 else
00335 {
00336 return (new CSin(pLeftOperand) );
00337 }
00338 }
00339
00346 CValue* CValue::GetNewCos(CValue* pLeftOperand)
00347 {
00348 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00349
00350 float Number;
00351 if (pLeftOperand->IsConstant(&Number))
00352 {
00353 delete pLeftOperand;
00354 return (new CNumber(cosf(Number)));
00355 }
00356 else
00357 {
00358 return (new CCos(pLeftOperand) );
00359 }
00360 }
00361
00368 CValue* CValue::GetNewTan(CValue* pLeftOperand)
00369 {
00370 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00371
00372 float Number;
00373 if (pLeftOperand->IsConstant(&Number))
00374 {
00375 delete pLeftOperand;
00376 return (new CNumber(tanf(Number)));
00377 }
00378 else
00379 {
00380 return (new CTan(pLeftOperand) );
00381 }
00382 }
00383
00390 CValue* CValue::GetNewExp(CValue* pLeftOperand)
00391 {
00392 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00393
00394 float Number;
00395 if (pLeftOperand->IsConstant(&Number))
00396 {
00397 delete pLeftOperand;
00398 return (new CNumber(expf(Number)));
00399 }
00400 else
00401 {
00402 return (new CExp(pLeftOperand) );
00403 }
00404 }
00405
00412 CValue* CValue::GetNewLn(CValue* pLeftOperand)
00413 {
00414 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00415
00416 float Number;
00417 if (pLeftOperand->IsConstant(&Number))
00418 {
00419 delete pLeftOperand;
00420 return (new CNumber(logf(Number)));
00421 }
00422 else
00423 {
00424 return (new CLn(pLeftOperand) );
00425 }
00426 }
00427
00434 CValue* CValue::GetNewPow(CValue* pLeftOperand, CValue* pRightOperand)
00435 {
00436 POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00437 POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00438
00439 float Number1, Number2;
00440 if (pLeftOperand->IsConstant(&Number1) &&
00441 pRightOperand->IsConstant(&Number2))
00442 {
00443 if (Number1 == 0 && Number2 == 0)
00444 {
00445 throw;
00446 }
00447
00448 Number1 = pow(Number1, Number2);
00449 delete pLeftOperand;
00450 delete pRightOperand;
00451
00452 if ( Number1 == Number1 )
00453 {
00454 return (new CNumber(Number1));
00455 }
00456 else
00457 {
00458 throw;
00459 return NULL;
00460 }
00461 }
00462
00463
00464 switch ( (pLeftOperand->IsConstant() << 1) +
00465 (pRightOperand->IsConstant() << 0) )
00466 {
00467 case ( (0 << 1) + (0 << 1) ):
00468 return (new CPow(pLeftOperand, pRightOperand));
00469 break;
00470 case ( (1 << 1) + (0 << 0) ):
00471 if ( pLeftOperand->IsMultAbsorbElem() )
00472 {
00473 delete pLeftOperand;
00474 delete pRightOperand;
00475 return new CNumber(0);
00476 }
00477 else if ( pLeftOperand->IsMultNeutralElem() )
00478 {
00479 delete pLeftOperand;
00480 delete pRightOperand;
00481 return (new CNumber(1));
00482 }
00483 else
00484 {
00485 return (new CPow(pLeftOperand, pRightOperand));
00486 }
00487 break;
00488 case ( (0 << 1) + (1 << 0) ):
00489 if ( pRightOperand->IsMultAbsorbElem() )
00490 {
00491 delete pRightOperand;
00492 return pLeftOperand;
00493 return (new CNumber(1));
00494 }
00495 else if ( pRightOperand->IsMultNeutralElem() )
00496 {
00497 delete pRightOperand;
00498 return (pLeftOperand);
00499 }
00500 else
00501 {
00502 return (new CPow(pLeftOperand, pRightOperand));
00503 }
00504 break;
00505 default:
00506
00507 POP_ILLEGAL("Should not get here");
00508 return NULL;
00509 break;
00510 }
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00526 CAddition::CAddition(CValue* pLeftOperand, CValue* pRightOperand)
00527 : COperation(pLeftOperand, pRightOperand)
00528 {
00529 }
00530
00534 CSubstraction::CSubstraction(CValue* pLeftOperand, CValue* pRightOperand)
00535 : COperation(pLeftOperand, pRightOperand)
00536 {
00537 }
00538
00542 CProduct::CProduct(CValue* pLeftOperand, CValue* pRightOperand)
00543 : COperation(pLeftOperand, pRightOperand)
00544 {
00545 }
00546
00550 CDivision::CDivision(CValue* pLeftOperand, CValue* pRightOperand)
00551 : COperation(pLeftOperand, pRightOperand)
00552 {
00553 }
00554
00558 COpposite::COpposite(CValue* pLeftOperand)
00559 : COperation(pLeftOperand, NULL)
00560 {
00561 }
00562
00566 CSqrt::CSqrt(CValue* pLeftOperand)
00567 : COperation(pLeftOperand, NULL)
00568 {
00569 }
00570
00574 CSin::CSin(CValue* pLeftOperand)
00575 : COperation(pLeftOperand, NULL)
00576 {
00577 }
00578
00582 CCos::CCos(CValue* pLeftOperand)
00583 : COperation(pLeftOperand, NULL)
00584 {
00585 }
00586
00590 CTan::CTan(CValue* pLeftOperand)
00591 : COperation(pLeftOperand, NULL)
00592 {
00593 }
00594
00598 CExp::CExp(CValue* pLeftOperand)
00599 : COperation(pLeftOperand, NULL)
00600 {
00601 }
00602
00606 CLn::CLn(CValue* pLeftOperand)
00607 : COperation(pLeftOperand, NULL)
00608 {
00609 }
00610
00614 CPow::CPow(CValue* pLeftOperand, CValue* pRightOperand)
00615 : COperation(pLeftOperand, pRightOperand)
00616 {
00617 }
00618
00622 CVariable::CVariable(TYPE_VARIABLE Type)
00623 {
00624 m_Type = Type;
00625 }
00626
00630 CNumber::CNumber(float Number)
00631 {
00632 m_Number = Number;
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00648 CValue* CAddition::GetCopy() const
00649 {
00650 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00651 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00652
00653 return new CAddition(m_pLeftOperand->GetCopy(), m_pRightOperand->GetCopy());
00654 }
00655
00660 CValue* CSubstraction::GetCopy() const
00661 {
00662 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00663 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00664
00665 return new CSubstraction(m_pLeftOperand->GetCopy(),
00666 m_pRightOperand->GetCopy());
00667 }
00668
00673 CValue* CProduct::GetCopy() const
00674 {
00675 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00676 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00677
00678 return new CProduct(m_pLeftOperand->GetCopy(), m_pRightOperand->GetCopy());
00679 }
00680
00685 CValue* CDivision::GetCopy() const
00686 {
00687 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00688 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00689
00690 return new CDivision(m_pLeftOperand->GetCopy(), m_pRightOperand->GetCopy());
00691 }
00692
00697 CValue* COpposite::GetCopy() const
00698 {
00699 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00700
00701 return new COpposite(m_pLeftOperand->GetCopy());
00702 }
00703
00708 CValue* CSqrt::GetCopy() const
00709 {
00710 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00711
00712 return new CSqrt(m_pLeftOperand->GetCopy());
00713 }
00714
00719 CValue* CSin::GetCopy() const
00720 {
00721 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00722
00723 return new CSin(m_pLeftOperand->GetCopy());
00724 }
00725
00730 CValue* CCos::GetCopy() const
00731 {
00732 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00733
00734 return new CCos(m_pLeftOperand->GetCopy());
00735 }
00736
00741 CValue* CTan::GetCopy() const
00742 {
00743 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00744
00745 return new CTan(m_pLeftOperand->GetCopy());
00746 }
00747
00752 CValue* CExp::GetCopy() const
00753 {
00754 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00755
00756 return new CExp(m_pLeftOperand->GetCopy());
00757 }
00758
00763 CValue* CLn::GetCopy() const
00764 {
00765 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00766
00767 return new CLn(m_pLeftOperand->GetCopy());
00768 }
00769
00774 CValue* CPow::GetCopy() const
00775 {
00776 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00777 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00778
00779 return new CPow(m_pLeftOperand->GetCopy(), m_pRightOperand->GetCopy());
00780 }
00781
00785 CValue* CVariable::GetCopy() const
00786 {
00787 return new CVariable(m_Type);
00788 }
00789
00793 CValue* CNumber::GetCopy() const
00794 {
00795 return new CNumber(m_Number);
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00810 float CAddition::Compute(const CVector3f& Point) const
00811 {
00812 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00813 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00814
00815 return (m_pLeftOperand->Compute(Point) + m_pRightOperand->Compute(Point));
00816 }
00817
00821 float CSubstraction::Compute(const CVector3f& Point) const
00822 {
00823 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00824 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00825
00826 return (m_pLeftOperand->Compute(Point) - m_pRightOperand->Compute(Point));
00827 }
00828
00832 float CProduct::Compute(const CVector3f& Point) const
00833 {
00834 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00835 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00836
00837 return (m_pLeftOperand->Compute(Point) * m_pRightOperand->Compute(Point));
00838 }
00839
00843 float CDivision::Compute(const CVector3f& Point) const
00844 {
00845 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00846 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00847
00848 return (m_pLeftOperand->Compute(Point) / m_pRightOperand->Compute(Point));
00849 }
00850
00854 float COpposite::Compute(const CVector3f& Point) const
00855 {
00856 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00857
00858 return (-(m_pLeftOperand->Compute(Point)));
00859 }
00860
00864 float CSqrt::Compute(const CVector3f& Point) const
00865 {
00866 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00867
00868 return (sqrtf(m_pLeftOperand->Compute(Point)));
00869 }
00870
00874 float CSin::Compute(const CVector3f& Point) const
00875 {
00876 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00877
00878 return (sinf(m_pLeftOperand->Compute(Point)));
00879 }
00880
00884 float CCos::Compute(const CVector3f& Point) const
00885 {
00886 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00887
00888 return (cosf(m_pLeftOperand->Compute(Point)));
00889 }
00890
00894 float CTan::Compute(const CVector3f& Point) const
00895 {
00896 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00897
00898 return (tanf(m_pLeftOperand->Compute(Point)));
00899 }
00900
00904 float CExp::Compute(const CVector3f& Point) const
00905 {
00906 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00907
00908 return (expf(m_pLeftOperand->Compute(Point)));
00909 }
00910
00914 float CLn::Compute(const CVector3f& Point) const
00915 {
00916 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00917
00918 return (logf(m_pLeftOperand->Compute(Point)));
00919 }
00920
00924 float CPow::Compute(const CVector3f& Point) const
00925 {
00926 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00927 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00928
00929 return (powf(m_pLeftOperand->Compute(Point), m_pRightOperand->Compute(Point)));
00930 }
00931
00936 float CVariable::Compute(const CVector3f& Point) const
00937 {
00938 switch (m_Type)
00939 {
00940 case (TYPE_X): return Point.x; break;
00941 case (TYPE_Y): return Point.y; break;
00942 case (TYPE_Z): return Point.z; break;
00943 default: POP_ILLEGAL("Should not get here"); return 0; break;
00944 }
00945 }
00946
00950 float CNumber::Compute(const CVector3f& Point) const
00951 {
00952 return m_Number;
00953 }
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00971 CValue* CAddition::Derive(TYPE_VARIABLE Type) const
00972 {
00973 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00974 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00975
00976 return GetNewAddition(m_pLeftOperand->Derive(Type),
00977 m_pRightOperand->Derive(Type));
00978 }
00979
00986 CValue* CSubstraction::Derive(TYPE_VARIABLE Type) const
00987 {
00988 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00989 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00990
00991 return GetNewSubstraction(m_pLeftOperand->Derive(Type),
00992 m_pRightOperand->Derive(Type));
00993 }
00994
01001 CValue* CProduct::Derive(TYPE_VARIABLE Type) const
01002 {
01003 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01004 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01005
01006 return GetNewAddition(GetNewProduct(m_pLeftOperand->Derive(Type),
01007 m_pRightOperand->GetCopy()),
01008 GetNewProduct(m_pLeftOperand->GetCopy(),
01009 m_pRightOperand->Derive(Type)));
01010 }
01011
01019 CValue* CDivision::Derive(TYPE_VARIABLE Type) const
01020 {
01021 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01022 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01023
01024 CValue* Numerator =
01025 GetNewSubstraction(
01026 GetNewProduct(m_pLeftOperand->Derive(Type),
01027 m_pRightOperand->GetCopy()),
01028 GetNewProduct(m_pLeftOperand->GetCopy(),
01029 m_pRightOperand->Derive(Type))
01030 );
01031
01032 CValue* Denominator = GetNewPow(m_pRightOperand->GetCopy(), new CNumber(2));
01033
01034 return GetNewDivision(Numerator, Denominator);
01035 }
01036
01044 CValue* COpposite::Derive(TYPE_VARIABLE Type) const
01045 {
01046 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01047
01048 return GetNewOpposite(m_pLeftOperand->Derive(Type));
01049 }
01050
01058 CValue* CSqrt::Derive(TYPE_VARIABLE Type) const
01059 {
01060 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01061
01062 return GetNewDivision( m_pLeftOperand->Derive(Type),
01063 GetNewProduct(new CNumber(2),
01064 GetNewSqrt(m_pLeftOperand->GetCopy())));
01065 }
01066
01073 CValue* CSin::Derive(TYPE_VARIABLE Type) const
01074 {
01075 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01076
01077 return GetNewProduct(GetNewCos(m_pLeftOperand->GetCopy()),
01078 m_pLeftOperand->Derive(Type));
01079 }
01080
01087 CValue* CCos::Derive(TYPE_VARIABLE Type) const
01088 {
01089 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01090
01091 return GetNewProduct(GetNewOpposite(GetNewSin(m_pLeftOperand->GetCopy())),
01092 m_pLeftOperand->Derive(Type));
01093 }
01094
01103 CValue* CTan::Derive(TYPE_VARIABLE Type) const
01104 {
01105 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01106
01107 return GetNewDivision(m_pLeftOperand->Derive(Type),
01108 GetNewPow(GetNewCos(m_pLeftOperand->GetCopy()),
01109 new CNumber(2)));
01110 }
01111
01118 CValue* CExp::Derive(TYPE_VARIABLE Type) const
01119 {
01120 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01121
01122 return GetNewProduct(GetNewExp(m_pLeftOperand->GetCopy()),
01123 m_pLeftOperand->Derive(Type));
01124 }
01125
01135 CValue* CPow::Derive(TYPE_VARIABLE Type) const
01136 {
01137 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01138 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01139
01140 float Number;
01141 if (m_pRightOperand->IsConstant(&Number))
01142 {
01143 return GetNewProduct(GetNewProduct(new CNumber(Number),
01144 m_pLeftOperand->Derive(Type)),
01145 GetNewPow(m_pLeftOperand->GetCopy(),
01146 new CNumber(Number - 1)));
01147 }
01148 else
01149 {
01150
01151 CValue* pLeftOperand =
01152 GetNewProduct(m_pRightOperand->Derive(Type),
01153 GetNewLn(m_pLeftOperand->GetCopy()));
01154
01155
01156 CValue* pRightOperand =
01157 GetNewDivision(GetNewProduct(m_pRightOperand->GetCopy(),
01158 m_pLeftOperand->Derive(Type)),
01159 m_pLeftOperand->GetCopy());
01160
01161 return GetNewProduct(this->GetCopy(),
01162 GetNewAddition(pLeftOperand, pRightOperand));
01163 }
01164 }
01165
01173 CValue* CLn::Derive(TYPE_VARIABLE Type) const
01174 {
01175 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01176
01177 return GetNewDivision(m_pLeftOperand->Derive(Type), m_pLeftOperand->GetCopy());
01178 }
01179
01186 CValue* CVariable::Derive(TYPE_VARIABLE Type) const
01187 {
01188 if (Type == m_Type)
01189 return new CNumber(1);
01190 else
01191 return new CNumber(0);
01192 }
01193
01200 CValue* CNumber::Derive(TYPE_VARIABLE Type) const
01201 {
01202 return new CNumber(0);
01203 }
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01219 void CAddition::Print(std::ostream& o) const
01220 {
01221 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01222 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01223
01224 o << '(';
01225 m_pLeftOperand->Print(o);
01226 o << '+';
01227 m_pRightOperand->Print(o);
01228 o << ')';
01229 }
01230
01235 void CSubstraction::Print(std::ostream& o) const
01236 {
01237 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01238 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01239
01240 o << '(';
01241 m_pLeftOperand->Print(o);
01242 o << '-';
01243 m_pRightOperand->Print(o);
01244 o << ')';
01245 }
01246
01251 void CProduct::Print(std::ostream& o) const
01252 {
01253 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01254 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01255
01256 o << '(';
01257 m_pLeftOperand->Print(o);
01258 o << '*';
01259 m_pRightOperand->Print(o);
01260 o << ')';
01261 }
01262
01267 void CDivision::Print(std::ostream& o) const
01268 {
01269 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01270 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01271
01272 o << '(';
01273 m_pLeftOperand->Print(o);
01274 o << '/';
01275 m_pRightOperand->Print(o);
01276 o << ')';
01277 }
01278
01283 void COpposite::Print(std::ostream& o) const
01284 {
01285 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01286
01287 o << "(-";
01288 m_pLeftOperand->Print(o);
01289 o << ')';
01290 }
01291
01296 void CSqrt::Print(std::ostream& o) const
01297 {
01298 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01299
01300 o << "sqrt(";
01301 m_pLeftOperand->Print(o);
01302 o << ')';
01303 }
01304
01309 void CSin::Print(std::ostream& o) const
01310 {
01311 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01312
01313 o << "sin(";
01314 m_pLeftOperand->Print(o);
01315 o << ')';
01316 }
01317
01322 void CCos::Print(std::ostream& o) const
01323 {
01324 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01325
01326 o << "cos(";
01327 m_pLeftOperand->Print(o);
01328 o << ')';
01329 }
01330
01335 void CTan::Print(std::ostream& o) const
01336 {
01337 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01338
01339 o << "tan(";
01340 m_pLeftOperand->Print(o);
01341 o << ')';
01342 }
01343
01348 void CExp::Print(std::ostream& o) const
01349 {
01350 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01351
01352 o << "exp(";
01353 m_pLeftOperand->Print(o);
01354 o << ')';
01355 }
01356
01361 void CLn::Print(std::ostream& o) const
01362 {
01363 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01364
01365 o << "ln(";
01366 m_pLeftOperand->Print(o);
01367 o << ')';
01368 }
01369
01374 void CPow::Print(std::ostream& o) const
01375 {
01376 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01377 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01378
01379 m_pLeftOperand->Print(o);
01380 o << '^';
01381 m_pRightOperand->Print(o);
01382 }
01383
01388 void CVariable::Print(std::ostream& o) const
01389 {
01390 switch (m_Type)
01391 {
01392 case (TYPE_X): o << 'x'; break;
01393 case (TYPE_Y): o << 'y'; break;
01394 case (TYPE_Z): o << 'z'; break;
01395 default: POP_ILLEGAL("Should not get here"); break;
01396 }
01397 }
01398
01403 void CNumber::Print(std::ostream& o) const
01404 {
01405 o << m_Number;
01406 }
01407
01408
01409
01410
01411
01412 inline void BEFORE_PUSH(std::vector<char>& v, int& i)
01413 {
01414 ++i;
01415
01416 if (i > 8)
01417 {
01418 v.push_back('\xd9');
01419 v.push_back('\xf6');
01420
01421 v.push_back('\x83');
01422 v.push_back('\xec');
01423 v.push_back('\x04');
01424
01425 v.push_back('\xd9');
01426 v.push_back('\x14');
01427 v.push_back('\x24');
01428
01429 v.push_back('\xdd');
01430 v.push_back('\xc0');
01431
01432 v.push_back('\xd9');
01433 v.push_back('\xf7');
01434 }
01435 }
01436
01437 inline void AFTER_POP(std::vector<char>& v, int& i)
01438 {
01439 if (i > 8)
01440 {
01441 v.push_back('\xd9');
01442 v.push_back('\x04');
01443 v.push_back('\x24');
01444
01445 v.push_back('\xd9');
01446 v.push_back('\xf7');
01447
01448 v.push_back('\x83');
01449 v.push_back('\xc4');
01450 v.push_back('\x04');
01451 }
01452
01453 --i;
01454 }
01455
01456
01457
01458
01459
01460
01461
01462 void CAddition::Compile(std::vector<char>& v, int& i) const
01463 {
01464 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01465 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01466
01467 m_pLeftOperand->Compile(v, i);
01468 m_pRightOperand->Compile(v, i);
01469
01470 v.push_back('\xde');
01471 v.push_back('\xc1');
01472
01473 AFTER_POP(v, i);
01474 }
01475
01476
01477 void CSubstraction::Compile(std::vector<char>& v, int& i) const
01478 {
01479 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01480 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01481
01482 m_pLeftOperand->Compile(v, i);
01483 m_pRightOperand->Compile(v, i);
01484
01485 v.push_back('\xde');
01486 v.push_back('\xe9');
01487
01488 AFTER_POP(v, i);
01489 }
01490
01491 void CProduct::Compile(std::vector<char>& v, int& i) const
01492 {
01493 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01494 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01495
01496 m_pLeftOperand->Compile(v, i);
01497 m_pRightOperand->Compile(v, i);
01498
01499 v.push_back('\xde');
01500 v.push_back('\xc9');
01501
01502 AFTER_POP(v, i);
01503 }
01504
01505 void CDivision::Compile(std::vector<char>& v, int& i) const
01506 {
01507 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01508 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01509
01510 m_pLeftOperand->Compile(v, i);
01511 m_pRightOperand->Compile(v, i);
01512
01513 v.push_back('\xde');
01514 v.push_back('\xf9');
01515
01516 AFTER_POP(v, i);
01517 }
01518
01519 void COpposite::Compile(std::vector<char>& v, int& i) const
01520 {
01521 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01522
01523 m_pLeftOperand->Compile(v, i);
01524
01525 v.push_back('\xd9');
01526 v.push_back('\xe0');
01527 }
01528
01529 void CSqrt::Compile(std::vector<char>& v, int& i) const
01530 {
01531 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01532
01533 m_pLeftOperand->Compile(v, i);
01534
01535 v.push_back('\xd9');
01536 v.push_back('\xfa');
01537 }
01538
01539 void CSin::Compile(std::vector<char>& v, int& i) const
01540 {
01541 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01542
01543 m_pLeftOperand->Compile(v, i);
01544
01545 v.push_back('\xd9');
01546 v.push_back('\xfe');
01547 }
01548
01549 void CCos::Compile(std::vector<char>& v, int& i) const
01550 {
01551 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01552
01553 m_pLeftOperand->Compile(v, i);
01554
01555 v.push_back('\xd9');
01556 v.push_back('\xff');
01557 }
01558
01559 void CTan::Compile(std::vector<char>& v, int& i) const
01560 {
01561 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01562
01563 m_pLeftOperand->Compile(v, i);
01564
01565 BEFORE_PUSH(v, i);
01566
01567 v.push_back('\xd9');
01568 v.push_back('\xf2');
01569
01570 v.push_back('\xdd');
01571 v.push_back('\xc0');
01572
01573 v.push_back('\xd9');
01574 v.push_back('\xf7');
01575
01576 AFTER_POP(v, i);
01577 }
01578
01579 void CExp::Compile(std::vector<char>& v, int& i) const
01580 {
01581 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01582
01583 m_pLeftOperand->Compile(v, i);
01584
01585
01586
01587
01588 BEFORE_PUSH(v, i);
01589
01590 v.push_back('\xd9');
01591 v.push_back('\xea');
01592
01593
01594 v.push_back('\xde');
01595 v.push_back('\xc9');
01596
01597
01598 v.push_back('\xd9');
01599 v.push_back('\xe8');
01600
01601
01602 BEFORE_PUSH(v, i);
01603
01604 v.push_back('\xd9');
01605 v.push_back('\xc1');
01606
01607
01608 v.push_back('\xd9');
01609 v.push_back('\xfc');
01610
01611
01612 v.push_back('\xd9');
01613 v.push_back('\xca');
01614
01615
01616 v.push_back('\xd8');
01617 v.push_back('\xe2');
01618
01619
01620 v.push_back('\xd9');
01621 v.push_back('\xf0');
01622
01623
01624 v.push_back('\xde');
01625 v.push_back('\xc1');
01626
01627
01628 AFTER_POP(v, i);
01629
01630
01631
01632 v.push_back('\xd9');
01633 v.push_back('\xfd');
01634
01635
01636 v.push_back('\xd9');
01637 v.push_back('\xc9');
01638
01639
01640
01641 v.push_back('\xdd');
01642 v.push_back('\xc0');
01643
01644 v.push_back('\xd9');
01645 v.push_back('\xf7');
01646
01647
01648 AFTER_POP(v, i);
01649 }
01650
01651 void CLn::Compile(std::vector<char>& v, int& i) const
01652 {
01653 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01654
01655 m_pLeftOperand->Compile(v, i);
01656
01657
01658
01659
01660 BEFORE_PUSH(v, i);
01661
01662 v.push_back('\xd9');
01663 v.push_back('\xe8');
01664
01665
01666 BEFORE_PUSH(v, i);
01667
01668 v.push_back('\xd9');
01669 v.push_back('\xea');
01670
01671
01672 v.push_back('\xd9');
01673 v.push_back('\xca');
01674
01675
01676 v.push_back('\xd9');
01677 v.push_back('\xf1');
01678
01679
01680 AFTER_POP(v, i);
01681
01682 v.push_back('\xde');
01683 v.push_back('\xf1');
01684
01685
01686 AFTER_POP(v, i);
01687 }
01688
01689 void CPow::Compile(std::vector<char>& v, int& i) const
01690 {
01691 POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01692 POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01693
01694 m_pLeftOperand->Compile(v, i);
01695 m_pRightOperand->Compile(v, i);
01696
01697
01698
01699
01700 bool entier = false;
01701 float exponent = 0;
01702 if (m_pRightOperand->IsConstant(&exponent))
01703 entier = (exponent == (int) exponent);
01704
01705 if (entier)
01706 {
01707 v.push_back('\xdb');
01708 v.push_back('\x54');
01709 v.push_back('\x24');
01710 v.push_back('\xfc');
01711
01712 v.push_back('\xdd');
01713 v.push_back('\xc0');
01714
01715 v.push_back('\xd9');
01716 v.push_back('\xf7');
01717
01718 v.push_back('\xd9');
01719 v.push_back('\xe8');
01720
01721 v.push_back('\xd9');
01722 v.push_back('\xc9');
01723
01724 v.push_back('\x8b');
01725 v.push_back('\x54');
01726 v.push_back('\x24');
01727 v.push_back('\xfc');
01728
01729 v.push_back('\x83');
01730 v.push_back('\xfa');
01731 v.push_back('\x00');
01732
01733 v.push_back('\x7f');
01734 v.push_back('\x04');
01735
01736 v.push_back('\xf7');
01737 v.push_back('\xda');
01738
01739 v.push_back('\xd8');
01740 v.push_back('\xf9');
01741
01742 v.push_back('\xd1');
01743 v.push_back('\xea');
01744
01745 v.push_back('\x73');
01746 v.push_back('\x02');
01747
01748 v.push_back('\xdc');
01749 v.push_back('\xc9');
01750
01751 v.push_back('\x83');
01752 v.push_back('\xfa');
01753 v.push_back('\x00');
01754
01755 v.push_back('\x74');
01756 v.push_back('\x04');
01757
01758 v.push_back('\xd8');
01759 v.push_back('\xc8');
01760
01761 v.push_back('\xeb');
01762 v.push_back('\xf1');
01763
01764 v.push_back('\xdd');
01765 v.push_back('\xc0');
01766
01767 v.push_back('\xd9');
01768 v.push_back('\xf7');
01769 }
01770 else
01771 {
01772 v.push_back('\xd9');
01773 v.push_back('\xc9');
01774
01775
01776 v.push_back('\xd9');
01777 v.push_back('\xf1');
01778
01779
01780 v.push_back('\xd9');
01781 v.push_back('\xe8');
01782
01783
01784 BEFORE_PUSH(v, i);
01785
01786 v.push_back('\xd9');
01787 v.push_back('\xc1');
01788
01789
01790 v.push_back('\xd9');
01791 v.push_back('\xfc');
01792
01793
01794 v.push_back('\xd9');
01795 v.push_back('\xca');
01796
01797
01798 v.push_back('\xd8');
01799 v.push_back('\xe2');
01800
01801
01802 v.push_back('\xd9');
01803 v.push_back('\xf0');
01804
01805
01806 v.push_back('\xde');
01807 v.push_back('\xc1');
01808
01809
01810 AFTER_POP(v, i);
01811
01812
01813
01814 v.push_back('\xd9');
01815 v.push_back('\xfd');
01816
01817
01818 v.push_back('\xd9');
01819 v.push_back('\xc9');
01820
01821
01822
01823 v.push_back('\xdd');
01824 v.push_back('\xc0');
01825
01826 v.push_back('\xd9');
01827 v.push_back('\xf7');
01828
01829 }
01830
01831 AFTER_POP(v, i);
01832 }
01833
01834 void CVariable::Compile(std::vector<char>& v, int& i) const
01835 {
01836 BEFORE_PUSH(v, i);
01837
01838 v.push_back('\xd9');
01839 v.push_back('\x40');
01840 v.push_back(m_Type*4);
01841 }
01842
01843 void CNumber::Compile(std::vector<char>& v, int& i) const
01844 {
01845 BEFORE_PUSH(v, i);
01846
01847 v.push_back('\xd9');
01848 v.push_back('\x05');
01849
01850 v.push_back((char)((int)&m_Number));
01851 v.push_back((char)((int)&m_Number >> 8));
01852 v.push_back((char)((int)&m_Number >> 16));
01853 v.push_back((char)((int)&m_Number >> 24));
01854 }
01855
01856