ex4-12l.cpp - Example 4-12 Point and Line classes - Line Source file (ex4-12l.cpp)

// File: ex4-12l.cpp � Line class source file

#include <cmath>
#include <cstring>
#include <iostream>
using namespace std;

#include "ex4-12l.h"

Line::Line(const Point& pp1, const Point& pp2) : p1(pp1), p2(pp2)
{
    if (slope() == HUGE_VAL) {
        a = 1.0;
        b = 0.0;
        c = -pp1.get_x();
    } else {
        a = -slope();
        b = 1.0;
        c = slope() * pp1.get_x() - pp1.get_y();
    }
}


// create a Line using equation coefficients

Line::Line(double c1, double c2, double c3)
: a(c1), b(c2), c(c3)
{
    if (c1 != 0.0) p1 = Point(-c3 / c1, 0.0);
    else if (c2 != 0.0) p1 = Point(1.0, -c3 / c2);
    else p1 = Point(0.0, 0.0);
    if (c2 != 0.0) p2 = Point(0.0, -c3 / c2);
    else if (c1 != 0.0) p2 = Point(-c3 / c1, 1.0);
    else p2 = Point(0.0, 0.0);
}


// create a Line through a Point parallel or perpendicular to a Line

Line::Line(const Point& p, const Line& l, const char* Line_type) : p1(p)
{
    double m; // slope
    if (strcmp(Line_type, "parallel") == 0.0) m = l.slope();
    else if (l.slope() == 0.0) m = HUGE_VAL;
    else if (l.slope() == HUGE_VAL) m = 0.0;
    else m = -1. / l.slope();
    if (m == HUGE_VAL) {
        a = 1.0;
        b = 0.0;
        c = -p.get_x();
        p2.set_x(p1.get_x());
        p2.set_y(p1.get_y() + 1.0);
    } else {
        a = m;
        b = -1.0;
        c = -m * p.get_x() + p.get_y();
        p2.set_x(0.0);
        p2.set_y(c);
    }
}


// create a vertical/horizontal Line through a Point

Line::Line(const Point& p, const char* Line_type) : p1(p)
{
    if (strcmp(Line_type, "vertical") == 0) {
        p2.set_x(p1.get_x());
        p2.set_y(p1.get_y() + 1);
        a = 1.0;
        b = 0.0;
        c = -p1.get_x();
    } else {
        p2.set_x(p1.get_x() + 1);
        p2.set_y(p1.get_y());
        a = 0.0;
        b = 1.0;
        c = -p1.get_y();
    }
}

Line::Line(const Line& l, double offset)
: p1(l.p1.get_x(), l.p1.get_y() + offset / fabs(sin(atan(l.slope())))),
p2(l.p2.get_x(), l.p2.get_y() + offset / fabs(sin(atan(l.slope()))))
{
    if (slope() == HUGE_VAL) {
        a = 1.0;
        b = 0.0;
        c = -p1.get_x();
    } else {
        a = -slope();
        b = 1.0;
        c = slope() * p1.get_x() - p1.get_y();
    }
}


// create an angled-length Line

Line::Line(const Point& p, double length, double angle)
: p1(p), p2(p1.get_x() + length*cos(angle), p1.get_y() + length*sin(angle))
{
    if (slope() == HUGE_VAL) {
        a = 1.0;
        b = 0.0;
        c = -p1.get_x();
    } else {
        a = -slope();
        b = 1.0;
        c = slope() * p1.get_x() - p1.get_y();
    }
}

void Line::print(void) const
{
    cout << "Line  eqn: ";
    if (a == 1.0) cout << 'x';
    else if (a == -1.0) cout << "-x";
    else if (a != 0.0) cout << a << 'x';
    if ((a != 0.0) && (b != 0.0)) cout << " + ";
    if (b == 1.0) cout << 'y';
    else if (b == -1.0) cout << "-y";
    else if (b != 0.0) cout << b << 'y';
    if (c != 0.0) cout << " + " << c;
    cout << " = 0";
    cout << "  pts: ";
    p1.print();
    cout << ',';
    p2.print();
    cout << "  slope: " << slope() << endl;
}

double Line::length(void) const
{
    return sqrt(square(p2.get_x() - p1.get_x()) + square((p2.get_y() - p1.get_y())));
}

Point Line::midpoint() const
{
    return Point((p1.get_x() + p2.get_x()) / 2, (p1.get_y() + p2.get_y()) / 2);
}

double Line::slope(void) const
{
    if (!(p2.get_x() - p1.get_x())) return HUGE_VAL;
    else return ((p2.get_y() - p1.get_y()) / (p2.get_x() - p1.get_x()));
}


// returns distance from a Line to a Point

double Line::distance_to_Point(const Point& p) const
{
    return (fabs(a * p.get_x() + b * p.get_y() + c) /
        sqrt(square(a) + square(b)));
}


// returns distance between two parallel Lines

double Line::distance_to_Line(const Line& l) const
{
    if (slope() != l.slope()) return 0.0;
    else return distance_to_Point(l.p1);
}

double Line::x_intercept(void) const
{
    if (a != 0.0) return -c / a;
    else return HUGE_VAL;
}

double Line::y_intercept(void) const
{
    if (b != 0.0) return -c / b;
    else return HUGE_VAL;
}



CIS27: Programming in C++    Instructor: Joe Bentley