Search in sources :

Example 1 with AddArrayCommand

use of org.concord.energy3d.undo.AddArrayCommand in project energy3d by concord-consortium.

the class Foundation method addCircularHeliostatArrays.

public int addCircularHeliostatArrays(final HeliostatCircularFieldLayout layout) {
    EnergyPanel.getInstance().updateRadiationHeatMap();
    final Class<?>[] clazz = new Class[] { Mirror.class };
    final AddArrayCommand command = new AddArrayCommand(removeChildrenOfClass(clazz), this, clazz);
    final double a = 0.5 * Math.min(getAbsPoint(0).distance(getAbsPoint(2)), getAbsPoint(0).distance(getAbsPoint(1)));
    final Vector3 center = getAbsCenter();
    final double w = (layout.getApertureWidth() + layout.getAzimuthalSpacing()) / Scene.getInstance().getAnnotationScale();
    final double h = (layout.getApertureHeight() + layout.getRadialSpacing()) / Scene.getInstance().getAnnotationScale();
    final double rows = a / h;
    final int nrows = (int) (rows > 2 ? rows - 2 : rows);
    final double roadHalfWidth = 0.5 * layout.getAxisRoadWidth() / Scene.getInstance().getAnnotationScale();
    switch(layout.getType()) {
        case EQUAL_AZIMUTHAL_SPACING:
            for (int r = nrows - 1; r >= 0; r--) {
                double b = a * (1.0 - r / rows);
                b += b * b * layout.getRadialSpacingIncrement();
                if (b > a) {
                    break;
                }
                final double roadAngle = Math.toDegrees(Math.atan(roadHalfWidth / b));
                final int n = (int) (2 * Math.PI * b / w);
                for (int i = 0; i < n; i++) {
                    final double theta = i * 2.0 * Math.PI / n;
                    final double az = Math.toDegrees(theta);
                    if (az >= layout.getStartAngle() && az < layout.getEndAngle()) {
                        if (!Util.isZero(roadAngle) && nearAxes(az, roadAngle)) {
                            continue;
                        }
                        final Vector3 p = new Vector3(center.getX() + b * Math.cos(theta), center.getY() + b * Math.sin(theta), 0);
                        addMirror(p, layout.getBaseHeight(), layout.getApertureWidth(), layout.getApertureHeight(), az);
                    }
                }
            }
            break;
        case // http://www.powerfromthesun.net/Book/chapter10/chapter10.html#10.1.3%20%20%20Field%20Layout
        RADIAL_STAGGER:
            final double rmin = a * (1.0 - (nrows - 5) / rows);
            final int n = (int) (rmin / layout.getApertureWidth() * Scene.getInstance().getAnnotationScale());
            for (int i = 0; i < n; i++) {
                double theta = i * 2.0 * Math.PI / n;
                double az = Math.toDegrees(theta);
                if (az >= layout.getStartAngle() && az < layout.getEndAngle()) {
                    for (int j = 0; j < nrows; j++) {
                        final double r = a * (1.0 - j / rows);
                        final Vector3 p = new Vector3(center.getX() + r * Math.cos(theta), center.getY() + r * Math.sin(theta), 0);
                        addMirror(p, layout.getBaseHeight(), layout.getApertureWidth(), layout.getApertureHeight(), az);
                    }
                }
                theta = (i + 0.5) * 2.0 * Math.PI / n;
                az = Math.toDegrees(theta);
                if (az >= layout.getStartAngle() && az < layout.getEndAngle()) {
                    for (int j = 0; j < nrows; j++) {
                        final double r = a * (1.0 - j / rows) - 0.5 * h;
                        final Vector3 p = new Vector3(center.getX() + r * Math.cos(theta), center.getY() + r * Math.sin(theta), 0);
                        addMirror(p, layout.getBaseHeight(), layout.getApertureWidth(), layout.getApertureHeight(), az);
                    }
                }
            }
            break;
    }
    SceneManager.getInstance().getUndoManager().addEdit(command);
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            EnergyPanel.getInstance().updateProperties();
        }
    });
    return countParts(Mirror.class);
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) AddArrayCommand(org.concord.energy3d.undo.AddArrayCommand) CullHint(com.ardor3d.scenegraph.hint.CullHint)

Example 2 with AddArrayCommand

use of org.concord.energy3d.undo.AddArrayCommand in project energy3d by concord-consortium.

the class Foundation method addSolarRackArrays.

public void addSolarRackArrays(final SolarPanel panel, double tiltAngle, final double baseHeight, final int panelRowsPerRack, final double rowSpacing, final int rowAxis, final double poleDistanceX, final double poleDistanceY) {
    EnergyPanel.getInstance().updateRadiationHeatMap();
    final Class<?>[] clazz = new Class[] { Rack.class, SolarPanel.class };
    final AddArrayCommand command = new AddArrayCommand(removeChildrenOfClass(clazz), this, clazz);
    final double az = Math.toRadians(getAzimuth());
    if (!Util.isZero(az)) {
        rotate(az, null, false);
    }
    if (Util.isZero(tiltAngle - 90)) {
        tiltAngle = 89.999;
    } else if (Util.isZero(tiltAngle + 90)) {
        tiltAngle = -89.999;
    }
    final Vector3 p0 = getAbsPoint(0);
    final double a = p0.distance(getAbsPoint(2));
    final double b = p0.distance(getAbsPoint(1));
    double x0 = Math.min(Math.min(p0.getX(), getAbsPoint(1).getX()), getAbsPoint(2).getX());
    double y0 = Math.min(Math.min(p0.getY(), getAbsPoint(1).getY()), getAbsPoint(2).getY());
    final double x1 = Math.max(Math.max(p0.getX(), getAbsPoint(1).getX()), getAbsPoint(2).getX());
    final double y1 = Math.max(Math.max(p0.getY(), getAbsPoint(1).getY()), getAbsPoint(2).getY());
    final double panelHeight = panel.isRotated() ? panel.getPanelWidth() : panel.getPanelHeight();
    final double rackHeight = panelHeight * panelRowsPerRack;
    final double halfHeight = 0.5 * rackHeight / Scene.getInstance().getAnnotationScale();
    final double h = rowSpacing / Scene.getInstance().getAnnotationScale();
    double rackWidth, rows;
    final Vector3 center = new Vector3();
    final Vector3 v1 = new Vector3();
    final Vector3 v2 = new Vector3();
    final List<Point2D.Double> intersections = new ArrayList<Point2D.Double>();
    double[] bounds = null;
    switch(rowAxis) {
        case 1:
            center.setX((x0 + x1) * 0.5);
            rackWidth = a * Scene.getInstance().getAnnotationScale() - panelHeight;
            rows = (int) Math.floor(b / h);
            double margin = (b - rows * h) * 0.5;
            for (int r = 0; r < rows; r++) {
                if (foundationPolygon != null && foundationPolygon.isVisible()) {
                    if (bounds == null) {
                        bounds = foundationPolygon.getBounds();
                    }
                    x0 = Math.max(x0, bounds[0]);
                    y0 = Math.max(y0, bounds[2]);
                    center.setY(y0 + halfHeight + h * r);
                    v1.set(x0, center.getY(), 0);
                    v2.set(x1, center.getY(), 0);
                    intersections.clear();
                    intersections.addAll(foundationPolygon.getIntersectingPoints(v1, v2));
                    final int n = intersections.size();
                    if (n >= 2) {
                        for (int i = 0; i < n; i += 2) {
                            final Point2D.Double pd1 = intersections.get(i);
                            final Point2D.Double pd2 = intersections.get(i + 1);
                            rackWidth = pd2.distance(pd1) * Scene.getInstance().getAnnotationScale();
                            final Rack rack = addRack(panel, tiltAngle, baseHeight, rowAxis, poleDistanceX, poleDistanceY, new Vector3(0.5 * (pd1.getX() + pd2.getX()), 0.5 * (pd1.getY() + pd2.getY()), 0), rackWidth, rackHeight, false);
                            rack.draw();
                        }
                    }
                } else {
                    center.setY(y0 + margin + h * (r + 0.5));
                    addRack(panel, tiltAngle, baseHeight, rowAxis, poleDistanceX, poleDistanceY, center, rackWidth, rackHeight, false).draw();
                }
            }
            break;
        case 0:
            center.setY((y0 + y1) * 0.5);
            rackWidth = b * Scene.getInstance().getAnnotationScale() - panelHeight;
            rows = (int) Math.floor(a / h);
            margin = (a - rows * h) * 0.5;
            for (int r = 0; r < rows; r++) {
                if (foundationPolygon != null && foundationPolygon.isVisible()) {
                    if (bounds == null) {
                        bounds = foundationPolygon.getBounds();
                    }
                    x0 = Math.max(x0, bounds[0]);
                    y0 = Math.max(y0, bounds[2]);
                    center.setX(x0 + halfHeight + h * r);
                    v1.set(center.getX(), y0, 0);
                    v2.set(center.getX(), y1, 0);
                    intersections.clear();
                    intersections.addAll(foundationPolygon.getIntersectingPoints(v1, v2));
                    final int n = intersections.size();
                    if (n >= 2) {
                        for (int i = 0; i < n; i += 2) {
                            final Point2D.Double pd1 = intersections.get(i);
                            final Point2D.Double pd2 = intersections.get(i + 1);
                            rackWidth = pd2.distance(pd1) * Scene.getInstance().getAnnotationScale();
                            final Rack rack = addRack(panel, tiltAngle, baseHeight, rowAxis, poleDistanceX, poleDistanceY, new Vector3(0.5 * (pd1.getX() + pd2.getX()), 0.5 * (pd1.getY() + pd2.getY()), 0), rackWidth, rackHeight, true);
                            rack.draw();
                        }
                    }
                } else {
                    center.setX(x0 + margin + h * (r + 0.5));
                    addRack(panel, tiltAngle, baseHeight, rowAxis, poleDistanceX, poleDistanceY, center, rackWidth, rackHeight, true).draw();
                }
            }
            break;
    }
    if (!Util.isZero(az)) {
        rotate(-az, null, false);
    }
    Scene.getInstance().redrawFoundationNow(this);
    SceneManager.getInstance().getUndoManager().addEdit(command);
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            EnergyPanel.getInstance().updateProperties();
        }
    });
}
Also used : ArrayList(java.util.ArrayList) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) CullHint(com.ardor3d.scenegraph.hint.CullHint) Point2D(java.awt.geom.Point2D) AddArrayCommand(org.concord.energy3d.undo.AddArrayCommand)

Example 3 with AddArrayCommand

use of org.concord.energy3d.undo.AddArrayCommand in project energy3d by concord-consortium.

the class Foundation method addSpiralHeliostatArrays.

public int addSpiralHeliostatArrays(final HeliostatSpiralFieldLayout layout) {
    EnergyPanel.getInstance().updateRadiationHeatMap();
    final Class<?>[] clazz = new Class[] { Mirror.class };
    final AddArrayCommand command = new AddArrayCommand(removeChildrenOfClass(clazz), this, clazz);
    final double a = 0.5 * Math.min(getAbsPoint(0).distance(getAbsPoint(2)), getAbsPoint(0).distance(getAbsPoint(1)));
    final double b = layout.getScalingFactor() * Math.max(layout.getApertureWidth(), layout.getApertureHeight()) / Scene.getInstance().getAnnotationScale();
    final Vector3 center = getAbsCenter();
    final double theta0 = layout.getStartTurn() * 2 * Math.PI;
    final double roadHalfWidth = 0.5 * layout.getAxisRoadWidth() / Scene.getInstance().getAnnotationScale();
    switch(layout.getType()) {
        case FERMAT_SPIRAL:
            for (int i = 1; i < 10000; i++) {
                double r = b * Math.sqrt(i);
                r += r * r * layout.getRadialSpacingIncrement();
                if (r > a) {
                    break;
                }
                final double theta = i * GOLDEN_ANGLE;
                if (theta < theta0) {
                    continue;
                }
                final double roadAngle = Math.toDegrees(Math.atan(roadHalfWidth / r));
                double az = Math.toDegrees(theta);
                az = az % 360;
                if (az >= layout.getStartAngle() && az < layout.getEndAngle()) {
                    if (!Util.isZero(roadAngle) && nearAxes(az, roadAngle)) {
                        continue;
                    }
                    final Vector3 p = new Vector3(center.getX() + r * Math.cos(theta), center.getY() + r * Math.sin(theta), 0);
                    addMirror(p, layout.getBaseHeight(), layout.getApertureWidth(), layout.getApertureHeight(), az);
                }
            }
            break;
    }
    SceneManager.getInstance().getUndoManager().addEdit(command);
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            EnergyPanel.getInstance().updateProperties();
        }
    });
    return countParts(Mirror.class);
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) AddArrayCommand(org.concord.energy3d.undo.AddArrayCommand) CullHint(com.ardor3d.scenegraph.hint.CullHint)

Example 4 with AddArrayCommand

use of org.concord.energy3d.undo.AddArrayCommand in project energy3d by concord-consortium.

the class Foundation method addRectangularHeliostatArrays.

public int addRectangularHeliostatArrays(final HeliostatRectangularFieldLayout layout) {
    EnergyPanel.getInstance().updateRadiationHeatMap();
    final Class<?>[] clazz = new Class[] { Mirror.class };
    final AddArrayCommand command = new AddArrayCommand(removeChildrenOfClass(clazz), this, clazz);
    final double az = Math.toRadians(getAzimuth());
    if (!Util.isZero(az)) {
        rotate(az, null, false);
    }
    final Vector3 p0 = getAbsPoint(0);
    final double a = p0.distance(getAbsPoint(2));
    final double b = p0.distance(getAbsPoint(1));
    final double x0 = Math.min(Math.min(p0.getX(), getAbsPoint(1).getX()), getAbsPoint(2).getX());
    final double y0 = Math.min(Math.min(p0.getY(), getAbsPoint(1).getY()), getAbsPoint(2).getY());
    final double w = (layout.getApertureWidth() + layout.getColumnSpacing()) / Scene.getInstance().getAnnotationScale();
    final double h = (layout.getApertureHeight() + layout.getRowSpacing()) / Scene.getInstance().getAnnotationScale();
    switch(layout.getRowAxis()) {
        case // north-south axis
        0:
            int rows = (int) Math.floor(b / w);
            int cols = (int) Math.floor(a / h);
            for (int c = 0; c < cols; c++) {
                for (int r = 0; r < rows; r++) {
                    final Vector3 p = new Vector3(x0 + h * (c + 0.5), y0 + w * (r + 0.5), 0);
                    addMirror(p, layout.getBaseHeight(), layout.getApertureWidth(), layout.getApertureHeight(), az);
                }
            }
            break;
        case // east-west axis
        1:
            rows = (int) Math.floor(a / w);
            cols = (int) Math.floor(b / h);
            for (int c = 0; c < cols; c++) {
                for (int r = 0; r < rows; r++) {
                    final Vector3 p = new Vector3(x0 + w * (r + 0.5), y0 + h * (c + 0.5), 0);
                    addMirror(p, layout.getBaseHeight(), layout.getApertureWidth(), layout.getApertureHeight(), az);
                }
            }
            break;
    }
    if (!Util.isZero(az)) {
        rotate(-az, null, false);
    }
    Scene.getInstance().redrawFoundationNow(this);
    SceneManager.getInstance().getUndoManager().addEdit(command);
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            EnergyPanel.getInstance().updateProperties();
        }
    });
    return countParts(Mirror.class);
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) AddArrayCommand(org.concord.energy3d.undo.AddArrayCommand) CullHint(com.ardor3d.scenegraph.hint.CullHint)

Example 5 with AddArrayCommand

use of org.concord.energy3d.undo.AddArrayCommand in project energy3d by concord-consortium.

the class Foundation method addSolarPanelArrays.

public void addSolarPanelArrays(final SolarPanel solarPanel, final double rowSpacing, final double colSpacing, final int rowAxis) {
    EnergyPanel.getInstance().updateRadiationHeatMap();
    final Class<?>[] clazz = new Class[] { Rack.class, SolarPanel.class };
    final AddArrayCommand command = new AddArrayCommand(removeChildrenOfClass(clazz), this, clazz);
    final double az = Math.toRadians(getAzimuth());
    if (!Util.isZero(az)) {
        rotate(az, null, false);
    }
    final Vector3 p0 = getAbsPoint(0);
    final double a = p0.distance(getAbsPoint(2));
    final double b = p0.distance(getAbsPoint(1));
    final double x0 = Math.min(Math.min(p0.getX(), getAbsPoint(1).getX()), getAbsPoint(2).getX());
    final double y0 = Math.min(Math.min(p0.getY(), getAbsPoint(1).getY()), getAbsPoint(2).getY());
    final double w = colSpacing / Scene.getInstance().getAnnotationScale();
    final double h = rowSpacing / Scene.getInstance().getAnnotationScale();
    Path2D.Double path = null;
    if (foundationPolygon != null && foundationPolygon.isVisible()) {
        path = new Path2D.Double();
        final int n = foundationPolygon.points.size();
        Vector3 v = foundationPolygon.getAbsPoint(0);
        path.moveTo(v.getX(), v.getY());
        for (int i = 1; i < n / 2; i++) {
            // use only the first half of the vertices from the polygon
            v = foundationPolygon.getAbsPoint(i);
            path.lineTo(v.getX(), v.getY());
        }
        path.closePath();
    }
    switch(rowAxis) {
        case 0:
            int rows = (int) Math.floor(b / w);
            int cols = (int) Math.floor(a / h);
            double marginx = (a - cols * h) * 0.5;
            double marginy = (b - rows * w) * 0.5;
            for (int c = 0; c < cols; c++) {
                for (int r = 0; r < rows; r++) {
                    final double x = x0 + marginx + h * (c + 0.5);
                    final double y = y0 + marginy + w * (r + 0.5);
                    if (path != null && !path.contains(x, y)) {
                        continue;
                    }
                    final SolarPanel sp = (SolarPanel) solarPanel.copy(false);
                    sp.setContainer(this);
                    final Vector3 v = sp.toRelative(new Vector3(x, y, 0));
                    sp.points.get(0).setX(v.getX());
                    sp.points.get(0).setY(v.getY());
                    sp.points.get(0).setZ(height);
                    Scene.getInstance().add(sp, false);
                    sp.complete();
                    sp.setRelativeAzimuth(90);
                    sp.draw();
                }
            }
            break;
        case 1:
            rows = (int) Math.floor(a / w);
            cols = (int) Math.floor(b / h);
            marginx = (a - rows * w) * 0.5;
            marginy = (b - cols * h) * 0.5;
            for (int c = 0; c < cols; c++) {
                for (int r = 0; r < rows; r++) {
                    final double x = x0 + marginx + w * (r + 0.5);
                    final double y = y0 + marginy + h * (c + 0.5);
                    if (path != null && !path.contains(x, y)) {
                        continue;
                    }
                    final SolarPanel sp = (SolarPanel) solarPanel.copy(false);
                    sp.setContainer(this);
                    final Vector3 v = sp.toRelative(new Vector3(x, y, 0));
                    sp.points.get(0).setX(v.getX());
                    sp.points.get(0).setY(v.getY());
                    sp.points.get(0).setZ(height);
                    Scene.getInstance().add(sp, false);
                    sp.complete();
                    sp.draw();
                }
            }
            break;
    }
    if (!Util.isZero(az)) {
        rotate(-az, null, false);
    }
    Scene.getInstance().redrawFoundationNow(this);
    SceneManager.getInstance().getUndoManager().addEdit(command);
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            EnergyPanel.getInstance().updateProperties();
        }
    });
}
Also used : Path2D(java.awt.geom.Path2D) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) AddArrayCommand(org.concord.energy3d.undo.AddArrayCommand) CullHint(com.ardor3d.scenegraph.hint.CullHint)

Aggregations

Vector3 (com.ardor3d.math.Vector3)6 ReadOnlyVector3 (com.ardor3d.math.type.ReadOnlyVector3)6 CullHint (com.ardor3d.scenegraph.hint.CullHint)6 AddArrayCommand (org.concord.energy3d.undo.AddArrayCommand)6 Path2D (java.awt.geom.Path2D)1 Point2D (java.awt.geom.Point2D)1 ArrayList (java.util.ArrayList)1