Commit 1a4836f2 authored by David Doria's avatar David Doria
Browse files

ENH: Added vector-on-plane projection and related test

ENH: added tests based on Arnauds comments

ENH: change test to orthogonal vector

Change-Id: I811f97b9b39ff33e588dbdde0d20bfe25408c49c
parent 13801688
......@@ -20,6 +20,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx
TestMinimalStandardRandomSequence.cxx
TestNew.cxx
TestObservers.cxx
TestPlane.cxx
TestPolynomialSolversUnivariate.cxx
TestSmartPointer.cxx
TestSortDataArray.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestPlane.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkMath.h"
#include "vtkPlane.h"
#include "vtkSmartPointer.h"
#include <vtkstd/limits>
#ifndef ABS
#define ABS(x) ((x) < 0 ? -(x) : (x))
#endif
template<class A>
bool fuzzyCompare1D(A a, A b)
{
return ABS(a - b) < vtkstd::numeric_limits<A>::epsilon();
}
template<class A>
bool fuzzyCompare3D(A a[3], A b[3])
{
return fuzzyCompare1D(a[0], b[0]) &&
fuzzyCompare1D(a[1], b[1]) &&
fuzzyCompare1D(a[2], b[2]);
}
int TestPlane(int,char *[])
{
// Test ProjectVector (vector is out of plane)
{
vtkSmartPointer<vtkPlane> plane =
vtkSmartPointer<vtkPlane>::New();
plane->SetOrigin(0.0, 0.0, 0.0);
plane->SetNormal(0,0,1);
std::cout << "Testing ProjectVector" << std::endl;
double v[3] = {1,2,3};
double projection[3];
double correct[3] = {1., 2., 0};
plane->ProjectVector(v, projection);
if(!fuzzyCompare3D(projection,correct))
{
std::cerr << "ProjectVector failed! Should be (1., 2., 0) but it is ("
<< projection[0] << " " << projection[1] << " " << projection[2] << ")" << std::endl;
return EXIT_FAILURE;
}
}
// Test ProjectVector where vector is already in plane
{
vtkSmartPointer<vtkPlane> plane =
vtkSmartPointer<vtkPlane>::New();
plane->SetOrigin(0.0, 0.0, 0.0);
plane->SetNormal(0,0,1);
std::cout << "Testing ProjectVector" << std::endl;
double v[3] = {1,2,0};
double projection[3];
double correct[3] = {1., 2., 0};
plane->ProjectVector(v, projection);
if(!fuzzyCompare3D(projection,correct))
{
std::cerr << "ProjectVector failed! Should be (1., 2., 0) but it is ("
<< projection[0] << " " << projection[1] << " " << projection[2] << ")" << std::endl;
return EXIT_FAILURE;
}
}
// Test ProjectVector where vector is orthogonal to plane
{
vtkSmartPointer<vtkPlane> plane =
vtkSmartPointer<vtkPlane>::New();
plane->SetOrigin(0.0, 0.0, 0.0);
plane->SetNormal(0,0,1);
std::cout << "Testing ProjectVector" << std::endl;
double v[3] = {0,0,1};
double projection[3];
double correct[3] = {0., 0., 0.};
plane->ProjectVector(v, projection);
if(!fuzzyCompare3D(projection,correct))
{
std::cerr << "ProjectVector failed! Should be (0., 0., 0) but it is ("
<< projection[0] << " " << projection[1] << " " << projection[2] << ")" << std::endl;
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
......@@ -56,6 +56,28 @@ void vtkPlane::ProjectPoint(double x[3], double xproj[3])
this->ProjectPoint(x, this->GetOrigin(), this->GetNormal(), xproj);
}
void vtkPlane::ProjectVector(double v[3], double origin[3], double normal[3],
double vproj[3])
{
// This function uses this equation:
// projected = vector - (vector dot Normal)Normal
// Where 'Normal' is unit length
vtkMath::Normalize(normal);
double dotProd = vtkMath::Dot(v, normal);
vtkMath::MultiplyScalar(normal, dotProd);
vtkMath::Subtract(v, normal, vproj);
}
void vtkPlane::ProjectVector(double v[3], double vproj[3])
{
this->ProjectVector(v, this->GetOrigin(), this->GetNormal(), vproj);
}
void vtkPlane::Push(double distance)
{
int i;
......
......@@ -69,6 +69,13 @@ public:
double xproj[3]);
void ProjectPoint(double x[3], double xproj[3]);
// Description
// Project a vector v onto plane defined by origin and normal. The
// projected vector is returned in vproj.
static void ProjectVector(double v[3], double origin[3], double normal[3],
double vproj[3]);
void ProjectVector(double v[3], double vproj[3]);
// Description
// Project a point x onto plane defined by origin and normal. The
// projected point is returned in xproj. NOTE : normal does NOT have to
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment