Files
deighton-ar/mobile/ios/ViroKit.framework/Headers/VROLineSegment.h
2018-03-27 17:46:15 -07:00

232 lines
7.3 KiB
C++

//
// VROTriangle.h
// ViroRenderer
//
// Created by Raj Advani on 10/12/16.
// Copyright © 2016 Viro Media. All rights reserved.
//
#ifndef VROLINESEGMENT_H_
#define VROLINESEGMENT_H_
#include "VROVector3f.h"
enum class VROOrientation {
Colinear = 0,
Left = 1,
Right = -1
};
class VROLineSegment {
public:
/*
Construct a new {@link LineSegment}.
@param A
First point.
@param B
Second point.
*/
VROLineSegment(VROVector3f A, VROVector3f B);
/*
Get the start and end of this segment.
*/
VROVector3f getA() const;
VROVector3f getB() const;
/*
Get a ray representation of the segment, the midpoint or the length.
*/
VROVector3f ray() const;
VROVector3f midpoint() const;
float length() const;
float lengthApprox() const;
/*
Flip the orientation of this segment (set A to B and vice-versa).
*/
VROLineSegment flip() const;
/*
Returns the orientation (as a VROOrientation) of the direction of the point p relative
to this segment.
*/
VROOrientation orientationOfPoint(VROVector3f q) const;
/*
Test if this segment intersects the given 2D segment or 2D box.
*/
bool intersectsSegment2D(VROLineSegment other) const;
bool intersectsSegment2D(VROLineSegment other, VROVector3f *result) const;
bool intersectsBox2D(float left, float right, float bottom, float top) const;
/*
Test if the line represented by this segment intersects the line represented by the
given segment. This function treats both segments as infinitely extending lines.
*/
bool intersectsLine(VROLineSegment other, VROVector3f *result) const;
/*
Test if this line segment intersects plane defined by the given point and normal.
Return true if so, storing the intersection point in the given out vector.
*/
bool intersectsPlane(VROVector3f point, VROVector3f normal, VROVector3f *outIntersectionPoint) const;
/*
Get the angle this segment makes with the given other line-segment,
normalized to the range [0, PI/2]. Note that this method ignores the
<i>direction</i> of the line-segment (we do not treat line-segments like
rays).
*/
float angleWithSegment(VROLineSegment other) const;
float angle2DWithSegment(VROLineSegment other) const;
/*
Get the angle this segment makes with the given other line-segment,
normalized to the range [-PI, PI]. Note that this method takes into
account the <i>direction</i> of the line-segment. A positive angle is
taken to mean the other segment is that many radians
<i>counter-clockwise</i> from this segment. Likewise, a negative angle
implies <i>clockwise</i> rotation.
For example, the angle between the segment [(0, -1) -> (0, 0)] and [(0,
0) -> (1,1)] is -45 degrees, as the latter is 45 degrees clockwise from
the former.
*/
float directedAngleWithSegment(VROLineSegment other) const;
/*
Compute the angle, in the same manner as directedAngleWithSegment, that this
segment makes with the given ray.
*/
float directedAngleWithRay(VROVector3f ray) const;
/*
Translate the segment by the given amount.
*/
VROLineSegment translate(VROVector3f translation) const;
/*
Rotate this line segment counter-clockwise about its center by the given
amount and return the result. Does not mutate this segment.
*/
VROLineSegment rotate(float radians) const;
/*
Rotate this line segment counter-clockwise about its start point, by the
given number of radians, and store the result. Does not mutate this
segment.
*/
VROLineSegment pivot(float radians) const;
/*
Scale this segment out by the given factor. This will essentially just
grow the segment, keeping its angle and midpoint the same.
*/
VROLineSegment scale(float scale) const;
/*
Get the normal unit vector in the positive or negative
direction for this line segment. This is a 2D calculation,
so the z-values in the line segment are ignored and the
z-value in the returned vector will be zero.
The returned vector will be <0, 0, 0> if this line
segment has an 2D-length of 0.
*/
VROVector3f normal2DUnitVector(bool positive) const;
/*
Extend this segment out by the given amount. This
essentially just pushes out the B endpoint in the direction of the segment.
The second function will push out the A endpoint in the reverse direction
of the segment, and the third does both.
*/
VROLineSegment extend(float amount) const;
VROLineSegment extendBackwards(float amount) const;
VROLineSegment extendForwardAndBackward(float amount) const;
/*
Shift the line segment by the given amount. This pushes out the A
and B endpoints in the direction of the segment.
*/
VROLineSegment shift(float amount) const;
/*
Traverse the line-segment by the given distance from the start-point and
return the result. If we overshoot either endpoint of the segment, just
interpolate away. The distance may be negative to go backward (from B to A
instead of A to B).
*/
VROVector3f traverseFromStart(float distance) const;
VROVector3f traverseFromEnd(float distance) const;
/*
Returns the 't' that gives the closest point on this line to
the given point 'p' for the vector operation 'AB * t + A', note
that this may be off of the actual line segment if t is not in
[0, 1]
see: * http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
*/
float parameterOfClosestPoint(VROVector3f p) const;
/*
Find the point on the line segment defined that is closest to
the given point. Call the closest point on the line P. Observe
that the vector formed by P and the given point is orthogonal
to the line defined by p1 and p2. Thus the dot product of these
two vectors is zero. From there we can calculate the x, y, and
z of the point P (after a lot of hairy algebra).
*/
VROVector3f pointOnLineSegmentClosestTo(VROVector3f p) const;
float distanceToPoint(VROVector3f v) const;
float distanceToPointSigned(VROVector3f v) const;
/*
Find the point on the infinite line given by this line segment
that is closest to the given point 'p'.
*/
VROVector3f pointOnLineClosestTo(VROVector3f p) const;
/*
Offset this line-segment by the given amount, and store the result in the
given segment. Positive distance offsets to the left, negative to the right.
*/
void offsetByDistance(double distance, VROLineSegment *result) const;
/*
Return a string representation of this segment.
*/
std::string toString() const;
inline bool operator==(const VROLineSegment &other) const {
return other.__A == __A && other.__B == __B;
}
private:
// Note: we use double underscores here (__A, __B, etc.) because _B is a
// reserved macro on some platforms (Android NDK)
/*
The two points joined by this segment.
*/
VROVector3f __A, __B;
/*
Useful values for intermediate calculations.
*/
float __ABx, __ABy, __ABz;
/*
Square of the length.
*/
float _lengthSq;
};
#endif /* VROLINESEGMENT_H_ */