// Wild Magic Source Code // David Eberly // http://www.geometrictools.com // Copyright (c) 1998-2007 // // This library is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation; either version 2.1 of the License, or (at // your option) any later version. The license is available for reading at // either of the locations: // http://www.gnu.org/copyleft/lgpl.html // http://www.geometrictools.com/License/WildMagicLicense.pdf // The license applies to versions 0 through 4 of Wild Magic. // // Version: 4.0.0 (2006/06/28) namespace Wm4 { //---------------------------------------------------------------------------- template Query2TRational::Query2TRational (int iVQuantity, const Vector2* akVertex) : Query2(iVQuantity,akVertex) { m_akRVertex = WM4_NEW RVector[m_iVQuantity]; m_abEvaluated = WM4_NEW bool[m_iVQuantity]; memset(m_abEvaluated,0,m_iVQuantity*sizeof(bool)); } //---------------------------------------------------------------------------- template Query2TRational::~Query2TRational () { WM4_DELETE[] m_akRVertex; WM4_DELETE[] m_abEvaluated; } //---------------------------------------------------------------------------- template Query::Type Query2TRational::GetType () const { return Query::QT_RATIONAL; } //---------------------------------------------------------------------------- template int Query2TRational::ToLine (int i, int iV0, int iV1) const { int aiIndex[3] = { i, iV0, iV1 }; Convert(3,aiIndex); return ToLine(m_akRVertex[i],iV0,iV1); } //---------------------------------------------------------------------------- template int Query2TRational::ToLine (const Vector2& rkP, int iV0, int iV1) const { RVector kRP; kRP[0] = Rational(rkP[0]); kRP[1] = Rational(rkP[1]); int aiIndex[2] = { iV0, iV1 }; Convert(2,aiIndex); return ToLine(kRP,iV0,iV1); } //---------------------------------------------------------------------------- template int Query2TRational::ToTriangle (int i, int iV0, int iV1, int iV2) const { int aiIndex[4] = { i, iV0, iV1, iV2 }; Convert(4,aiIndex); return ToTriangle(m_akRVertex[i],iV0,iV1,iV2); } //---------------------------------------------------------------------------- template int Query2TRational::ToTriangle (const Vector2& rkP, int iV0, int iV1, int iV2) const { RVector kRP; kRP[0] = Rational(rkP[0]); kRP[1] = Rational(rkP[1]); int aiIndex[3] = { iV0, iV1, iV2 }; Convert(3,aiIndex); return ToTriangle(kRP,iV0,iV1,iV2); } //---------------------------------------------------------------------------- template int Query2TRational::ToCircumcircle (int i, int iV0, int iV1, int iV2) const { int aiIndex[4] = { i, iV0, iV1, iV2 }; Convert(4,aiIndex); return ToCircumcircle(m_akRVertex[i],iV0,iV1,iV2); } //---------------------------------------------------------------------------- template int Query2TRational::ToCircumcircle (const Vector2& rkP, int iV0, int iV1, int iV2) const { RVector kRP; kRP[0] = Rational(rkP[0]); kRP[1] = Rational(rkP[1]); int aiIndex[3] = { iV0, iV1, iV2 }; Convert(3,aiIndex); return ToCircumcircle(kRP,iV0,iV1,iV2); } //---------------------------------------------------------------------------- template void Query2TRational::Convert (int iQuantity, int* aiIndex) const { for (int i = 0; i < iQuantity; i++) { int j = aiIndex[i]; if (!m_abEvaluated[j]) { m_abEvaluated[j] = true; m_akRVertex[j][0] = Rational(m_akVertex[j][0]); m_akRVertex[j][1] = Rational(m_akVertex[j][1]); } } } //---------------------------------------------------------------------------- template int Query2TRational::ToLine (const RVector& rkRP, int iV0, int iV1) const { Rational kX0 = rkRP[0] - m_akRVertex[iV0][0]; Rational kY0 = rkRP[1] - m_akRVertex[iV0][1]; Rational kX1 = m_akRVertex[iV1][0] - m_akRVertex[iV0][0]; Rational kY1 = m_akRVertex[iV1][1] - m_akRVertex[iV0][1]; Rational kDet2 = Det2(kX0,kY0,kX1,kY1); return (kDet2 > 0 ? +1 : (kDet2 < 0 ? -1 : 0)); } //---------------------------------------------------------------------------- template int Query2TRational::ToTriangle (const RVector& rkRP, int iV0, int iV1, int iV2) const { int iSign0 = ToLine(rkRP,iV1,iV2); if (iSign0 > 0) { return +1; } int iSign1 = ToLine(rkRP,iV0,iV2); if (iSign1 < 0) { return +1; } int iSign2 = ToLine(rkRP,iV0,iV1); if (iSign2 > 0) { return +1; } return ((iSign0 && iSign1 && iSign2) ? -1 : 0); } //---------------------------------------------------------------------------- template int Query2TRational::ToCircumcircle (const RVector& rkRP, int iV0, int iV1, int iV2) const { RVector& rkRV0 = m_akRVertex[iV0]; RVector& rkRV1 = m_akRVertex[iV1]; RVector& rkRV2 = m_akRVertex[iV2]; Rational kS0x = rkRV0[0] + rkRP[0]; Rational kD0x = rkRV0[0] - rkRP[0]; Rational kS0y = rkRV0[1] + rkRP[1]; Rational kD0y = rkRV0[1] - rkRP[1]; Rational kS1x = rkRV1[0] + rkRP[0]; Rational kD1x = rkRV1[0] - rkRP[0]; Rational kS1y = rkRV1[1] + rkRP[1]; Rational kD1y = rkRV1[1] - rkRP[1]; Rational kS2x = rkRV2[0] + rkRP[0]; Rational kD2x = rkRV2[0] - rkRP[0]; Rational kS2y = rkRV2[1] + rkRP[1]; Rational kD2y = rkRV2[1] - rkRP[1]; Rational kZ0 = kS0x*kD0x + kS0y*kD0y; Rational kZ1 = kS1x*kD1x + kS1y*kD1y; Rational kZ2 = kS2x*kD2x + kS2y*kD2y; Rational kDet3 = Det3(kD0x,kD0y,kZ0,kD1x,kD1y,kZ1,kD2x,kD2y,kZ2); return (kDet3 < 0 ? 1 : (kDet3 > 0 ? -1 : 0)); } //---------------------------------------------------------------------------- template typename Query2TRational::Rational Query2TRational::Dot ( Rational& rkX0, Rational& rkY0, Rational& rkX1, Rational& rkY1) { return rkX0*rkX1 + rkY0*rkY1; } //---------------------------------------------------------------------------- template typename Query2TRational::Rational Query2TRational::Det2 ( Rational& rkX0, Rational& rkY0, Rational& rkX1, Rational& rkY1) { return rkX0*rkY1 - rkX1*rkY0; } //---------------------------------------------------------------------------- template typename Query2TRational::Rational Query2TRational::Det3 ( Rational& rkX0, Rational& rkY0, Rational& rkZ0, Rational& rkX1, Rational& rkY1, Rational& rkZ1, Rational& rkX2, Rational& rkY2, Rational& rkZ2) { Rational kC00 = rkY1*rkZ2 - rkY2*rkZ1; Rational kC01 = rkY2*rkZ0 - rkY0*rkZ2; Rational kC02 = rkY0*rkZ1 - rkY1*rkZ0; return rkX0*kC00 + rkX1*kC01 + rkX2*kC02; } //---------------------------------------------------------------------------- } //namespace Wm4