/******************************************************************************* * Copyright 2010 Simon Mieth * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.kabeja.processing.helper; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.kabeja.common.DraftEntity; import org.kabeja.common.Layer; import org.kabeja.entities.Arc; import org.kabeja.entities.Line; import org.kabeja.entities.Polyline; import org.kabeja.entities.Vertex; import org.kabeja.entities.util.Utils; import org.kabeja.math.Point3D; import org.kabeja.util.Constants; public class PolylineQueue { private List elements = new ArrayList(); private Point3D startPoint; private Point3D endPoint; private double radius = Constants.POINT_CONNECTION_RADIUS; public PolylineQueue(DraftEntity e, Point3D start, Point3D end, double radius) { this.elements.add(e); this.startPoint = start; this.endPoint = end; this.radius = radius; } public int size() { return this.elements.size(); } /** * connect a entity if possible. * * @param e * @param start * @param end * @return true if the entity could be connected, otherwise false */ public boolean connectEntity(DraftEntity e, Point3D start, Point3D end) { if (Utils.equals(this.startPoint, end, radius)) { this.startPoint = start; this.elements.add(0, e); return true; } else if (Utils.equals(this.endPoint, start, radius)) { this.endPoint = end; this.elements.add(e); return true; } else if (Utils.equals(this.startPoint, start, radius)) { // we need to reverse then the entity this.startPoint = end; reverse(e); this.elements.add(0, e); return true; } else if (Utils.equals(this.endPoint, end, radius)) { // we need to reverse then the entity this.endPoint = start; reverse(e); this.elements.add(e); return true; } return false; } public Point3D getStartPoint() { return this.startPoint; } public Point3D getEndPoint() { return this.endPoint; } public Iterator getElementIterator() { return this.elements.iterator(); } public boolean connect(PolylineQueue queue) { if (Utils.equals(queue.getStartPoint(), this.endPoint, radius)) { // add to the end add(queue); return true; } else if (Utils.equals(queue.getEndPoint(), this.startPoint, radius)) { // insert before insertBefore(queue); return true; } else if (Utils.equals(queue.getStartPoint(), this.startPoint, radius)) { queue.reverse(); insertBefore(queue); return true; } else if (Utils.equals(queue.getEndPoint(), this.endPoint, radius)) { queue.reverse(); add(queue); return true; } return false; } public void createPolyline(Layer layer) { // create the polyline and remove the entity Polyline pline = new Polyline(); Vertex first = new Vertex(this.startPoint); pline.addVertex(first); Iterator i = this.elements.iterator(); while (i.hasNext()) { DraftEntity e = (DraftEntity) i.next(); if (Constants.ENTITY_TYPE_LINE.equals(e.getType())) { Line line = (Line) e; first = new Vertex(line.getEndPoint()); pline.addVertex(first); } else if (Constants.ENTITY_TYPE_POLYLINE.equals(e.getType()) || Constants.ENTITY_TYPE_LWPOLYLINE.equals(e.getType())) { Polyline pl = (Polyline) e; double bulge = pl.getVertex(0).getBulge(); if (bulge != 0.0) { first.setBulge(bulge); } for (int x = 1; x < pl.getVertexCount(); x++) { first = pl.getVertex(x); pline.addVertex(first); } } else if (Constants.ENTITY_TYPE_ARC.equals(e.getType())) { Arc arc = (Arc) e; if (arc.getTotalAngle() > 0.0) { double h = arc.getRadius() * (1 - Math.cos(Math.toRadians(arc.getTotalAngle() / 2))); double chordLength = arc.getChordLength(); if (Utils.equals(arc.getStartPoint(), first.getPoint(), radius)) { // the last point is our start point, // which is always set // we have to calculate the bulge first.setBulge((2 * h) / chordLength); first = new Vertex(arc.getEndPoint()); pline.addVertex(first); } else { // reverse the arc, we change the start/end points // and set the bulge to >0 first.setBulge(-1.0 * ((2 * h) / chordLength)); first = new Vertex(arc.getStartPoint()); pline.addVertex(first); } } } // remove from layer layer.removeEntity(e); } // add the new polyline to the layer pline.setLayer(layer); layer.addEntity(pline); } protected void reverse(DraftEntity entity) { if (Constants.ENTITY_TYPE_LINE.equals(entity.getType())) { Utils.reverseLine((Line) entity); } else if (Constants.ENTITY_TYPE_POLYLINE.equals(entity.getType()) || Constants.ENTITY_TYPE_LWPOLYLINE.equals(entity.getType())) { Utils.reversePolyline((Polyline) entity); } else if (Constants.ENTITY_TYPE_ARC.equals(entity.getType())) { // we cannot reverse an ARC } } protected void reverse() { Point3D p = this.endPoint; this.endPoint = this.startPoint; this.startPoint = p; // reverse the list and all entities int last = this.elements.size() - 1; for (int i = 0; i < (last + 1); i++) { DraftEntity first = (DraftEntity) this.elements.get(i); this.reverse(first); if (i < last) { DraftEntity e = (DraftEntity) this.elements.set(last, first); this.reverse(e); this.elements.set(i, e); last--; } } } /** * Insert the PolylineQueue before the first element. * * @param queue */ public void insertBefore(PolylineQueue queue) { this.startPoint = queue.getStartPoint(); Iterator i = queue.getElementIterator(); int x = 0; while (i.hasNext()) { DraftEntity e = (DraftEntity) i.next(); this.elements.add(x, e); x++; } } /** * Adds the queue to the end. * * @param queue */ public void add(PolylineQueue queue) { this.endPoint = queue.getEndPoint(); Iterator i = queue.getElementIterator(); while (i.hasNext()) { DraftEntity e = (DraftEntity) i.next(); this.elements.add(e); } } }