Package es.iiia.shapegrammar.shape

Source Code of es.iiia.shapegrammar.shape.IntersectionModel

package es.iiia.shapegrammar.shape;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Hashtable;

import es.iiia.shapegrammar.shape.guides.IntersectionTriplet;
import es.iiia.shapegrammar.utils.MathUtils;
import es.iiia.shapegrammar.utils.Vector;

public class IntersectionModel implements Comparable<IntersectionModel> {
  private CarrierModel carrier1;
    private CarrierModel carrier2;
    private Point2D intersection;
    private double angle;
    private Hashtable<Double, ArrayList<IntersectionTriplet>> triplets;

    // constructor

    public IntersectionModel(CarrierModel carrier1, CarrierModel carrier2, boolean includeOuter) {
        this.carrier1 = carrier1;
        this.carrier2 = carrier2;

        // first find an intersetion point
        this.findIntersection();

        // this is done if lines have an intersection point
        if (this.intersection != null) {
          // now check if this is outer or inner intersection
          int found = 0;
          if (!includeOuter) {
            for (LineModel line : carrier1.getLines()) {
              if (line.contains(this.getIntersection())) {
                found += 1;
                break;
              }
            }
            if (found < 1) {
              this.intersection = null;
              return;
            }
            for (LineModel line : carrier2.getLines()) {
              if (line.contains(this.getIntersection())) {
                found += 1;
                break;
              }
            }
            if (found < 2) {
              this.intersection = null;
              return;
            }
             
          }
         
         
            // add this interscetion to carriers it is used in pointA,B calculations
            this.carrier1.addPoint(this.intersection);
            this.carrier2.addPoint(this.intersection);

            // find angles and 2 closest points to intersetion
            this.findAngle();

            //this.intersection.setLabel(SGShape.getName(naming++) + ":" + this.angle + " " + this.intersection);
            //this.intersection.setLabel(this.intersection.toString());

            //this.intersection.setLabel(SGShape.getName(naming++));
            //this.intersection.setVisible(true);
        }
        // point have no intersection
        else {
            // TODO: handle nonintesecting shapes
            // we'll predefine angle to maximal value 360 if lines are paralel
            this.intersection = null;
            return;

//            this.angle = 360;
//            this.intersection = carrier1.getDefinition().getP1();
//            this.pointA = carrier1.getDefinition().getP2();
//            this.pointB = carrier2.getDefinition().getP1();
//
//            this.intersection.setLabel(SGShape.getName(naming++) + " : " + this.pointA + this.pointB);
//
//            // create raio of these two sides (smaller/bigger)
//            this.createRatio();
        }
    }

    /**
     * Gets first found triplet
     */
    public IntersectionTriplet getTriplet() {
        // gets first found pair
        Point2D pointA = null;
        for (int i = 0; i < this.carrier1.getPoints().size(); i++) {
            pointA = this.carrier1.getPoints().get(i);
            if (MathUtils.compare(pointA, this.intersection) != 0)
                break;
        }

        Point2D pointB = null;
        for (int i = 0; i < this.carrier2.getPoints().size(); i++) {
            pointB = this.carrier2.getPoints().get(i);
            if (MathUtils.compare(pointB, this.intersection) != 0 &&
              MathUtils.compare(pointB, pointA) != 0)
                break;
        }

        double ratio = getRatio(pointA, pointB);

        return new IntersectionTriplet(pointA, pointB, ratio);
    }

    /**
     * Finds all triplets with the given ratio
     *
     * @param ratio
     * @return collection of triplets with the given ratio
     */
    public ArrayList<IntersectionTriplet> getTriplets(double ratio) {
        // check if collection exists
        if (this.triplets == null) {
            this.triplets = new Hashtable<Double, ArrayList<IntersectionTriplet>>();

            this.createTriplets(this.carrier1, this.carrier2);
            this.createTriplets(this.carrier2, this.carrier1);
        }

        // return initialized collection
        return this.triplets.get(ratio);
    }
   
    private void createTriplets(CarrierModel car1, CarrierModel car2) {
      // we'll create collection for each ratio
        Point2D pointA, pointB;
        double currentRatio;

        // TODO: maybe the problem with indexes of type double
        for (int i = 0; i < car1.getPoints().size(); i++) {
            pointA = car1.getPoints().get(i);
            // exclude intersecion
            if (MathUtils.compare(pointA, this.intersection) == 0)
                continue;
            for (int j = 0; j < car2.getPoints().size(); j++) {
                // init point
                pointB = car2.getPoints().get(j);

                // avoid same points
                if (MathUtils.compare(pointA, pointB) == 0)
                    continue;

                // exclude intersecion
                if (MathUtils.compare(pointB, this.intersection) == 0)
                    continue;

                // count current ratio
                currentRatio = getRatio(pointA, pointB);

                // check if we have current value in collection
                if (!this.triplets.containsKey(currentRatio)) {
                    this.triplets.put(currentRatio, new ArrayList<IntersectionTriplet>());
                }

                // now add this triplet to this ratio
                this.triplets.get(currentRatio).add(new IntersectionTriplet(pointA, pointB, currentRatio));
            }
        }
    }


    // private methods
    private double getRatio(Point2D pointA, Point2D pointB) {
        return getRatio(this.intersection, pointA, pointB);
    }

    private static double getRatio(Point2D intersection, Point2D pointA, Point2D pointB) {
        try {
            Vector t1 = new Vector(pointA, intersection);
            Vector t2 = new Vector(pointB, intersection);

            double norm1 = Math.sqrt(t1.x * t1.x + t1.y * t1.y);
            double norm2 = Math.sqrt(t2.x * t2.x + t2.y * t2.y);

            return MathUtils.round(norm1 / norm2);
           
//            if (norm1 < norm2) {
//                return MathUtils.round(norm1 / norm2);
//            } else {
//                return MathUtils.round(norm2 / norm1);
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    private void findIntersection() {

        // PROBLEM: ZLE NACHADZA BODY
        double m1, m2, c1, c2, det, x, y;

        // y = mx + c
        // m = (yB-yA / xB - xA) ... slope
        // mX - Y - m*xB + yB = 0

        m1 = carrier1.getDefinition().getSlope();
        m2 = carrier2.getDefinition().getSlope();

        // for finding intersection we'll be using Cramers rule
        // first check if lines are paralel [determinant of coeficients == 0]

        //System.out.println("DET: " + MathUtils.getDeterminant(m1, -1, m2, -1));
        //System.out.println("DET: " + (det = MathUtils.getDeterminant(m1, -1, m2, -1)));

        // check if one of the carrier is non-function (e.g. x=4)
        if (m1 == Double.MAX_VALUE || m2 == Double.MAX_VALUE) {
//                    System.out.println("NON FUNCTION");
            if (m1 != m2) {
                if (m1 == Double.MAX_VALUE) {
                    x = carrier1.getDefinition().getP1().getX();
                    y = m2 * x + carrier2.getDefinition().getC();

                    this.intersection = new Point2D.Double(x, y);
                } else {
                    x = carrier2.getDefinition().getP1().getX();
                    y = m1 * x + carrier1.getDefinition().getC();

                    this.intersection = new Point2D.Double(x, y);
                }
            }
            // carriers cannot be are parallel
        } else if (MathUtils.round((det = MathUtils.getDeterminant(m1, -1, m2, -1))) != 0) {
            // now we know there exists intersection so we'll count values for X and Y.
            c1 = -carrier1.getDefinition().getC();
            c2 = -carrier2.getDefinition().getC();

            x = MathUtils.getDeterminant(c1, -1, c2, -1) / det;
            y = MathUtils.getDeterminant(m1, c1, m2, c2) / det;

            this.intersection = new Point2D.Double(x, y);
        }

//        System.out.println("INTERSECTION: " + new Point2D(x, y).toString());
    }

    @SuppressWarnings("restriction")
  private void findAngle() {
        // carriers can be parallel
        if (this.intersection == null) {
            this.angle = 0;
        }
        // otherwise count parameters
        else {
            // first order points
            try {
                // create vectors
                Vector t1 = new Vector(
                        carrier1.getDefinition().getP1(),
                        carrier1.getDefinition().getP2());

                Vector t2 = new Vector(
                        carrier2.getDefinition().getP1(),
                        carrier2.getDefinition().getP2());

                double dot = t1.x * t2.x + t1.y * t2.y;
                double norm1 = Math.sqrt(t1.x * t1.x + t1.y * t1.y);
                double norm2 = Math.sqrt(t2.x * t2.x + t2.y * t2.y);

                this.angle = MathUtils.round(Math.acos(dot / (norm1 * norm2)) * (180 / Math.PI));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

//    private Point2D findClosestPoint(CarrierModel carrier) {
//        // finds closest points
//
//        // if both points are on the left or both on the right of the intersection point
//        // we'll keep the angle. Otherwise it's 180
//        Point2D intersection;
//
//        for (int i = 0; i < carrier.getIntersections().size(); i++) {
//            intersection = carrier.getIntersections().get(i);
//
//            // else try to find point to the right
//            if (intersection.getX() > this.intersection.getX() ||
//                    (intersection.getX() == this.intersection.getX() && intersection.getY() > this.intersection.getY())) {
//                return intersection;
//            }
//
//            // we've reached the last element
//            if (i == carrier.getIntersections().size() - 1) {
//                // flip angle, because point is in oposite direction as expected
//                this.angle = 180 - this.angle;
//
//                if (intersection.getX() == this.intersection.getX() &&
//                        intersection.getY() == this.intersection.getY()) {
//                    // don't return the same point
//                    return carrier.getIntersections().get(i - 1);
//                } else {
//                    // get the point to the left
//                    return carrier.getIntersections().get(i);
//                }
//            }
//        }
//        // this should never happen
//        return null;
//    }

    // Gs/Ss

    public Point2D getIntersection() {
        return intersection;
    }

    public double getAngle() {
        return angle;
    }

    // temp
    public static int naming;

    public int compareTo(IntersectionModel sgIntersection) {
        if (this.angle < sgIntersection.angle) {
            return -1;
        } else if (this.angle > sgIntersection.angle) {
            return 1;
        }
        return 0;

    }
}
TOP

Related Classes of es.iiia.shapegrammar.shape.IntersectionModel

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.