Package chunmap.model.elem

Source Code of chunmap.model.elem.Line

/**
* Copyright (c) 2009-2011, chunquedong(YangJiandong)
*
* This file is part of ChunMap project
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
*
* History:
*     2010-05-05  Jed Young  Creation
*/
package chunmap.model.elem;

import chunmap.model.coord.CPoint;
import chunmap.model.coord.Coordinate2D;
import chunmap.util.math.MyDouble;

/**
* 直线
*
* @author chunquedong
*
*/
public class Line {

  private double k;// 斜率
  private double b;// 截距
  private boolean isVertical = false;

  /**
   * 两点式
   */
  public Line(CPoint p1, CPoint p2) {
    double dy = p2.getY() - p1.getY();
    double dx = p2.getX() - p1.getX();

    if (p1.equals(p2))
      throw new IllegalArgumentException(
          "need tow different points to make one line");
    // 竖直线时
    if (dx == 0) {
      k = Double.POSITIVE_INFINITY;
      b = p1.getX();// b变为x轴的截距
      isVertical = true;
    } else {
      k = dy / dx;
      b = p1.getY() - k * p1.getX();
    }

  }

  /**
   * 截距式
   */
  public Line(double k, double b) {
    if (Double.isInfinite(k))
      isVertical = true;
    this.k = k;
    this.b = b;
  }

  /**
   * 点斜式
   */
  public Line(CPoint p, double k) {
    if (Double.isInfinite(k)) {
      k = Double.POSITIVE_INFINITY;
      b = p.getX();
      isVertical = true;
    } else {
      b = p.getY() - k * p.getX();
      this.k = k;
    }
  }

  // ------------------------------------------------------------

  public boolean isVertical() {
    return isVertical;
  }

  public double getY(double x) {
    if (isVertical)
      return Double.NaN;// 竖直

    return k * x + b;
  }

  public double getX(double y) {
    if (isVertical)
      return b;// 竖直
    if (k == 0)
      return Double.NaN;// 水平

    return (y - b) / k;
  }

  /**
   * 斜率
   *
   * @return
   */
  public double getK() {
    if (isVertical)
      return Double.POSITIVE_INFINITY;
    return k;
  }

  /**
   * 截距
   *
   * @return
   */
  public double getB() {
    return b;
  }

  /**
   * 垂直线的斜率
   *
   * @return
   */
  public double getVerticalK() {
    if (isVertical)
      return 0;
    else if (k == 0)
      return Double.POSITIVE_INFINITY;
    return -1d / k;
  }

  // ------------------------------------------------------------

  /**
   * 两线交点,平行返回null
   */
  public CPoint crossPoint(Line l2) {
    double k1 = this.getK();
    double b1 = this.getB();
    double k2 = l2.getK();
    double b2 = l2.getB();

    if (this.isVertical() && l2.isVertical()) {
      return null;
    } else if (this.isVertical()) {
      double y = l2.getY(this.b);
      return new Coordinate2D(this.b, y);
    } else if (l2.isVertical()) {
      double y = this.getY(l2.b);
      return new Coordinate2D(l2.b, y);
    } else if (k1 == k2) {
      return null;// 平行
    } else if (k1 == 0) {
      double x = l2.getX(this.b);
      return new Coordinate2D(x, this.b);
    } else if (k2 == 0) {
      double x = this.getX(l2.b);
      return new Coordinate2D(x, l2.b);
    }

    double x = (b1 - b2) / (k2 - k1);
    double y = this.getY(x);

    return new Coordinate2D(x, y);
  }

  /**
   * 点到直线的距离
   *
   * @param point
   * @return
   */
  public double distance(CPoint point) {
    Line vertical = new Line(point, getVerticalK());
    CPoint crossP = crossPoint(vertical);
    return point.distance2D(crossP);
  }

  /**
   * 点是否在线上,近似值
   *
   * @param p
   * @return
   */
  public boolean onLine(CPoint p) {
    // 线垂直时
    if (isVertical()) {
      return p.getX() == getB();
    }

    double expectedY = getY(p.getX());
    return MyDouble.approximateEquals(expectedY, p.getY());
  }
}
TOP

Related Classes of chunmap.model.elem.Line

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.