// SPDX-License-Identifier: LGPL-2.1-or-later // 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) #include "Wm4FoundationPCH.h" #include "Wm4Intersector1.h" namespace Wm4 { //---------------------------------------------------------------------------- template Intersector1::Intersector1 (Real fU0, Real fU1, Real fV0, Real fV1) { assert(fU0 <= fU1 && fV0 <= fV1); m_afU[0] = fU0; m_afU[1] = fU1; m_afV[0] = fV0; m_afV[1] = fV1; m_fFirstTime = (Real)0.0; m_fLastTime = (Real)0.0; m_iQuantity = 0; } //---------------------------------------------------------------------------- template Intersector1::Intersector1 (Real afU[2], Real afV[2]) { assert(afU[0] <= afU[1] && afV[0] <= afV[1]); for (int i = 0; i < 2; i++) { m_afU[i] = afU[i]; m_afV[i] = afV[i]; } m_fFirstTime = (Real)0.0; m_fLastTime = (Real)0.0; m_iQuantity = 0; } //---------------------------------------------------------------------------- template Intersector1::~Intersector1 () { } //---------------------------------------------------------------------------- template Real Intersector1::GetU (int i) const { assert(0 <= i && i < 2); return m_afU[i]; } //---------------------------------------------------------------------------- template Real Intersector1::GetV (int i) const { assert(0 <= i && i < 2); return m_afV[i]; } //---------------------------------------------------------------------------- template bool Intersector1::Test () { return m_afU[0] <= m_afV[1] && m_afU[1] >= m_afV[0]; } //---------------------------------------------------------------------------- template bool Intersector1::Find () { if (m_afU[1] < m_afV[0] || m_afU[0] > m_afV[1]) { m_iQuantity = 0; } else if (m_afU[1] > m_afV[0]) { if (m_afU[0] < m_afV[1]) { m_iQuantity = 2; m_afOverlap[0] = (m_afU[0] < m_afV[0] ? m_afV[0] : m_afU[0]); m_afOverlap[1] = (m_afU[1] > m_afV[1] ? m_afV[1] : m_afU[1]); if (m_afOverlap[0] == m_afOverlap[1]) { m_iQuantity = 1; } } else // m_afU[0] == m_afV[1] { m_iQuantity = 1; m_afOverlap[0] = m_afU[0]; } } else // m_afU[1] == m_afV[0] { m_iQuantity = 1; m_afOverlap[0] = m_afU[1]; } return m_iQuantity > 0; } //---------------------------------------------------------------------------- template bool Intersector1::Test (Real fTMax, Real fSpeedU, Real fSpeedV) { Real fDiffSpeed, fInvDiffSpeed, fDiffPos; if (m_afU[1] < m_afV[0]) { // [u0,u1] initially to the left of [v0,v1] fDiffSpeed = fSpeedU - fSpeedV; if (fDiffSpeed > (Real)0.0) { // the intervals must move towards each other fDiffPos = m_afV[0] - m_afU[1]; if (fDiffPos <= fTMax*fDiffSpeed) { // the intervals intersect within the specified time fInvDiffSpeed = ((Real)1.0)/fDiffSpeed; m_fFirstTime = fDiffPos*fInvDiffSpeed; m_fLastTime = (m_afV[1] - m_afU[0])*fInvDiffSpeed; return true; } } } else if (m_afU[0] > m_afV[1]) { // [u0,u1] initially to the right of [v0,v1] fDiffSpeed = fSpeedV - fSpeedU; if ( fDiffSpeed > (Real)0.0 ) { // the intervals must move towards each other fDiffPos = m_afU[0] - m_afV[1]; if (fDiffPos <= fTMax*fDiffSpeed) { // the intervals intersect within the specified time fInvDiffSpeed = ((Real)1.0)/fDiffSpeed; m_fFirstTime = fDiffPos*fInvDiffSpeed; m_fLastTime = (m_afU[1] - m_afV[0])*fInvDiffSpeed; return true; } } } else { // the intervals are initially intersecting m_fFirstTime = 0.0f; if (fSpeedV > fSpeedU) { m_fLastTime = (m_afU[1] - m_afV[0])/(fSpeedV - fSpeedU); } else if (fSpeedV < fSpeedU) { m_fLastTime = (m_afV[1] - m_afU[0])/(fSpeedU - fSpeedV); } else { m_fLastTime = Math::MAX_REAL; } return true; } return false; } //---------------------------------------------------------------------------- template bool Intersector1::Find (Real fTMax, Real fSpeedU, Real fSpeedV) { Real fDiffSpeed, fInvDiffSpeed, fDiffPos; if (m_afU[1] < m_afV[0]) { // [u0,u1] initially to the left of [v0,v1] fDiffSpeed = fSpeedU - fSpeedV; if (fDiffSpeed > (Real)0.0) { // the intervals must move towards each other fDiffPos = m_afV[0] - m_afU[1]; if (fDiffPos <= fTMax*fDiffSpeed) { // the intervals intersect within the specified time fInvDiffSpeed = ((Real)1.0)/fDiffSpeed; m_fFirstTime = fDiffPos*fInvDiffSpeed; m_fLastTime = (m_afV[1] - m_afU[0])*fInvDiffSpeed; m_iQuantity = 1; m_afOverlap[0] = m_afU[0] + m_fFirstTime*fSpeedU; return true; } } } else if (m_afU[0] > m_afV[1]) { // [u0,u1] initially to the right of [v0,v1] fDiffSpeed = fSpeedV - fSpeedU; if (fDiffSpeed > (Real)0.0) { // the intervals must move towards each other fDiffPos = m_afU[0] - m_afV[1]; if (fDiffPos <= fTMax*fDiffSpeed) { // the intervals intersect within the specified time fInvDiffSpeed = ((Real)1.0)/fDiffSpeed; m_fFirstTime = fDiffPos*fInvDiffSpeed; m_fLastTime = (m_afU[1] - m_afV[0])*fInvDiffSpeed; m_iQuantity = 1; m_afOverlap[0] = m_afV[1] + m_fFirstTime*fSpeedV; return true; } } } else { // the intervals are initially intersecting m_fFirstTime = 0.0f; if (fSpeedV > fSpeedU) { m_fLastTime = (m_afU[1] - m_afV[0])/(fSpeedV - fSpeedU); } else if (fSpeedV < fSpeedU) { m_fLastTime = (m_afV[1] - m_afU[0])/(fSpeedU - fSpeedV); } else { m_fLastTime = Math::MAX_REAL; } if (m_afU[1] > m_afV[0]) { if (m_afU[0] < m_afV[1]) { m_iQuantity = 2; m_afOverlap[0] = (m_afU[0] < m_afV[0] ? m_afV[0] : m_afU[0]); m_afOverlap[1] = (m_afU[1] > m_afV[1] ? m_afV[1] : m_afU[1]); } else // m_afU[0] == m_afV[1] { m_iQuantity = 1; m_afOverlap[0] = m_afU[0]; } } else // m_afU[1] == m_afV[0] { m_iQuantity = 1; m_afOverlap[0] = m_afU[1]; } return true; } m_iQuantity = 0; return false; } //---------------------------------------------------------------------------- template Real Intersector1::GetFirstTime () const { return m_fFirstTime; } //---------------------------------------------------------------------------- template Real Intersector1::GetLastTime () const { return m_fLastTime; } //---------------------------------------------------------------------------- template int Intersector1::GetQuantity () const { return m_iQuantity; } //---------------------------------------------------------------------------- template Real Intersector1::GetOverlap (int i) const { assert(0 <= i && i < m_iQuantity); return m_afOverlap[i]; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // explicit instantiation //---------------------------------------------------------------------------- template WM4_FOUNDATION_ITEM class Intersector1; template WM4_FOUNDATION_ITEM class Intersector1; //---------------------------------------------------------------------------- }