/* * Copyright 2016 Nathan Howard * * This file is part of OpenGrave * * OpenGrave is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenGrave 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 OpenGrave. If not, see <http://www.gnu.org/licenses/>. */ package com.opengrave.common.pathing; public class Line { boolean strictOrder = false; Point p1, p2; public Line(Point p1, Point p2, boolean strict) { if (strict) { if (p1.x < p2.x) { this.p1 = p2; this.p2 = p1; } else if (p1.x == p2.x && p1.y < p2.y) { this.p1 = p2; this.p2 = p1; } else { this.p1 = p1; this.p2 = p2; } } else { this.p1 = p1; this.p2 = p2; } this.strictOrder = strict; } public Line(Line line) { this.strictOrder = line.strictOrder; this.p1 = new Point(line.p1); this.p2 = new Point(line.p2); } public boolean intersectsWith(Line line) { double s1_x, s1_y, s2_x, s2_y; s1_x = p2.x - p1.x; s1_y = p2.y - p1.y; s2_x = line.p2.x - line.p1.x; s2_y = line.p2.y - line.p1.y; double s, t; s = (-s1_y * (p1.x - line.p1.x) + s1_x * (p1.y - line.p1.y)) / (-s2_x * s1_y + s1_x * s2_y); t = (s2_x * (p1.y - line.p1.y) - s2_y * (p1.x - line.p1.x)) / (-s2_x * s1_y + s1_x * s2_y); if (s >= 0 && s <= 1 && t >= 0 && t <= 1) { return true; } return false; // No collision } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Line)) return false; Line other = (Line) obj; if (p1 == null || p2 == null || other.p1 == null || other.p2 == null) { return false; } if (p1.x == other.p1.x && p2.x == other.p2.x && p1.y == other.p1.y && p2.y == other.p2.y) { return true; } if (p1.x == other.p2.x && p2.x == other.p1.x && p1.y == other.p2.y && p2.y == other.p1.y) { return true; } return false; } public boolean isPointOnLine(Point l, double epsilon) { if (l.x - Math.max(p1.x, p2.x) > epsilon || Math.min(p1.x, p2.x) - l.x > epsilon || l.y - Math.max(p1.y, p2.y) > epsilon || Math.min(p1.y, p2.y) - l.y > epsilon) { return false; } if (Math.abs(p2.x - p1.x) < epsilon) return Math.abs(p1.x - l.x) < epsilon || Math.abs(p2.x - l.x) < epsilon; if (Math.abs(p2.y - p1.y) < epsilon) return Math.abs(p1.y - l.y) < epsilon || Math.abs(p2.y - l.y) < epsilon; double x = p1.x + (l.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y); double y = p1.y + (l.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x); return Math.abs(l.x - x) < epsilon || Math.abs(l.y - y) < epsilon; } public Point getPoint(int i) { if (i == 0) { return p1; } else { return p2; } } public Point getPoint(Point p) { if (p.equals(p1)) { return p2; } return p1; } public Line shortenEnd(double size) { Line line = new Line(new Point(p1), new Point(p2), strictOrder); double dx = line.p2.x - line.p1.x; double dy = line.p2.y - line.p1.y; double len = Math.sqrt(dx * dx + dy * dy); double scale = (len - size) / len; dx *= scale; dy *= scale; line.p2.x = line.p1.x + dx; line.p2.y = line.p1.y + dy; return line; } public Line shortenStart(double size) { Line line = new Line(new Point(p1), new Point(p2), strictOrder); double dx = line.p1.x - line.p2.x; double dy = line.p1.y - line.p2.y; double len = Math.sqrt(dx * dx + dy * dy); double scale = (len - size) / len; dx *= scale; dy *= scale; line.p1.x = line.p2.x + dx; line.p1.y = line.p2.y + dy; return line; } public double getLength() { return p1.getDistance(p2); } public Point getPointAtLengthFromStart(double dist) { Line l = new Line(this); l = l.shortenEnd(getLength() - dist); return l.getPoint(1); } }