|
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