Ray

Struct Ray 

Source
pub struct Ray {
    pub origin: Point,
    pub direction: Vector,
}
Expand description

Represents a Ray object in three-dimensional space.

Fields§

§origin: Point

The origin Point from which we shoot the Vector.

§direction: Vector

The direction Vector of the Ray. Should be an unitized Vector.

Implementations§

Source§

impl Ray

Source

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

Source

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);
Source

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);
Source

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);
Source

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);
Source

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);
Source

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);

Trait Implementations§

Source§

impl PartialEq for Ray

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl Freeze for Ray

§

impl RefUnwindSafe for Ray

§

impl Send for Ray

§

impl Sync for Ray

§

impl Unpin for Ray

§

impl UnwindSafe for Ray

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.