pub struct Ray {
pub origin: Point,
pub direction: Vector,
}
Expand description
Represents a Ray object in three-dimensional space.
Fields§
§origin: Point
§direction: Vector
Implementations§
Source§impl Ray
impl Ray
Sourcepub fn new(origin: Point, direction: Vector) -> Ray
pub fn new(origin: Point, direction: Vector) -> Ray
Creates a new Ray.
New created Ray will have a direction
unitized automatically.
§Example
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let result = Ray::new(Point::new(0.0, 1.0, -2.5), Vector::new(1.0, 0.0, 0.0));
assert_eq!(result.origin.eq(&Point::new(0.0, 1.0, -2.5)), true);
assert_eq!(result.direction.eq(&Vector::new(1.0, 0.0, 0.0)), true);
Source§impl Ray
impl Ray
Sourcepub fn eq_with_tolerance(&self, other: &Ray, tolerance: f64) -> bool
pub fn eq_with_tolerance(&self, other: &Ray, tolerance: f64) -> bool
Compares given Ray to other one, but with a f64
tolerance.
If any value absolute difference is > tolerance, then it should return false
.
§Examples
In this example we can see the differences of coordinates are not > tolerance, so we expect true
.
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let tolerance: f64 = 0.001;
let a = Ray::new(Point::new(0.0, 1.0, -2.5), Vector::new(1.0, 0.0, 0.0));
let b = Ray::new(Point::new(0.0, 1.0 + 0.001, -2.5), Vector::new(1.0, 0.0, 0.0 + 0.0009));
assert_eq!(a.eq_with_tolerance(&b, tolerance), true);
In this example we can see the Y-coordinate absolute difference is > tolerance, so we expect ‘false’.
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let tolerance: f64 = 0.001;
let a = Ray::new(Point::new(0.0, 1.0, -2.5), Vector::new(1.0, 0.0, 0.0));
let b = Ray::new(Point::new(0.0, 1.0 + 0.0011, -2.5), Vector::new(1.0, 0.0, 0.0 + 0.0009));
assert_eq!(a.eq_with_tolerance(&b, tolerance), false);
Sourcepub fn does_intersect_with_mesh(&self, mesh: &Mesh) -> bool
pub fn does_intersect_with_mesh(&self, mesh: &Mesh) -> bool
Checks if this Ray hits given Mesh.
If it hits: then true
is returned, if not: false
.
Orientations of Triangles are not taken into an account.
§Examples
First example shows detecting of hit, so true
is expected.
use meshmeshmesh::mesh::Mesh;
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let mesh = Mesh::new(
vec![
// Base
-2.0,1.0,0.0,
8.0,1.0,0.0,
8.0,11.0,0.0,
-2.0,11.0,0.0,
// Top
3.0,6.0,4.0
],
vec![
// Base faces
0,1,2,
0,2,3,
// Side faces
0,1,4,
1,2,4,
2,3,4,
3,0,4
]);
let ray = Ray::new(Point::new(-4.912183, 2.730841, 0.76832), Vector::new(0.853281,0.510629,0.105683));
let actual = ray.does_intersect_with_mesh(&mesh);
assert_eq!(actual, true);
Second example shows not hitting the Mesh, so false
is expected.
use meshmeshmesh::mesh::Mesh;
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let mesh = Mesh::new(
vec![
// Base
-2.0,1.0,0.0,
8.0,1.0,0.0,
8.0,11.0,0.0,
-2.0,11.0,0.0,
// Top
3.0,6.0,4.0
],
vec![
// Base faces
0,1,2,
0,2,3,
// Side faces
0,1,4,
1,2,4,
2,3,4,
3,0,4
]);
let ray = Ray::new(Point::new(-4.912183, 7.757342, 0.76832), Vector::new(0.853281,0.510629,0.105683));
let actual = ray.does_intersect_with_mesh(&mesh);
assert_eq!(actual, false);
Sourcepub fn get_point_at(&self, distance: f64) -> Point
pub fn get_point_at(&self, distance: f64) -> Point
Creates a Point which is located on Ray with the given distance
from the Ray’s origin
.
Negative value of distance is also accepted, will create a Point in the reversed direction.
§Example
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let ray = Ray::new(Point::new(1.0, 2.0, 3.0), Vector::new(0.660831,0.569323,0.489054));
let distance = 5.0;
let expected = Point::new(4.304155, 4.846615, 5.445269);
let actual = ray.get_point_at(distance);
assert_eq!(expected.eq_with_tolerance(&actual, 0.001), true);
Sourcepub fn get_distance_from_origin_to_closest_point(&self, point: &Point) -> f64
pub fn get_distance_from_origin_to_closest_point(&self, point: &Point) -> f64
Gets distance from Rays origin to the closest Point to the given one, which is located on the Ray.
If the output distance is negative, this means the closest Point is located in the opposite direction.
§Examples
This an example with positive distance as an output.
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let input = Ray::new(Point::new(19.945547, 14.606347, 25.49375), Vector::new(0.62795,-0.249624,0.737134));
let point = Point::new(14.64437, -18.601827, 38.908651);
let actual = input.get_distance_from_origin_to_closest_point(&point);
let expected = 14.84926367021245;
assert_eq!(actual, expected);
The example below shows the case with negative distance as output.
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let input = Ray::new(Point::new(19.945547, 14.606347, 25.49375), Vector::new(0.62795,-0.249624,0.737134));
let point = Point::new(-10.121151, -18.601827, 14.761326);
let actual = input.get_distance_from_origin_to_closest_point(&point);
let expected = -18.502061545519965;
assert_eq!(actual, expected);
Sourcepub fn get_intersection_with_triangle(
&self,
triangle: &Triangle,
) -> Option<Point>
pub fn get_intersection_with_triangle( &self, triangle: &Triangle, ) -> Option<Point>
Calculates intersection of the Ray with given Triangle using Möller–Trumbore intersection algorithm.
It uses epsilon
value for check if the Ray is parallel to Triangle.
§Examples
Here below there is an example of hitting the Triangle with the Ray
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::triangle::Triangle;
use meshmeshmesh::vector::Vector;
let triangle = Triangle::new(Point::new(18.106339, 26.580607, 7.381013), Point::new(27.733604, 26.580607, 28.757986), Point::new(24.296286, -0.019341, 19.121015));
let ray = Ray::new(Point::new(1.0, 2.0, 3.0), Vector::new(0.660831,0.569323,0.489054));
let expected = Point::new(23.94358, 21.766485, 19.979597);
let actual = ray.get_intersection_with_triangle(&triangle).unwrap();
assert_eq!(expected.eq_with_tolerance(&actual, 0.001), true);
Below is an example of Ray that misses the Triangle
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::triangle::Triangle;
use meshmeshmesh::vector::Vector;
let triangle = Triangle::new(Point::new(18.106339, 26.580607, 7.381013), Point::new(27.733604, 26.580607, 28.757986), Point::new(24.296286, -0.019341, 19.121015));
let ray = Ray::new(Point::new(1.0, 2.0, 3.0), Vector::new(0.590527,0.508754,0.626457));
let actual_option = ray.get_intersection_with_triangle(&triangle);
assert_eq!(actual_option.is_none(), true);
Sourcepub fn get_intersections_with_mesh(&self, mesh: &Mesh) -> Vec<Point>
pub fn get_intersections_with_mesh(&self, mesh: &Mesh) -> Vec<Point>
Calculates Ray’s intersections with the Mesh.
It iterates all the Triangles and for each it tries to get an intersection.
§Examples
There is an example below with a Ray hitting the Mesh, returning 2 intersection Points.
use meshmeshmesh::mesh::Mesh;
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let mesh = Mesh::new(
vec![
// Base
-2.0,1.0,0.0,
8.0,1.0,0.0,
8.0,11.0,0.0,
-2.0,11.0,0.0,
// Top
3.0,6.0,4.0
],
vec![
// Base faces
0,1,2,
0,2,3,
// Side faces
0,1,4,
1,2,4,
2,3,4,
3,0,4
]);
let ray = Ray::new(Point::new(-4.912183, 2.730841, 0.76832), Vector::new(0.853281,0.510629,0.105683));
let actual = ray.get_intersections_with_mesh(&mesh);
let expected = vec![Point::new(4.790800375717201,8.537397923404011,1.9700816612767906), Point::new(-0.3302282935488474,5.472820429754613,1.3358173651609224)];
assert_eq!(actual.len(), 2);
assert_eq!(actual[0].eq_with_tolerance(&expected[0], 0.001), true);
assert_eq!(actual[1].eq_with_tolerance(&expected[1], 0.001), true);
The example below shows the case where Ray misses the Mesh, so there is an empty vector
returned.
use meshmeshmesh::mesh::Mesh;
use meshmeshmesh::point::Point;
use meshmeshmesh::ray::Ray;
use meshmeshmesh::vector::Vector;
let mesh = Mesh::new(
vec![
// Base
-2.0,1.0,0.0,
8.0,1.0,0.0,
8.0,11.0,0.0,
-2.0,11.0,0.0,
// Top
3.0,6.0,4.0
],
vec![
// Base faces
0,1,2,
0,2,3,
// Side faces
0,1,4,
1,2,4,
2,3,4,
3,0,4
]);
let ray = Ray::new(Point::new(-4.912183, 7.757342, 0.76832), Vector::new(0.853281,0.510629,0.105683));
let actual = ray.get_intersections_with_mesh(&mesh);
assert_eq!(actual.is_empty(), true);