# 15.1.160. tablet_qt/graphics/linesegment.h¶

/*
Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
Created by Rudolf Cardinal (rnc1001@cam.ac.uk).

This file is part of CamCOPS.

CamCOPS is free software: you can redistribute it and/or modify
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

CamCOPS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once
#include <QPointF>
#include <QRectF>
#include <QTransform>

// Represents a line segment: a line from one piont to another.
//
// Its equation is
//      a(x - xm) + b(y - ym) = c       [1]
//
// http://stackoverflow.com/questions/385305/efficient-maths-algorithm-to-calculate-intersections

class LineSegment {
public:
LineSegment(const QPointF& from, const QPointF& to);

// Return c for given values of x and y; see [1] above
qreal c(qreal x, qreal y) const;  // 0 if point is on the line; otherwise, sign gives side

// Return c for a point pt = (x, y); see [1] above
qreal c(const QPointF& pt) const;

// Which side of the line is the point on?
// Returns -1 if c < 0; 0 if c == 0; +1 if c > 0; see [1] above.
int side(const QPointF& pt) const;

// Is this a point, not a line (i.e. start and end points are identical)?
bool isPoint() const;

// Is there overlap in the ranges defined by this line segment's
// x coordinates and the other's?
bool xRangesOverlap(const LineSegment& other) const;

// Is there overlap in the ranges defined by this line segment's
// y coordinates and the other's?
bool yRangesOverlap(const LineSegment& other) const;

// Does this line intersect the other?
bool intersects(const LineSegment& other) const;

// Is the point on the line?
bool pointOn(const QPointF& point) const;

// What's the angle of this line (heading from "from" to "to")?
// The angle is in radians where 0 is the direction of the x axis.

// Return the rectangle (with sides parallel to the x and y axes) that
// just encloses this line.
QRectF rect() const;

/*
Is the point in the area swept out by the line (swept perpendicular to it)?

Example 1:

n       y   y   y           n

n  ----------y-----------     n

n     y             y           n

Example 2:

n   n
n
y             n
/      n
/
/ y    y
n      /

n  n

*/
bool pointInPerpendicularArea(const QPointF& point) const;

protected:
QPointF from;
QPointF to;

qreal xlow;  // minimum x coordinate
qreal xhigh;  // maximum x coordinate
qreal ylow;  // minimum y coordinate
qreal yhigh;  // maximum coordinate

qreal a;  // y span of line segment
qreal xm;  // x median of line segment
qreal b;  // x span of line segment
qreal ym;  // y median of line segment
};