Search in sources :

Example 1 with Point

use of org.poly2tri.geometry.primitives.Point in project energy3d by concord-consortium.

the class Wall method applyXYTransform.

public void applyXYTransform(final List<Vector3> hole) {
    if (toXY == null) {
        computeNormalAndXYTransform();
    }
    for (final Vector3 p : hole) {
        final Point point = new ArdorVector3Point(p);
        toXY.transform(point);
        p.set(point.getX(), point.getY(), point.getZ());
    }
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) PolygonPoint(org.poly2tri.geometry.polygon.PolygonPoint) ArdorVector3Point(org.poly2tri.triangulation.point.ardor3d.ArdorVector3Point) TPoint(org.poly2tri.triangulation.point.TPoint) Point(org.poly2tri.geometry.primitives.Point) ArdorVector3Point(org.poly2tri.triangulation.point.ardor3d.ArdorVector3Point)

Example 2 with Point

use of org.poly2tri.geometry.primitives.Point in project energy3d by concord-consortium.

the class Wall method getThicknessNormal.

public Vector3 getThicknessNormal() {
    if (thicknessNormal != null) {
        return thicknessNormal;
    }
    computeNormalAndXYTransform();
    final Vector3 n = normal.clone();
    final Snap neighbor;
    final int whichNeighbor;
    if (editPointIndex == 0 || editPointIndex == 1) {
        /*
			 * if edit point has snapped to a new wall then use the angle with new wall to determine inside direction of this wall otherwise use the angle with the other wall attached to none moving corner of the this wall
			 */
        if (neighbors[0] == null) {
            whichNeighbor = 1;
        } else {
            whichNeighbor = 0;
        }
    } else {
        if (neighbors[1] == null) {
            whichNeighbor = 0;
        } else {
            whichNeighbor = 1;
        }
    }
    neighbor = neighbors[whichNeighbor];
    if (neighbor != null && neighbor.getNeighborOf(this).getPoints().size() >= 4) {
        final HousePart other = neighbor.getNeighborOf(this);
        final int otherPointIndex = neighbor.getSnapPointIndexOfNeighborOf(this);
        final Vector3 otherWallDir = other.getAbsPoint(otherPointIndex == 0 ? 2 : 0).subtract(other.getAbsPoint(otherPointIndex), null).normalizeLocal();
        if (n.dot(otherWallDir) < 0) {
            n.negateLocal();
        }
    } else {
        final ReadOnlyVector3 camera = SceneManager.getInstance().getCamera().getDirection();
        if (camera.dot(n) < 0) {
            n.negateLocal();
        }
    }
    n.multiplyLocal(wallThickness);
    thicknessNormal = n;
    return thicknessNormal;
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) CullHint(com.ardor3d.scenegraph.hint.CullHint) PolygonPoint(org.poly2tri.geometry.polygon.PolygonPoint) ArdorVector3Point(org.poly2tri.triangulation.point.ardor3d.ArdorVector3Point) PickingHint(com.ardor3d.scenegraph.hint.PickingHint) TPoint(org.poly2tri.triangulation.point.TPoint) Point(org.poly2tri.geometry.primitives.Point)

Example 3 with Point

use of org.poly2tri.geometry.primitives.Point in project energy3d by concord-consortium.

the class SolarRadiation method computeOnImportedMesh.

private void computeOnImportedMesh(final int minute, final ReadOnlyVector3 directionTowardSun, final Foundation foundation, final Mesh mesh) {
    final UserData userData = (UserData) mesh.getUserData();
    if (!userData.isReachable()) {
        return;
    }
    final ReadOnlyVector3 normal = userData.getRotatedNormal() == null ? userData.getNormal() : userData.getRotatedNormal();
    final MeshDataStore data = onMesh.get(mesh);
    final int timeStep = Scene.getInstance().getTimeStep();
    final int iMinute = minute / timeStep;
    final double dot = normal.dot(directionTowardSun);
    final double directRadiation = dot > 0 ? calculateDirectRadiation(directionTowardSun, normal) : 0;
    final double indirectRadiation = calculateDiffuseAndReflectedRadiation(directionTowardSun, normal);
    final double solarStep = Scene.getInstance().getSolarStep();
    final double annotationScale = Scene.getInstance().getAnnotationScale();
    final double scaleFactor = annotationScale * annotationScale / 60 * timeStep;
    final float absorption = 1 - foundation.getAlbedo();
    for (int col = 0; col < data.cols; col++) {
        // final double w = col == data.cols - 1 ? data.p2.distance(data.u.multiply(col * solarStep, null).addLocal(data.p0)) : solarStep;
        final double w = col == data.cols - 1 ? data.p2.distance(data.p0) - col * solarStep : solarStep;
        final ReadOnlyVector3 pU = data.u.multiply(col * solarStep + 0.5 * w, null).addLocal(data.p0);
        for (int row = 0; row < data.rows; row++) {
            if (EnergyPanel.getInstance().isCancelled()) {
                throw new CancellationException();
            }
            if (data.dailySolarIntensity[row][col] == -1) {
                continue;
            }
            final double h = row == data.rows - 1 ? data.p1.distance(data.p0) - row * solarStep : solarStep;
            // cannot do offset as in computeOnMesh
            final ReadOnlyVector3 p = data.v.multiply(row * solarStep + 0.5 * h, null).addLocal(pU);
            final Ray3 pickRay = new Ray3(p, directionTowardSun);
            final PickResults pickResults = new PrimitivePickResults();
            // assuming that indirect (ambient or diffuse) radiation can always reach a grid point
            double radiation = indirectRadiation;
            final double scaledArea = w * h * scaleFactor;
            if (dot > 0) {
                for (final Spatial spatial : collidables) {
                    if (EnergyPanel.getInstance().isCancelled()) {
                        throw new CancellationException();
                    }
                    if (spatial != mesh) {
                        PickingUtil.findPick(spatial, pickRay, pickResults, false);
                        if (pickResults.getNumber() != 0) {
                            break;
                        }
                    }
                }
                if (pickResults.getNumber() == 0) {
                    radiation += directRadiation;
                }
            }
            data.dailySolarIntensity[row][col] += Scene.getInstance().getOnlyAbsorptionInSolarMap() ? absorption * radiation : radiation;
            if (data.solarPotential != null) {
                data.solarPotential[iMinute] += radiation * scaledArea;
            }
            // sum all the solar energy up over all meshes and store in the foundation's solar potential array
            foundation.getSolarPotential()[iMinute] += radiation * scaledArea;
        }
    }
}
Also used : PrimitivePickResults(com.ardor3d.intersection.PrimitivePickResults) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) UserData(org.concord.energy3d.model.UserData) CancellationException(java.util.concurrent.CancellationException) Spatial(com.ardor3d.scenegraph.Spatial) PrimitivePickResults(com.ardor3d.intersection.PrimitivePickResults) PickResults(com.ardor3d.intersection.PickResults) CullHint(com.ardor3d.scenegraph.hint.CullHint) TPoint(org.poly2tri.triangulation.point.TPoint) Point(org.poly2tri.geometry.primitives.Point) Ray3(com.ardor3d.math.Ray3)

Example 4 with Point

use of org.poly2tri.geometry.primitives.Point in project energy3d by concord-consortium.

the class SolarRadiation method computeOnFresnelReflector.

// unlike PV solar panels, no indirect (ambient or diffuse) radiation should be included in reflection calculation
private void computeOnFresnelReflector(final int minute, final ReadOnlyVector3 directionTowardSun, final FresnelReflector reflector) {
    final int nx = reflector.getNSectionLength();
    final int ny = reflector.getNSectionWidth();
    final Foundation target = reflector.getReceiver();
    if (target != null) {
        final Calendar calendar = Heliodon.getInstance().getCalendar();
        calendar.set(Calendar.HOUR_OF_DAY, (int) ((double) minute / (double) SolarRadiation.MINUTES_OF_DAY * 24.0));
        calendar.set(Calendar.MINUTE, minute % 60);
        reflector.draw();
    }
    // nx*ny*60: nx*ny is to get the unit cell area of the nx*ny grid; 60 is to convert the unit of timeStep from minute to kWh
    final double a = reflector.getModuleWidth() * reflector.getLength() * Scene.getInstance().getTimeStep() / (nx * ny * 60.0);
    final ReadOnlyVector3 normal = reflector.getNormal();
    if (normal == null) {
        throw new RuntimeException("Normal is null");
    }
    final Mesh mesh = reflector.getRadiationMesh();
    MeshDataStore data = onMesh.get(mesh);
    if (data == null) {
        data = initMeshTextureDataOnRectangle(mesh, nx, ny);
    }
    final ReadOnlyVector3 offset = directionTowardSun.multiply(1, null);
    final double dot = normal.dot(directionTowardSun);
    double directRadiation = 0;
    if (dot > 0) {
        directRadiation += calculateDirectRadiation(directionTowardSun, normal);
    }
    final FloatBuffer vertexBuffer = mesh.getMeshData().getVertexBuffer();
    // (0, 0)
    final Vector3 p0 = new Vector3(vertexBuffer.get(3), vertexBuffer.get(4), vertexBuffer.get(5));
    // (1, 0)
    final Vector3 p1 = new Vector3(vertexBuffer.get(6), vertexBuffer.get(7), vertexBuffer.get(8));
    // (0, 1)
    final Vector3 p2 = new Vector3(vertexBuffer.get(0), vertexBuffer.get(1), vertexBuffer.get(2));
    // final Vector3 q0 = mesh.localToWorld(p0, null);
    // final Vector3 q1 = mesh.localToWorld(p1, null);
    // final Vector3 q2 = mesh.localToWorld(p2, null);
    // System.out.println("***" + q0.distance(q1) * Scene.getInstance().getAnnotationScale() + "," + q0.distance(q2) * Scene.getInstance().getAnnotationScale());
    // this is the longer side (supposed to be y)
    final Vector3 u = p1.subtract(p0, null).normalizeLocal();
    // this is the shorter side (supposed to be x)
    final Vector3 v = p2.subtract(p0, null).normalizeLocal();
    // x and y must be swapped to have correct heat map texture, because nx represents rows and ny columns as we call initMeshTextureDataOnRectangle(mesh, nx, ny)
    final double xSpacing = p1.distance(p0) / nx;
    final double ySpacing = p2.distance(p0) / ny;
    final Vector3 absorber = target != null ? target.getSolarReceiverCenter() : null;
    List<Mesh> absorberCollisionMeshes = null;
    if (target != null) {
        absorberCollisionMeshes = new ArrayList<Mesh>();
        for (final HousePart child : target.getChildren()) {
            absorberCollisionMeshes.add((Mesh) child.getRadiationCollisionSpatial());
        }
        final List<Roof> roofs = target.getRoofs();
        if (!roofs.isEmpty()) {
            for (final Roof r : roofs) {
                for (final Spatial roofPart : r.getRoofPartsRoot().getChildren()) {
                    absorberCollisionMeshes.add((Mesh) ((Node) roofPart).getChild(6));
                }
            }
        }
    }
    final int iMinute = minute / Scene.getInstance().getTimeStep();
    final boolean reflectionMapOnly = Scene.getInstance().getOnlyReflectedEnergyInMirrorSolarMap();
    for (int x = 0; x < nx; x++) {
        for (int y = 0; y < ny; y++) {
            if (EnergyPanel.getInstance().isCancelled()) {
                throw new CancellationException();
            }
            final Vector3 u2 = u.multiply(xSpacing * (x + 0.5), null);
            final Vector3 v2 = v.multiply(ySpacing * (y + 0.5), null);
            final ReadOnlyVector3 p = mesh.getWorldTransform().applyForward(p0.add(v2, null).addLocal(u2)).addLocal(offset);
            final Ray3 pickRay = new Ray3(p, directionTowardSun);
            if (dot > 0) {
                final PickResults pickResults = new PrimitivePickResults();
                for (final Spatial spatial : collidables) {
                    if (spatial != mesh) {
                        PickingUtil.findPick(spatial, pickRay, pickResults, false);
                        if (pickResults.getNumber() != 0) {
                            break;
                        }
                    }
                }
                if (pickResults.getNumber() == 0) {
                    // for heat map generation
                    if (!reflectionMapOnly) {
                        data.dailySolarIntensity[x][y] += directRadiation;
                    }
                    // TODO: Edge losses are not considered yet
                    if (absorber != null) {
                        // TODO: This calculation is not exactly accurate as the collision detection assumes that the ray emits from a grid point on the reflector to
                        // the parallel position on the absorber tube -- without considering the actual direction of the reflected light
                        final Vector3 toAbsorber = absorber.subtract(p, null);
                        toAbsorber.setY(0);
                        final Ray3 rayToAbsorber = new Ray3(p, toAbsorber.normalize(null));
                        final PickResults pickResultsToAbsorber = new PrimitivePickResults();
                        for (final Spatial spatial : collidables) {
                            if (spatial != mesh) {
                                if (absorberCollisionMeshes == null || (absorberCollisionMeshes != null && !absorberCollisionMeshes.contains(spatial))) {
                                    PickingUtil.findPick(spatial, rayToAbsorber, pickResultsToAbsorber, false);
                                    if (pickResultsToAbsorber.getNumber() != 0) {
                                        // FIXME: how to stop the ray when it hits the absorber?
                                        break;
                                    }
                                }
                            }
                        }
                        if (pickResultsToAbsorber.getNumber() == 0) {
                            final double r = directRadiation * Atmosphere.getTransmittance(toAbsorber.length() * Scene.getInstance().getAnnotationScale() * 0.001, false);
                            reflector.getSolarPotential()[iMinute] += r * a;
                            if (reflectionMapOnly) {
                                data.dailySolarIntensity[x][y] += r;
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : Calendar(java.util.Calendar) Node(com.ardor3d.scenegraph.Node) Mesh(com.ardor3d.scenegraph.Mesh) FloatBuffer(java.nio.FloatBuffer) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) CullHint(com.ardor3d.scenegraph.hint.CullHint) TPoint(org.poly2tri.triangulation.point.TPoint) Point(org.poly2tri.geometry.primitives.Point) Ray3(com.ardor3d.math.Ray3) PrimitivePickResults(com.ardor3d.intersection.PrimitivePickResults) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Roof(org.concord.energy3d.model.Roof) Spatial(com.ardor3d.scenegraph.Spatial) CancellationException(java.util.concurrent.CancellationException) Foundation(org.concord.energy3d.model.Foundation) PrimitivePickResults(com.ardor3d.intersection.PrimitivePickResults) PickResults(com.ardor3d.intersection.PickResults) HousePart(org.concord.energy3d.model.HousePart)

Example 5 with Point

use of org.poly2tri.geometry.primitives.Point in project energy3d by concord-consortium.

the class MeshLib method computeOutline.

public static ArrayList<ReadOnlyVector3> computeOutline(final FloatBuffer buf) {
    final Map<LineSegment3, Boolean> visitMap = new HashMap<LineSegment3, Boolean>();
    for (int i = 0; i < buf.limit(); i += 9) {
        for (int trianglePointIndex = 0; trianglePointIndex < 9; trianglePointIndex += 3) {
            buf.position(i + trianglePointIndex);
            Vector3 p1 = new Vector3(buf.get(), buf.get(), buf.get());
            buf.position(i + (trianglePointIndex + 3) % 9);
            Vector3 p2 = new Vector3(buf.get(), buf.get(), buf.get());
            if (p2.getX() < p1.getX() || (p2.getX() == p1.getX() && p2.getY() < p1.getY())) {
                final Vector3 tmp = p1;
                p1 = p2;
                p2 = tmp;
            }
            final LineSegment3 line = new LineSegment3(p1, p2);
            final Boolean pastVisit = visitMap.get(line);
            if (pastVisit == null) {
                visitMap.put(line, true);
            } else {
                visitMap.put(line, false);
            }
        }
    }
    final ArrayList<ReadOnlyVector3> outlinePoints = new ArrayList<ReadOnlyVector3>();
    for (final LineSegment3 line : visitMap.keySet()) {
        if (visitMap.get(line)) {
            final Vector3 negativeEnd = line.getNegativeEnd(null);
            outlinePoints.add(negativeEnd);
            outlinePoints.add(line.getPositiveEnd(null));
        }
    }
    final ArrayList<ReadOnlyVector3> sortedOutlinePoints = new ArrayList<ReadOnlyVector3>(outlinePoints.size() / 2);
    sortedOutlinePoints.add(outlinePoints.get(0));
    ReadOnlyVector3 lastPoint = outlinePoints.get(1);
    sortedOutlinePoints.add(lastPoint);
    outlinePoints.remove(1);
    outlinePoints.remove(0);
    while (!outlinePoints.isEmpty()) {
        boolean foundSomething = false;
        for (int i = 0; i < outlinePoints.size(); i++) {
            if (Util.isEqual(outlinePoints.get(i), lastPoint)) {
                final int otherEndIndex = i % 2 == 0 ? i + 1 : i - 1;
                lastPoint = outlinePoints.get(otherEndIndex);
                sortedOutlinePoints.add(lastPoint);
                outlinePoints.remove(Math.max(i, otherEndIndex));
                outlinePoints.remove(Math.min(i, otherEndIndex));
                foundSomething = true;
                break;
            }
        }
        if (!foundSomething) {
            break;
        }
    }
    // remove last point if duplicated of first point
    if (Util.isEqual(sortedOutlinePoints.get(0), sortedOutlinePoints.get(sortedOutlinePoints.size() - 1))) {
        sortedOutlinePoints.remove(sortedOutlinePoints.size() - 1);
    }
    return sortedOutlinePoints;
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) HashMap(java.util.HashMap) LineSegment3(com.ardor3d.math.LineSegment3) ArrayList(java.util.ArrayList) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) CullHint(com.ardor3d.scenegraph.hint.CullHint) PolygonPoint(org.poly2tri.geometry.polygon.PolygonPoint) TPoint(org.poly2tri.triangulation.point.TPoint) Point(org.poly2tri.geometry.primitives.Point)

Aggregations

Point (org.poly2tri.geometry.primitives.Point)15 ReadOnlyVector3 (com.ardor3d.math.type.ReadOnlyVector3)12 TPoint (org.poly2tri.triangulation.point.TPoint)12 CullHint (com.ardor3d.scenegraph.hint.CullHint)11 Vector3 (com.ardor3d.math.Vector3)9 PickResults (com.ardor3d.intersection.PickResults)6 PrimitivePickResults (com.ardor3d.intersection.PrimitivePickResults)6 Ray3 (com.ardor3d.math.Ray3)6 Spatial (com.ardor3d.scenegraph.Spatial)6 FloatBuffer (java.nio.FloatBuffer)6 CancellationException (java.util.concurrent.CancellationException)6 PickingHint (com.ardor3d.scenegraph.hint.PickingHint)5 PolygonPoint (org.poly2tri.geometry.polygon.PolygonPoint)5 Mesh (com.ardor3d.scenegraph.Mesh)4 Calendar (java.util.Calendar)3 ArdorVector3Point (org.poly2tri.triangulation.point.ardor3d.ArdorVector3Point)3 Vector2 (com.ardor3d.math.Vector2)2 ReadOnlyVector2 (com.ardor3d.math.type.ReadOnlyVector2)2 Path2D (java.awt.geom.Path2D)2 ArrayList (java.util.ArrayList)2