blob: a8a61195dadb6bc7c8f10f6fbfe0ceb93ea04cf0 [file] [log] [blame] [edit]
//===========================================================================//
// Purpose : Method definitions for a TGS_ArrayGrid_c class.
//
// Public methods include:
// - TGS_ArrayGrid, ~TGS_ArrayGrid
// - operator=
// - operator==, operator!=
// - Init
// - GetPitch, GetOffset
// - FoundCount
// - SnapToGrid
// - SnapToPitch
//
// Private methods include:
// - SnapDims_
//
//===========================================================================//
//---------------------------------------------------------------------------//
// Copyright (C) 2012-2013 Jeff Rudolph, Texas Instruments (jrudolph@ti.com) //
// //
// Permission is hereby granted, free of charge, to any person obtaining a //
// copy of this software and associated documentation files (the "Software"),//
// to deal in the Software without restriction, including without limitation //
// the rights to use, copy, modify, merge, publish, distribute, sublicense, //
// and/or sell copies of the Software, and to permit persons to whom the //
// Software is furnished to do so, subject to the following conditions: //
// //
// The above copyright notice and this permission notice shall be included //
// in all copies or substantial portions of the Software. //
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS //
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF //
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN //
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, //
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR //
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE //
// USE OR OTHER DEALINGS IN THE SOFTWARE. //
//---------------------------------------------------------------------------//
#include "TGS_ArrayGrid.h"
//===========================================================================//
// Method : TGS_ArrayGrid_c
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
TGS_ArrayGrid_c::TGS_ArrayGrid_c(
void )
:
pitchDims_( 0.0, 0.0 ),
offsetDims_( 0.0, 0.0 )
{
}
//===========================================================================//
TGS_ArrayGrid_c::TGS_ArrayGrid_c(
const TGS_FloatDims_t& pitchDims )
:
pitchDims_( 0.0, 0.0 ),
offsetDims_( 0.0, 0.0 )
{
this->Init( pitchDims );
}
//===========================================================================//
TGS_ArrayGrid_c::TGS_ArrayGrid_c(
const TGS_FloatDims_t& pitchDims,
const TGS_FloatDims_t& offsetDims )
:
pitchDims_( 0.0, 0.0 ),
offsetDims_( 0.0, 0.0 )
{
this->Init( pitchDims, offsetDims );
}
//===========================================================================//
TGS_ArrayGrid_c::TGS_ArrayGrid_c(
double xPitch,
double yPitch )
:
pitchDims_( 0.0, 0.0 ),
offsetDims_( 0.0, 0.0 )
{
this->Init( xPitch, yPitch );
}
//===========================================================================//
TGS_ArrayGrid_c::TGS_ArrayGrid_c(
double xPitch,
double yPitch,
double xOffset,
double yOffset )
:
pitchDims_( 0.0, 0.0 ),
offsetDims_( 0.0, 0.0 )
{
this->Init( xPitch, yPitch, xOffset, yOffset );
}
//===========================================================================//
// Method : ~TGS_ArrayGrid_c
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
TGS_ArrayGrid_c::~TGS_ArrayGrid_c(
void )
{
}
//===========================================================================//
// Method : operator=
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
TGS_ArrayGrid_c& TGS_ArrayGrid_c::operator=(
const TGS_ArrayGrid_c& arrayGrid )
{
if( &arrayGrid != this )
{
this->pitchDims_ = arrayGrid.pitchDims_;
this->offsetDims_ = arrayGrid.offsetDims_;
}
return( *this );
}
//===========================================================================//
// Method : operator==
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
bool TGS_ArrayGrid_c::operator==(
const TGS_ArrayGrid_c& arrayGrid ) const
{
return(( this->pitchDims_ == arrayGrid.pitchDims_ ) &&
( this->offsetDims_ == arrayGrid.offsetDims_ ) ?
true : false );
}
//===========================================================================//
// Method : operator!=
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
bool TGS_ArrayGrid_c::operator!=(
const TGS_ArrayGrid_c& arrayGrid ) const
{
return(( !this->operator==( arrayGrid )) ?
true : false );
}
//===========================================================================//
// Method : Init
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
void TGS_ArrayGrid_c::Init(
const TGS_FloatDims_t& pitchDims )
{
this->pitchDims_.dx = pitchDims.dx;
this->pitchDims_.dy = pitchDims.dy;
this->offsetDims_.dx = 0.0;
this->offsetDims_.dy = 0.0;
}
//===========================================================================//
void TGS_ArrayGrid_c::Init(
const TGS_FloatDims_t& pitchDims,
const TGS_FloatDims_t& offsetDims )
{
this->pitchDims_.dx = pitchDims.dx;
this->pitchDims_.dy = pitchDims.dy;
this->offsetDims_.dx = fmod( offsetDims.dx, pitchDims.dx );
this->offsetDims_.dy = fmod( offsetDims.dy, pitchDims.dy );
}
//===========================================================================//
void TGS_ArrayGrid_c::Init(
double xPitch,
double yPitch )
{
this->pitchDims_.dx = xPitch;
this->pitchDims_.dy = yPitch;
this->offsetDims_.dx = 0.0;
this->offsetDims_.dy = 0.0;
}
//===========================================================================//
void TGS_ArrayGrid_c::Init(
double xPitch,
double yPitch,
double xOffset,
double yOffset )
{
this->pitchDims_.dx = xPitch;
this->pitchDims_.dy = yPitch;
this->offsetDims_.dx = fmod( xOffset, xPitch );
this->offsetDims_.dy = fmod( yOffset, yPitch );
}
//===========================================================================//
// Method : GetPitch
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
void TGS_ArrayGrid_c::GetPitch(
TGS_FloatDims_t* ppitchDims ) const
{
if( ppitchDims )
{
*ppitchDims = this->pitchDims_;
}
}
//===========================================================================//
void TGS_ArrayGrid_c::GetPitch(
double* pxPitch,
double* pyPitch ) const
{
if( pxPitch && pyPitch )
{
*pxPitch = this->pitchDims_.dx;
*pyPitch = this->pitchDims_.dy;
}
}
//===========================================================================//
// Method : GetOffset
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
void TGS_ArrayGrid_c::GetOffset(
TGS_FloatDims_t* poffsetDims ) const
{
if( poffsetDims )
{
*poffsetDims = this->offsetDims_;
}
}
//===========================================================================//
void TGS_ArrayGrid_c::GetOffset(
double* pxOffset,
double* pyOffset ) const
{
if( pxOffset && pyOffset )
{
*pxOffset = this->offsetDims_.dx;
*pyOffset = this->offsetDims_.dy;
}
}
//===========================================================================//
// Method : FindCount
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
void TGS_ArrayGrid_c::FindCount(
const TGS_Region_c& region,
TGS_IntDims_t* pcount,
TGS_ArraySnapMode_t snapMode ) const
{
TGS_IntDims_t count;
this->FindCount( region,
&count.dx,
&count.dy,
snapMode );
if( pcount )
{
*pcount = count;
}
}
//===========================================================================//
void TGS_ArrayGrid_c::FindCount(
const TGS_Region_c& region,
int* pxCount,
int* pyCount,
TGS_ArraySnapMode_t snapMode ) const
{
// First, snap given region to nearest grid based on the given region
TGS_Region_c region_;
this->SnapToGrid( region, &region_, snapMode );
// Second, compute counts based on region dims and pitch values
double xCount = 0.0;
double yCount = 0.0;
if( region_.IsValid( ))
{
double xPitch = this->pitchDims_.dx;
double yPitch = this->pitchDims_.dy;
xCount = ( TCTF_IsGT( xPitch, 0.0 ) ?
( region_.GetDx( ) + TC_FLT_EPSILON ) / xPitch + 1.0:
0.0 );
yCount = ( TCTF_IsGT( yPitch, 0.0 ) ?
( region_.GetDy( ) + TC_FLT_EPSILON ) / yPitch + 1.0:
0.0 );
}
if( pxCount && pyCount )
{
*pxCount = static_cast< int >( xCount );
*pyCount = static_cast< int >( yCount );
}
}
//===========================================================================//
// Method : SnapToGrid
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
void TGS_ArrayGrid_c::SnapToGrid(
const TGS_Point_c& point,
TGS_Point_c* ppoint,
TGS_CornerMode_t cornerMode ) const
{
double x = this->SnapDims_( point.x,
this->pitchDims_.dx,
this->offsetDims_.dx );
double y = this->SnapDims_( point.y,
this->pitchDims_.dy,
this->offsetDims_.dy );
switch( cornerMode )
{
case TGS_CORNER_LOWER_LEFT:
case TGS_CORNER_UPPER_LEFT:
if( TCTF_IsGT( x, point.x )) // Snapped point to nearest right
x -= this->pitchDims_.dx; // Apply pitch to snap left instead
break;
case TGS_CORNER_LOWER_RIGHT:
case TGS_CORNER_UPPER_RIGHT:
if( TCTF_IsLT( x, point.x )) // Snapped point to nearest left
x += this->pitchDims_.dx; // Apply pitch to snap right instead
break;
default:
break;
}
switch( cornerMode )
{
case TGS_CORNER_LOWER_LEFT:
case TGS_CORNER_LOWER_RIGHT:
if( TCTF_IsGT( y, point.y )) // Snapped point to nearest upper
y -= this->pitchDims_.dy; // Apply pitch to snap lower instead
break;
case TGS_CORNER_UPPER_LEFT:
case TGS_CORNER_UPPER_RIGHT:
if( TCTF_IsLT( y, point.y )) // Snapped point to nearest lower
y += this->pitchDims_.dy; // Apply pitch to snap upperinstead;
break;
default:
break;
}
if( ppoint )
{
ppoint->Set( x, y );
}
}
//===========================================================================//
void TGS_ArrayGrid_c::SnapToGrid(
const TGS_Region_c& region,
TGS_Region_c* pregion,
TGS_ArraySnapMode_t snapMode ) const
{
double x1 = this->SnapDims_( region.x1,
this->pitchDims_.dx,
this->offsetDims_.dx );
double y1 = this->SnapDims_( region.y1,
this->pitchDims_.dy,
this->offsetDims_.dy );
double x2 = this->SnapDims_( region.x2,
this->pitchDims_.dx,
this->offsetDims_.dx );
double y2 = this->SnapDims_( region.y2,
this->pitchDims_.dy,
this->offsetDims_.dy );
if( snapMode == TGS_ARRAY_SNAP_WITHIN )
{
x1 += ( TCTF_IsLT( x1, region.x1 ) ? this->pitchDims_.dx : 0.0 );
y1 += ( TCTF_IsLT( y1, region.y1 ) ? this->pitchDims_.dy : 0.0 );
x2 -= ( TCTF_IsGT( x2, region.x2 ) ? this->pitchDims_.dx : 0.0 );
y2 -= ( TCTF_IsGT( y2, region.y2 ) ? this->pitchDims_.dy : 0.0 );
}
if( pregion )
{
if( TCTF_IsLE( x1, x2 ) &&
TCTF_IsLE( y1, y2 ))
{
pregion->Set( x1, y1, x2, y2 );
}
else
{
pregion->Reset( );
}
}
}
//===========================================================================//
void TGS_ArrayGrid_c::SnapToGrid(
const TGS_Region_c& region,
const TGS_Point_c& point,
TGS_Point_c* ppoint,
TGS_ArraySnapMode_t snapMode ) const
{
int z = point.z;
double x = this->SnapDims_( point.x,
this->pitchDims_.dx,
this->offsetDims_.dx );
double y = this->SnapDims_( point.y,
this->pitchDims_.dy,
this->offsetDims_.dy );
if( snapMode == TGS_ARRAY_SNAP_WITHIN )
{
x += ( TCTF_IsLT( x, region.x1 ) ? this->pitchDims_.dx : 0.0 );
y += ( TCTF_IsLT( y, region.y1 ) ? this->pitchDims_.dy : 0.0 );
x -= ( TCTF_IsGT( x, region.x2 ) ? this->pitchDims_.dx : 0.0 );
y -= ( TCTF_IsGT( y, region.y2 ) ? this->pitchDims_.dy : 0.0 );
}
if( ppoint )
{
if( TCTF_IsGE( x, region.x1 ) && TCTF_IsLE( x, region.x2 ) &&
TCTF_IsGE( y, region.y1 ) && TCTF_IsLE( y, region.y2 ))
{
ppoint->Set( x, y, z );
}
else
{
ppoint->Reset( );
}
}
}
//===========================================================================//
// Method : SnapToPitch
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
void TGS_ArrayGrid_c::SnapToPitch(
const TGS_Point_c& point,
TGS_Point_c* ppoint ) const
{
double x = this->SnapDims_( point.x,
this->pitchDims_.dx );
double y = this->SnapDims_( point.y,
this->pitchDims_.dy );
if( ppoint )
{
ppoint->Set( x, y );
}
}
//===========================================================================//
void TGS_ArrayGrid_c::SnapToPitch(
const TGS_Region_c& region,
TGS_Region_c* pregion,
TGS_ArraySnapMode_t snapMode ) const
{
double x1 = this->SnapDims_( region.x1,
this->pitchDims_.dx );
double y1 = this->SnapDims_( region.y1,
this->pitchDims_.dy );
double x2 = this->SnapDims_( region.x2,
this->pitchDims_.dx );
double y2 = this->SnapDims_( region.y2,
this->pitchDims_.dy );
if( snapMode == TGS_ARRAY_SNAP_WITHIN )
{
x1 += ( TCTF_IsLT( x1, region.x1 ) ? this->pitchDims_.dx : 0.0 );
y1 += ( TCTF_IsLT( y1, region.y1 ) ? this->pitchDims_.dy : 0.0 );
x2 -= ( TCTF_IsGT( x2, region.x2 ) ? this->pitchDims_.dx : 0.0 );
y2 -= ( TCTF_IsGT( y2, region.y2 ) ? this->pitchDims_.dy : 0.0 );
}
if( pregion )
{
if( TCTF_IsLE( x1, x2 ) &&
TCTF_IsLE( y1, y2 ))
{
pregion->Set( x1, y1, x2, y2 );
}
else
{
pregion->Reset( );
}
}
}
//===========================================================================//
// Method : SnapDims_
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 08/25/12 jeffr : Original
//===========================================================================//
double TGS_ArrayGrid_c::SnapDims_(
double f,
double pitch,
double offset ) const
{
if( TCTF_IsGT( pitch, 0.0 ))
{
f = floor(( f - offset ) / pitch + TC_FLT_EPSILON ) * pitch + offset;
}
return( f );
}