vtkPlane.cxx 5.58 KB
Newer Older
Will Schroeder's avatar
Will Schroeder committed
1
2
/*=========================================================================

Ken Martin's avatar
Ken Martin committed
3
  Program:   Visualization Toolkit
Ken Martin's avatar
Ken Martin committed
4
  Module:    vtkPlane.cxx
Will Schroeder's avatar
Will Schroeder committed
5

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7
8
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
Ken Martin's avatar
Ken Martin committed
9

10
11
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
     PURPOSE.  See the above copyright notice for more information.
Will Schroeder's avatar
Will Schroeder committed
13
14

=========================================================================*/
Ken Martin's avatar
Ken Martin committed
15
16
#include "vtkPlane.h"
#include "vtkMath.h"
17
18
#include "vtkObjectFactory.h"

Brad King's avatar
Brad King committed
19
vtkStandardNewMacro(vtkPlane);
20

Will Schroeder's avatar
Will Schroeder committed
21
// Construct plane passing through origin and normal to z-axis.
Ken Martin's avatar
Ken Martin committed
22
vtkPlane::vtkPlane()
Will Schroeder's avatar
Will Schroeder committed
23
24
25
26
27
28
29
30
31
32
{
  this->Normal[0] = 0.0;
  this->Normal[1] = 0.0;
  this->Normal[2] = 1.0;

  this->Origin[0] = 0.0;
  this->Origin[1] = 0.0;
  this->Origin[2] = 0.0;
}

33
34
35
36
37
double vtkPlane::DistanceToPlane(double x[3])
{
  return this->DistanceToPlane(x, this->GetNormal(), this->GetOrigin());
}

38
void vtkPlane::ProjectPoint(double x[3], double origin[3],
Ken Martin's avatar
Ken Martin committed
39
                            double normal[3], double xproj[3])
40
41
42
43
44
45
46
47
{
  double t, xo[3];

  xo[0] = x[0] - origin[0];
  xo[1] = x[1] - origin[1];
  xo[2] = x[2] - origin[2];

  t = vtkMath::Dot(normal,xo);
Jim Miller's avatar
Jim Miller committed
48
49
50
51

  xproj[0] = x[0] - t * normal[0];
  xproj[1] = x[1] - t * normal[1];
  xproj[2] = x[2] - t * normal[2];
Will Schroeder's avatar
Will Schroeder committed
52
}
Will Schroeder's avatar
Will Schroeder committed
53

54
55
56
57
58
void vtkPlane::ProjectPoint(double x[3], double xproj[3])
{
  this->ProjectPoint(x, this->GetOrigin(), this->GetNormal(), xproj);
}

59
60
61
void vtkPlane::ProjectVector(
  double v[3], double vtkNotUsed(origin)[3], double normal[3],
  double vproj[3])
62
{
63
64
65
66
67
68
69
70
71
  double t = vtkMath::Dot(v, normal);
  double n2 = vtkMath::Dot(normal, normal);
  if (n2 == 0)
    {
    n2 = 1.0;
    }
  vproj[0] = v[0] - t * normal[0] / n2;
  vproj[1] = v[1] - t * normal[1] / n2;
  vproj[2] = v[2] - t * normal[2] / n2;
72
73
74
75
76
77
78
79
}

void vtkPlane::ProjectVector(double v[3], double vproj[3])
{
  this->ProjectVector(v, this->GetOrigin(), this->GetNormal(), vproj);
}


Ken Martin's avatar
Ken Martin committed
80
void vtkPlane::Push(double distance)
81
82
83
84
85
86
87
88
89
90
91
92
93
94
{
  int i;

  if ( distance == 0.0 )
    {
    return;
    }
  for (i=0; i < 3; i++ )
    {
    this->Origin[i] += distance * this->Normal[i];
    }
  this->Modified();
}

95
// Project a point x onto plane defined by origin and normal. The
96
97
// projected point is returned in xproj. NOTE : normal NOT required to
// have magnitude 1.
Ken Martin's avatar
Ken Martin committed
98
99
void vtkPlane::GeneralizedProjectPoint(double x[3], double origin[3],
                                       double normal[3], double xproj[3])
100
{
Ken Martin's avatar
Ken Martin committed
101
  double t, xo[3], n2;
102
103
104
105
106
107

  xo[0] = x[0] - origin[0];
  xo[1] = x[1] - origin[1];
  xo[2] = x[2] - origin[2];

  t = vtkMath::Dot(normal,xo);
Burlen Loring's avatar
Burlen Loring committed
108
  n2 = vtkMath::Dot(normal, normal);
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

  if (n2 != 0)
    {
    xproj[0] = x[0] - t * normal[0]/n2;
    xproj[1] = x[1] - t * normal[1]/n2;
    xproj[2] = x[2] - t * normal[2]/n2;
    }
  else
    {
    xproj[0] = x[0];
    xproj[1] = x[1];
    xproj[2] = x[2];
    }
}

124
125
126
127
128
void vtkPlane::GeneralizedProjectPoint(double x[3], double xproj[3])
{
  this->GeneralizedProjectPoint(x, this->GetOrigin(), this->GetNormal(), xproj);
}

129
// Evaluate plane equation for point x[3].
Ken Martin's avatar
Ken Martin committed
130
double vtkPlane::EvaluateFunction(double x[3])
Will Schroeder's avatar
Will Schroeder committed
131
{
132
133
  return ( this->Normal[0]*(x[0]-this->Origin[0]) +
           this->Normal[1]*(x[1]-this->Origin[1]) +
134
           this->Normal[2]*(x[2]-this->Origin[2]) );
Will Schroeder's avatar
Will Schroeder committed
135
}
Will Schroeder's avatar
Will Schroeder committed
136

137
// Evaluate function gradient at point x[3].
Ken Martin's avatar
Ken Martin committed
138
void vtkPlane::EvaluateGradient(double vtkNotUsed(x)[3], double n[3])
Will Schroeder's avatar
Will Schroeder committed
139
{
Jim Miller's avatar
Style    
Jim Miller committed
140
141
142
143
  for (int i=0; i<3; i++)
    {
    n[i] = this->Normal[i];
    }
Will Schroeder's avatar
Will Schroeder committed
144
}
145

Jim Miller's avatar
Style    
Jim Miller committed
146
#define VTK_PLANE_TOL 1.0e-06
Will Schroeder's avatar
Will Schroeder committed
147

148
149
// Given a line defined by the two points p1,p2; and a plane defined by the
// normal n and point p0, compute an intersection. The parametric
150
// coordinate along the line is returned in t, and the coordinates of
151
// intersection are returned in x. A zero is returned if the plane and line
152
// do not intersect between (0<=t<=1). If the plane and line are parallel,
Ken Martin's avatar
Ken Martin committed
153
// zero is returned and t is set to VTK_LARGE_DOUBLE.
154
int vtkPlane::IntersectWithLine(double p1[3], double p2[3], double n[3],
Ken Martin's avatar
Ken Martin committed
155
                               double p0[3], double& t, double x[3])
156
{
Ken Martin's avatar
Ken Martin committed
157
158
  double num, den, p21[3];
  double fabsden, fabstolerance;
159

Jim Miller's avatar
Style    
Jim Miller committed
160
  // Compute line vector
161
  //
Jim Miller's avatar
Jim Miller committed
162
163
164
165
  p21[0] = p2[0] - p1[0];
  p21[1] = p2[1] - p1[1];
  p21[2] = p2[2] - p1[2];

Jim Miller's avatar
Style    
Jim Miller committed
166
  // Compute denominator.  If ~0, line and plane are parallel.
167
  //
168
  num = vtkMath::Dot(n,p0) - ( n[0]*p1[0] + n[1]*p1[1] + n[2]*p1[2] ) ;
169
  den = n[0]*p21[0] + n[1]*p21[1] + n[2]*p21[2];
Jim Miller's avatar
Style    
Jim Miller committed
170
171
  //
  // If denominator with respect to numerator is "zero", then the line and
172
  // plane are considered parallel.
Jim Miller's avatar
Style    
Jim Miller committed
173
  //
Jim Miller's avatar
Jim Miller committed
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

  // trying to avoid an expensive call to fabs()
  if (den < 0.0)
    {
    fabsden = -den;
    }
  else
    {
    fabsden = den;
    }
  if (num < 0.0)
    {
    fabstolerance = -num*VTK_PLANE_TOL;
    }
  else
    {
    fabstolerance = num*VTK_PLANE_TOL;
    }
  if ( fabsden <= fabstolerance )
Jim Miller's avatar
Style    
Jim Miller committed
193
    {
Ken Martin's avatar
Ken Martin committed
194
    t = VTK_DOUBLE_MAX;
Jim Miller's avatar
Style    
Jim Miller committed
195
196
    return 0;
    }
197

198
  // valid intersection
199
  t = num / den;
Jim Miller's avatar
Jim Miller committed
200
201
202
203

  x[0] = p1[0] + t*p21[0];
  x[1] = p1[1] + t*p21[1];
  x[2] = p1[2] + t*p21[2];
Jim Miller's avatar
Style    
Jim Miller committed
204
205
206
207
208
209
210
211
212

  if ( t >= 0.0 && t <= 1.0 )
    {
    return 1;
    }
  else
    {
    return 0;
    }
213
}
Will Schroeder's avatar
Will Schroeder committed
214

215
216
217
218
219
int vtkPlane::IntersectWithLine(double p1[3], double p2[3], double& t, double x[3])
{
  return this->IntersectWithLine(p1, p2, this->GetNormal(), this->GetOrigin(), t, x);
}

220
void vtkPlane::PrintSelf(ostream& os, vtkIndent indent)
Will Schroeder's avatar
Will Schroeder committed
221
{
Brad King's avatar
Brad King committed
222
  this->Superclass::PrintSelf(os,indent);
Will Schroeder's avatar
Will Schroeder committed
223

224
  os << indent << "Normal: (" << this->Normal[0] << ", "
Will Schroeder's avatar
Will Schroeder committed
225
226
    << this->Normal[1] << ", " << this->Normal[2] << ")\n";

227
  os << indent << "Origin: (" << this->Origin[0] << ", "
Will Schroeder's avatar
Will Schroeder committed
228
229
    << this->Origin[1] << ", " << this->Origin[2] << ")\n";
}