/**************************************************************************** ** COPYRIGHT (C): 1997 Cay S. Horstmann. All Rights Reserved. ** PROJECT: Practical OO Development with C++ and Java ** FILE: Segment.java ** PURPOSE: shape class ** VERSION 1.0 ** PROGRAMMERS: Cay Horstmann (CSH) ** RELEASE DATE: 3-15-97 (CSH) ** UPDATE HISTORY: ****************************************************************************/ package practicaloo; import java.awt.Graphics; import java.io.PrintStream; public class Segment { public Segment(Point f, Point t) { _from = f; _to = t; } public void scale(Point center, double s) { _from.scale(center, s); _to.scale(center, s); } public void move(int x, int y) { _from.move(x, y); _to.move(x, y); } public void plot(Graphics g) { g.drawLine(_from.get_x(), _from.get_y(), _to.get_x(), _to.get_y()); } public void print(PrintStream p) { p.print(System.out); } public Point center() { return new Point((int)((_from.get_x() + _to.get_x()) / 2.0), (int)((_from.get_y() + _to.get_y()) / 2.0)); } public boolean intersect(Segment seg) { Point a = _from; Point b = _to; Point c = seg.get_from(); Point d = seg.get_to(); double msx, mtx, msy, mty; // the matrix to invert double rx, ry; // the right hand side of the system msx = a.get_x() - b.get_x(); mtx = -c.get_x() + d.get_x(); msy = a.get_y() - b.get_y(); mty = -c.get_y() + d.get_y(); rx = -b.get_x() + d.get_x(); ry = -b.get_y() + d.get_y(); double det = msx * mty - msy * mtx; if (Approx.equal(det, 0)) return false; // the lines are parallel double s, t; // the solutions of the system s = (mty * rx - mtx * ry) / det; t = (-msy * rx + msx * ry) / det; if (!Approx.lessOrEqual(0, s) || !Approx.lessOrEqual(s, 1) || !Approx.lessOrEqual(0, t) || !Approx.lessOrEqual(t, 1)) return false; Point p = new Point((int)(t * c.get_x() + (1 - t) * d.get_x()), (int)(t * c.get_y() + (1 - t) * d.get_y())); //intersection point return true; } public Point closest(Point p) /* PURPOSE: compute the closest point to a given point on a line segment RECEIVES: p - the point RETURNS: the closest point on the line segment */ { Point a = _from; Point b = _to; Point p1 = (Point)p.clone(); p1.move(-a.get_x(), -a.get_y()); Point r = (Point)b.clone(); r.move(-a.get_x(), -a.get_y()); double blen = r.get_x() * r.get_x() + r.get_y() * r.get_y(); if (Approx.equal(blen, 0)) return a; double proj = (r.get_x() * p1.get_x() + r.get_y() * p1.get_y()) / blen; if (Approx.lessOrEqual(1, proj)) return b; if (Approx.lessOrEqual(proj, 0)) return a; Point ret = (Point)a.clone(); ret.move((int)(proj * r.get_x()), (int)(proj * r.get_y())); return ret; } public double distance(Point p) { return p.distance(closest(p)); } public Point get_from() { return _from; } public Point get_to() { return _to; } private Point _from; private Point _to; }