Gazebo Math
API Reference
9.3.0
insert_drive_file
Tutorials
library_books
Classes
toc
Namespaces
insert_drive_file
Files
launch
Gazebo Website
Index
List
Hierarchy
Members: All
Members: Functions
Members: Variables
Members: Typedefs
Members: Enumerations
Members: Enumerator
List
Members
Functions
Typedefs
Variables
Enumerations
Enumerator
src
gz-math
include
gz
math
Line3.hh
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2015 Open Source Robotics Foundation
3
*
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
7
*
8
* http://www.apache.org/licenses/LICENSE-2.0
9
*
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
15
*
16
*/
17
#ifndef GZ_MATH_LINE3_HH_
18
#define GZ_MATH_LINE3_HH_
19
20
#include <algorithm>
21
#include <
gz/math/Vector3.hh
>
22
#include <gz/math/config.hh>
23
24
namespace
gz::math
25
{
26
// Inline bracket to help doxygen filtering.
27
inline
namespace
GZ_MATH_VERSION_NAMESPACE {
28
//
32
template
<
typename
T>
33
class
Line3
34
{
36
public
:
Line3
() =
default
;
37
41
public
:
Line3
(
const
math::Vector3<T>
&
_ptA
,
const
math::Vector3<T>
&
_ptB
)
42
{
43
this->Set(
_ptA
,
_ptB
);
44
}
45
51
public
:
Line3
(
const
double
_x1
,
const
double
_y1
,
52
const
double
_x2
,
const
double
_y2
)
53
{
54
this->Set(
_x1
,
_y1
,
_x2
,
_y2
);
55
}
56
64
public
:
Line3
(
const
double
_x1
,
const
double
_y1
,
65
const
double
_z1
,
const
double
_x2
,
66
const
double
_y2
,
const
double
_z2
)
67
{
68
this->Set(
_x1
,
_y1
,
_z1
,
_x2
,
_y2
,
_z2
);
69
}
70
74
public
:
void
Set
(
const
math::Vector3<T>
&
_ptA
,
75
const
math::Vector3<T>
&
_ptB
)
76
{
77
this->pts[0] =
_ptA
;
78
this->pts[1] =
_ptB
;
79
}
80
83
public
:
void
SetA
(
const
math::Vector3<T>
&
_ptA
)
84
{
85
this->pts[0] =
_ptA
;
86
}
87
90
public
:
void
SetB
(
const
math::Vector3<T>
&
_ptB
)
91
{
92
this->pts[1] =
_ptB
;
93
}
94
103
public
:
void
Set
(
const
double
_x1
,
const
double
_y1
,
104
const
double
_x2
,
const
double
_y2
,
105
const
double
_z
= 0)
106
{
107
this->pts[0].
Set
(
108
static_cast<
T
>
(
_x1
),
static_cast<
T
>
(
_y1
),
static_cast<
T
>
(
_z
));
109
this->pts[1].
Set
(
110
static_cast<
T
>
(
_x2
),
static_cast<
T
>
(
_y2
),
static_cast<
T
>
(
_z
));
111
}
112
120
public
:
void
Set
(
const
double
_x1
,
const
double
_y1
,
121
const
double
_z1
,
const
double
_x2
,
122
const
double
_y2
,
const
double
_z2
)
123
{
124
this->pts[0].
Set
(
125
static_cast<
T
>
(
_x1
),
static_cast<
T
>
(
_y1
),
static_cast<
T
>
(
_z1
));
126
this->pts[1].
Set
(
127
static_cast<
T
>
(
_x2
),
static_cast<
T
>
(
_y2
),
static_cast<
T
>
(
_z2
));
128
}
129
132
public
:
math::Vector3<T>
Direction
()
const
133
{
134
return
(this->pts[1] - this->pts[0]).Normalize();
135
}
136
139
public
: T
Length
()
const
140
{
141
return
static_cast<
T
>
(this->pts[0].Distance(this->pts[1]));
142
}
143
154
public
:
bool
Distance
(
const
Line3<T>
&
_line
,
Line3<T>
&
_result
,
155
const
double
_epsilon
= 1
e
-6)
const
156
{
157
Vector3<T>
p13
= this->pts[0] -
_line
[0];
158
Vector3<T>
p43
=
_line
[1] -
_line
[0];
159
160
if
(std::abs(
p43
.X()) <
_epsilon
&& std::abs(
p43
.Y()) <
_epsilon
&&
161
std::abs(
p43
.Z()) <
_epsilon
)
162
{
163
return
false
;
164
}
165
166
Vector3<T>
p21
= this->pts[1] - this->pts[0];
167
168
if
(std::abs(
p21
.X()) <
_epsilon
&& std::abs(
p21
.Y()) <
_epsilon
&&
169
std::abs(
p21
.Z()) <
_epsilon
)
170
{
171
return
false
;
172
}
173
174
double
d1343
=
p13
.Dot(
p43
);
175
double
d4321
=
p43
.Dot(
p21
);
176
double
d1321
=
p13
.Dot(
p21
);
177
double
d4343
=
p43
.Dot(
p43
);
178
double
d2121
=
p21
.Dot(
p21
);
179
180
double
denom
=
d2121
*
d4343
-
d4321
*
d4321
;
181
182
// In this case, we choose the first point in this line,
183
// and the closest point in the provided line.
184
if
(std::abs(
denom
) <
_epsilon
)
185
{
186
double
d1
= this->pts[0].Distance(
_line
[0]);
187
double
d2
= this->pts[0].Distance(
_line
[1]);
188
189
double
d3
= this->pts[1].Distance(
_line
[0]);
190
double
d4
= this->pts[1].Distance(
_line
[1]);
191
192
if
(
d1
<=
d2
&&
d1
<=
d3
&&
d1
<=
d4
)
193
{
194
_result
.SetA(this->pts[0]);
195
_result
.SetB(
_line
[0]);
196
}
197
else
if
(
d2
<=
d3
&&
d2
<=
d4
)
198
{
199
_result
.SetA(this->pts[0]);
200
_result
.SetB(
_line
[1]);
201
}
202
else
if
(
d3
<=
d4
)
203
{
204
_result
.SetA(this->pts[1]);
205
_result
.SetB(
_line
[0]);
206
}
207
else
208
{
209
_result
.SetA(this->pts[1]);
210
_result
.SetB(
_line
[1]);
211
}
212
213
return
true
;
214
}
215
216
double
numer
=
d1343
*
d4321
-
d1321
*
d4343
;
217
218
double
mua
=
clamp
(
numer
/
denom
, 0.0, 1.0);
219
double
mub
=
clamp
((
d1343
+
d4321
*
mua
) /
d4343
, 0.0, 1.0);
220
221
_result
.
Set
(this->pts[0] + (
p21
*
static_cast<
T
>
(
mua
)),
222
_line
[0] + (
p43
*
static_cast<
T
>
(
mub
)));
223
224
return
true
;
225
}
226
230
public
: T
Distance
(
const
Vector3<T>
&
_pt
)
231
{
232
auto
line
= this->pts[1] - this->pts[0];
233
auto
ptTo0
=
_pt
- this->pts[0];
234
auto
ptTo1
=
_pt
- this->pts[1];
235
236
// Point is projected beyond pt0 or the line has length 0
237
if
(
ptTo0
.Dot(
line
) <=
static_cast<
T
>
(0))
238
{
239
return
ptTo0
.Length();
240
}
241
242
// Point is projected beyond pt1
243
if
(
ptTo1
.Dot(
line
) >=
static_cast<
T
>
(0))
244
{
245
return
ptTo1
.Length();
246
}
247
248
// Distance to point projected onto line
249
// line.Length() will have to be > 0 at this point otherwise it would
250
// return at line 244.
251
auto
d =
ptTo0
.Cross(
line
);
252
auto
lineLength
=
line
.Length();
253
assert
(
lineLength
> 0);
254
return
d.Length() /
lineLength
;
255
}
256
262
public
:
bool
Intersect
(
const
Line3<T>
&
_line
,
263
double
_epsilon
= 1
e
-6)
const
264
{
265
math::Vector3<T>
ignore;
266
return
this->Intersect(
_line
, ignore,
_epsilon
);
267
}
268
274
public
:
bool
Coplanar
(
const
Line3<T>
&
_line
,
275
const
double
_epsilon
= 1
e
-6)
const
276
{
277
return
std::abs((
_line
[0] - this->pts[0]).Dot(
278
(this->pts[1] - this->pts[0]).Cross(
_line
[1] -
_line
[0])))
279
<=
_epsilon
;
280
}
281
287
public
:
bool
Parallel
(
const
Line3<T>
&
_line
,
288
const
double
_epsilon
= 1
e
-6)
const
289
{
290
return
(this->pts[1] - this->pts[0]).Cross(
291
_line
[1] -
_line
[0]).Length() <=
_epsilon
;
292
}
293
302
public
:
bool
Intersect
(
const
Line3<T>
&
_line
,
math::Vector3<T>
&
_pt
,
303
double
_epsilon
= 1
e
-6)
const
304
{
305
// Handle special case when lines are parallel
306
if
(this->Parallel(
_line
,
_epsilon
))
307
{
308
// Check if _line's starting point is on the line.
309
if
(this->Within(
_line
[0],
_epsilon
))
310
{
311
_pt
=
_line
[0];
312
return
true
;
313
}
314
// Check if _line's ending point is on the line.
315
else
if
(this->Within(
_line
[1],
_epsilon
))
316
{
317
_pt
=
_line
[1];
318
return
true
;
319
}
320
// Otherwise return false.
321
else
322
return
false
;
323
}
324
325
// Get the line that is the shortest distance between this and _line
326
math::Line3<T>
distLine
;
327
this->Distance(
_line
,
distLine
,
_epsilon
);
328
329
// If the length of the line is less than epsilon, then they
330
// intersect.
331
if
(
distLine
.Length() <
_epsilon
)
332
{
333
_pt
=
distLine
[0];
334
return
true
;
335
}
336
337
return
false
;
338
}
339
346
public
:
bool
Within
(
const
math::Vector3<T>
&
_pt
,
347
double
_epsilon
= 1
e
-6)
const
348
{
349
auto
eps
=
static_cast<
T
>
(
_epsilon
);
350
return
_pt
.X() <=
std::max
(this->pts[0].X(),
351
this->pts[1].X()) +
eps
&&
352
_pt
.X() >=
std::min
(this->pts[0].X(),
353
this->pts[1].X()) -
eps
&&
354
_pt
.Y() <=
std::max
(this->pts[0].Y(),
355
this->pts[1].Y()) +
eps
&&
356
_pt
.Y() >=
std::min
(this->pts[0].Y(),
357
this->pts[1].Y()) -
eps
&&
358
_pt
.Z() <=
std::max
(this->pts[0].Z(),
359
this->pts[1].Z()) +
eps
&&
360
_pt
.Z() >=
std::min
(this->pts[0].Z(),
361
this->pts[1].Z()) -
eps
;
362
}
363
367
public
:
bool
operator==
(
const
Line3<T>
&
_line
)
const
368
{
369
return
this->pts[0] ==
_line
[0] && this->pts[1] ==
_line
[1];
370
}
371
375
public
:
bool
operator!=
(
const
Line3<T>
&
_line
)
const
376
{
377
return
!(*
this
==
_line
);
378
}
379
383
public
:
math::Vector3<T>
operator[]
(
const
size_t
_index
)
const
384
{
385
return
this->pts[
clamp
(
_index
, GZ_ZERO_SIZE_T, GZ_ONE_SIZE_T)];
386
}
387
392
public
:
friend
std::ostream
&
operator<<
(
393
std::ostream
&
_out
,
const
Line3<T>
&
_line
)
394
{
395
_out
<<
_line
[0] <<
" "
<<
_line
[1];
396
return
_out
;
397
}
398
400
private
:
math::Vector3<T>
pts[2];
401
};
402
403
typedef
Line3<int>
Line3i
;
404
typedef
Line3<double>
Line3d
;
405
typedef
Line3<float>
Line3f
;
406
}
// namespace GZ_MATH_VERSION_NAMESPACE_
407
}
// namespace gz::math
408
#endif
// GZ_MATH_LINE3_HH_