1 /*
   2  * Copyright (c) 2012, 2014, Oracle and/or its affiliates.
   3  * All rights reserved. Use is subject to license terms.
   4  *
   5  * This file is available and licensed under the following license:
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  *
  11  *  - Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  *  - Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in
  15  *    the documentation and/or other materials provided with the distribution.
  16  *  - Neither the name of Oracle Corporation nor the names of its
  17  *    contributors may be used to endorse or promote products derived
  18  *    from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 package com.oracle.javafx.scenebuilder.kit.editor.panel.content.util;
  33 
  34 import javafx.geometry.Point2D;
  35 
  36 /**
  37  *
  38  *
  39  */
  40 public class LineEquation {
  41 
  42     private final double x0;
  43     private final double y0;
  44     private final double x1;
  45     private final double y1;
  46     private final double distance;
  47 
  48     public LineEquation(double x0, double y0, double x1, double y1) {
  49         assert ! ((x0 == x1) && (y0 == y1));
  50         this.x0 = x0;
  51         this.y0 = y0;
  52         this.x1 = x1;
  53         this.y1 = y1;
  54         final double dx = x1 - x0;
  55         final double dy = y1 - y0;
  56         this.distance = Math.sqrt(dx * dx + dy * dy);
  57     }
  58 
  59     public LineEquation(Point2D p0, Point2D p1) {
  60         this(p0.getX(), p0.getY(), p1.getX(), p1.getY());
  61     }
  62 
  63     public double getDistance() {
  64         return distance;
  65     }
  66 
  67     public boolean isValid() {
  68         return distance > 0.0;
  69     }
  70 
  71     /**
  72      * Returns the (x,y) of a target point given its offset along this line.
  73      *
  74      * @param offset offset of the target point
  75      * @return the coordinates of the target point
  76      */
  77     public Point2D pointAtOffset(double offset) {
  78         /*
  79          *  - offset=0           matches p0
  80          *  - offset=+D          matches p1
  81          *  - offset < 0         matches line points before p0
  82          *  - 0 < offset < D     matches line points between p0 and p1
  83          *  - D < offset         matches line points after p1
  84          *
  85          * where D is the distance between p0 and p1
  86          */
  87         return pointAtP(offsetToP(offset));
  88     }
  89 
  90     /**
  91      * Projects p on this line and returns the offset of the projected point.
  92      *
  93      * @param x target point x
  94      * @param y target point y
  95      * @return the offset of p projection on this line.
  96      */
  97     public double offsetAtPoint(double x, double y) {
  98         /*
  99          * offset is the dot product of:
 100          *      - v1 : vector ((x0, y0), (x, y))
 101          *      - v2 : normalized vector ((x0, y0), (x1, y1))
 102          */
 103 
 104         final double dx1 = x - x0;
 105         final double dy1 = y - y0;
 106         final double dx2 = (x1 - x0) / distance;
 107         final double dy2 = (y1 - y0) / distance;
 108         final double result = dx1 * dx2 + dy1 * dy2;
 109 
 110         return result;
 111     }
 112 
 113     /**
 114      * Returns the (x,y) of a target point given its parametric position.
 115      *
 116      * @param p parametric position of the target point
 117      * @return the coordinates of the target point
 118      */
 119     public Point2D pointAtP(double p) {
 120         final double x, y;
 121 
 122         /*
 123          *  - p=0           matches p0
 124          *  - p=1           matches p1
 125          *  - p < 0         matches line points before p0
 126          *  - 0 < p < 1     matches line points between p0 and p1
 127          *  - 1 < p         matches line points after p1
 128          */
 129 
 130         assert isValid();
 131 
 132         x = x0 + p * (x1 - x0);
 133         y = y0 + p * (y1 - y0);
 134 
 135         return new Point2D(x, y);
 136     }
 137 
 138     /**
 139      * Convert an offset to a parametric position
 140      *
 141      * @param offset an offset along this line
 142      * @return the matching parametric position
 143      */
 144     public double offsetToP(double offset) {
 145         assert isValid();
 146         return offset / distance;
 147     }
 148 
 149     /**
 150      * Convert a parametric position to an offset
 151      *
 152      * @param p a parametric position
 153      * @return the matching offset
 154      */
 155     public double pToOffset(double p) {
 156         assert isValid();
 157         return p * distance;
 158     }
 159 }