/* * Copyright (c) 2003, PostgreSQL Global Development Group * See the LICENSE file in the project root for more information. */ package org.postgresql.geometric; import org.postgresql.util.GT; import org.postgresql.util.PGobject; import org.postgresql.util.PGtokenizer; import org.postgresql.util.PSQLException; import org.postgresql.util.PSQLState; import java.io.Serializable; import java.sql.SQLException; /** * This implements a line represented by the linear equation Ax + By + C = 0 **/ public class PGline extends PGobject implements Serializable, Cloneable { /** * Coefficient of x */ public double a; /** * Coefficient of y */ public double b; /** * Constant */ public double c; /** * @param a coefficient of x * @param b coefficient of y * @param c constant */ public PGline(double a, double b, double c) { this(); this.a = a; this.b = b; this.c = c; } /** * @param x1 coordinate for first point on the line * @param y1 coordinate for first point on the line * @param x2 coordinate for second point on the line * @param y2 coordinate for second point on the line */ public PGline(double x1, double y1, double x2, double y2) { this(); if (x1 == x2) { a = -1; b = 0; } else { a = (y2 - y1) / (x2 - x1); b = -1; } c = y1 - a * x1; } /** * @param p1 first point on the line * @param p2 second point on the line */ public PGline(PGpoint p1, PGpoint p2) { this(p1.x, p1.y, p2.x, p2.y); } /** * @param lseg Line segment which calls on this line. */ public PGline(PGlseg lseg) { this(lseg.point[0], lseg.point[1]); } /** * @param s definition of the line in PostgreSQL's syntax. * @throws SQLException on conversion failure */ public PGline(String s) throws SQLException { this(); setValue(s); } /** * required by the driver */ public PGline() { setType("line"); } /** * @param s Definition of the line in PostgreSQL's syntax * @throws SQLException on conversion failure */ @Override public void setValue(String s) throws SQLException { if (s.trim().startsWith("{")) { PGtokenizer t = new PGtokenizer(PGtokenizer.removeCurlyBrace(s), ','); if (t.getSize() != 3) { throw new PSQLException(GT.tr("Conversion to type {0} failed: {1}.", type, s), PSQLState.DATA_TYPE_MISMATCH); } a = Double.parseDouble(t.getToken(0)); b = Double.parseDouble(t.getToken(1)); c = Double.parseDouble(t.getToken(2)); } else if (s.trim().startsWith("[")) { PGtokenizer t = new PGtokenizer(PGtokenizer.removeBox(s), ','); if (t.getSize() != 2) { throw new PSQLException(GT.tr("Conversion to type {0} failed: {1}.", type, s), PSQLState.DATA_TYPE_MISMATCH); } PGpoint point1 = new PGpoint(t.getToken(0)); PGpoint point2 = new PGpoint(t.getToken(1)); a = point2.x - point1.x; b = point2.y - point1.y; c = point1.y; } } /** * @param obj Object to compare with * @return true if the two lines are identical */ public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } if (!super.equals(obj)) { return false; } PGline pGline = (PGline) obj; return Double.compare(pGline.a, a) == 0 && Double.compare(pGline.b, b) == 0 && Double.compare(pGline.c, c) == 0; } public int hashCode() { int result = super.hashCode(); long temp; temp = Double.doubleToLongBits(a); result = 31 * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(b); result = 31 * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(c); result = 31 * result + (int) (temp ^ (temp >>> 32)); return result; } /** * @return the PGline in the syntax expected by org.postgresql */ public String getValue() { return "{" + a + "," + b + "," + c + "}"; } @Override public Object clone() throws CloneNotSupportedException { // squid:S2157 "Cloneables" should implement "clone return super.clone(); } }