/* (non-Javadoc) * @see org.apache.batik.parser.PathHandler#curvetoCubicSmoothAbs(float, float, float, float) */ public void curvetoCubicSmoothAbs(float x2, float y2, float x, float y) throws ParseException { if (verbose) System.out.println("curvetoCubicSmoothAbs x2:" + x2 + " y2:" + y2 + " x:" + x + " y:" + y); Vertex lastPoint = pathPoints.getLast(); if (lastPoint instanceof BezierVertex) { BezierVertex lastBez = (BezierVertex) lastPoint; Vertex lastConPointCopy = (Vertex) lastBez.getSecondCtrlPoint().getCopy(); // reflect the last controlpoint at the current point lastConPointCopy.rotateZ(lastPoint, 180); BezierVertex b = new BezierVertex(lastConPointCopy.getX(), lastConPointCopy.getY(), 0, x2, y2, 0, x, y, 0); pathPoints.add(b); currentSubPath.add(b); } else { if (verbose) System.out.println( "Couldnt get last controlpoint at: curvetoCubicSmoothAbs - using last point as first controlpoint"); Vertex lastEndPoint = new Vertex(lastPoint.getX(), lastPoint.getY(), 0); BezierVertex b = new BezierVertex(lastEndPoint.getX(), lastEndPoint.getY(), 0, x2, y2, 0, x, y, 0); pathPoints.add(b); currentSubPath.add(b); } }
/** * Returns an array of exact copies of the provided vertices. * * @param vertices the vertices * @return the deep vertex array copy */ public static Vertex[] getDeepVertexArrayCopy(Vertex[] vertices) { Vertex[] copy = new Vertex[vertices.length]; for (int i = 0; i < vertices.length; i++) { Vertex vertex = vertices[i]; copy[i] = (Vertex) vertex.getCopy(); } return copy; }
/** * Gets the vertices. * * @param resolution the resolution * @return the vertices */ protected Vertex[] getVertices(int resolution) { Vertex[] verts = new Vertex[resolution + 1]; float t; float inc = degrees / (float) resolution; double cosTheta = Math.cos(theta); double sinTheta = Math.sin(theta); MTColor fillColor = this.getFillColor(); for (int i = 0; i < resolution; i++) { t = 0 + (i * inc); // float x = (float) (centerPoint.x + (radiusX * Math.cos(t) * cosTheta) //TODO remove theta // stuff? oder enablen als parameter? // - (radiusY * Math.sin(t) * sinTheta) ); // float y = (float) (centerPoint.y + (radiusX * Math.cos(t) * sinTheta) // + (radiusY * Math.sin(t) * cosTheta) ); float x = (float) (centerPoint.x - (radiusX * Math.cos(t) * cosTheta) + (radiusY * Math.sin(t) * sinTheta)); float y = (float) (centerPoint.y - (radiusX * Math.cos(t) * sinTheta) - (radiusY * Math.sin(t) * cosTheta)); verts[i] = new Vertex( x, y, centerPoint.z, fillColor.getR(), fillColor.getG(), fillColor.getB(), fillColor.getAlpha()); } verts[verts.length - 1] = verts[0]; // System.out.println("Points: " + verts.length); // Create tex coords float width = radiusX * 2; float height = radiusY * 2; float upperLeftX = centerPoint.x - radiusX; float upperLeftY = centerPoint.y - radiusY; for (int i = 0; i < verts.length; i++) { Vertex vertex = verts[i]; vertex.setTexCoordU((vertex.x - upperLeftX) / width); vertex.setTexCoordV((vertex.y - upperLeftY) / height); // System.out.println("TexU:" + vertex.getTexCoordU() + " TexV:" + vertex.getTexCoordV()); } return verts; }
/** * Returns a list of exact copies of the provided vertices. * * @param vertices the vertices * @return the deep vertex array copy */ public static ArrayList<Vertex[]> getDeepVertexArrayCopy(ArrayList<Vertex[]> vertices) { ArrayList<Vertex[]> returnList = new ArrayList<Vertex[]>(); for (Vertex[] vs : vertices) { Vertex[] copy = new Vertex[vs.length]; for (int i = 0; i < vs.length; i++) { Vertex vertex = vs[i]; copy[i] = (Vertex) vertex.getCopy(); } returnList.add(copy); } return returnList; }
/* (non-Javadoc) * @see org.apache.batik.parser.PathHandler#movetoAbs(float, float) */ public void movetoAbs(float x, float y) throws ParseException { if (verbose) System.out.println("movetoAbs: x:" + x + " y:" + y); // If the last contour wasnt closed with Z, // we save the last contour here,but without closing it if (!currentSubPath.isEmpty()) { Vertex[] currentSplitPathArr = (Vertex[]) currentSubPath.toArray(new Vertex[currentSubPath.size()]); subPaths.add(currentSplitPathArr); currentSubPath.clear(); } Vertex moveTo = new Vertex(x, y, 0); pathPoints.add(moveTo); currentSubPath.add(moveTo); reverseMoveToStack.push((Vertex) moveTo.getCopy()); }
/* (non-Javadoc) * @see org.apache.batik.parser.PathHandler#movetoRel(float, float) */ public void movetoRel(float x, float y) throws ParseException { if (verbose) System.out.println("movetoRel: " + x + "," + y); // If the last contour wasnt closed with Z, // we save the last contour here, without closing it if (!currentSubPath.isEmpty()) { Vertex[] currentSplitPathArr = (Vertex[]) currentSubPath.toArray(new Vertex[currentSubPath.size()]); subPaths.add(currentSplitPathArr); currentSubPath.clear(); } Vertex moveTo; if (!pathPoints.isEmpty() && pathPoints.getLast() != null) { moveTo = new Vertex(pathPoints.getLast().getX() + x, pathPoints.getLast().getY() + y, 0); } else { moveTo = new Vertex(x, y, 0); } pathPoints.add(moveTo); currentSubPath.add(moveTo); reverseMoveToStack.push((Vertex) moveTo.getCopy()); }
/* (non-Javadoc) * @see org.apache.batik.parser.PathHandler#curvetoQuadraticSmoothAbs(float, float) */ public void curvetoQuadraticSmoothAbs(float x, float y) throws ParseException { if (verbose) System.out.println("curvetoQuadraticSmoothAbs " + " x:" + x + " y:" + y); Vertex lastPoint = pathPoints.getLast(); if (lastPoint instanceof BezierVertex && cubicBezVertTOQuadricControlPoint.get(lastPoint) != null) { Vertex lastEndPoint = new Vertex( pathPoints.getLast().getX(), pathPoints.getLast().getY(), pathPoints.getLast().getZ()); // Get control point of last QuadTo Vertex lastQuadControlPoint = cubicBezVertTOQuadricControlPoint.get(lastPoint); cubicBezVertTOQuadricControlPoint.remove(lastPoint); // Rotate that controlpoint around the end point of the last QuadTo lastQuadControlPoint.rotateZ(lastEndPoint, 180); // Put in startPoint = last QuadTo Endpoint of this smoothQuadTo, the calculated control // point, and the endpoint of smoothQuadTo BezierVertex b5 = Tools3D.getCubicFromQuadraticCurve( lastEndPoint, lastQuadControlPoint, new Vertex(x, y, 0)); // Save last quad control point cubicBezVertTOQuadricControlPoint.put(b5, lastQuadControlPoint); pathPoints.add(b5); currentSubPath.add(b5); } else { if (verbose) System.out.println( "Couldnt get last controlpoint at: curvetoQuadraticSmoothAbs - using last point as controlpoint"); // If we couldnt retrieve the controlpoint of the current point, // we use the current point as the new controlpoint Vertex lastEndPoint = new Vertex(lastPoint.getX(), lastPoint.getY(), 0); Vertex quadControlPoint = new Vertex(lastPoint.getX(), lastPoint.getY(), 0); BezierVertex b5 = Tools3D.getCubicFromQuadraticCurve(lastEndPoint, quadControlPoint, new Vertex(x, y, 0)); cubicBezVertTOQuadricControlPoint.put(b5, quadControlPoint); pathPoints.add(b5); currentSubPath.add(b5); } }
/* (non-Javadoc) * @see org.apache.batik.parser.PathHandler#curvetoQuadraticRel(float, float, float, float) */ public void curvetoQuadraticRel(float x1, float y1, float x, float y) throws ParseException { if (verbose) System.out.println("curvetoQuadraticRel: " + x1 + "," + y1 + " " + x + "," + y); if (!pathPoints.isEmpty() && pathPoints.getLast() != null) { Vertex lastPoint = pathPoints.getLast(); Vertex lastEndPoint = new Vertex(lastPoint.getX(), lastPoint.getY(), lastPoint.getZ()); Vertex quadControlPoint = new Vertex(lastPoint.getX() + x1, lastPoint.getY() + y1, 0); // Put in startPoint = last QuadTo Endpoint of this smoothQuadTo, the calculated control // point, and the endpoint of smoothQuadTo BezierVertex b5 = Tools3D.getCubicFromQuadraticCurve( lastEndPoint, quadControlPoint, new Vertex(lastPoint.getX() + x, lastPoint.getY() + y, 0)); cubicBezVertTOQuadricControlPoint.put(b5, quadControlPoint); pathPoints.add(b5); currentSubPath.add(b5); } else { System.out.println("last point null at curvetoQuadraticRel"); } }
/* (non-Javadoc) * @see org.apache.batik.parser.PathHandler#curvetoCubicRel(float, float, float, float, float, float) */ public void curvetoCubicRel(float x1, float y1, float x2, float y2, float x, float y) throws ParseException { if (verbose) System.out.println( "curvetoCubicSmoothRel: " + x1 + "," + y1 + " " + x2 + "," + y2 + " " + x + "," + y); Vertex lastPoint = pathPoints.getLast(); BezierVertex b = new BezierVertex( lastPoint.getX() + x1, lastPoint.getY() + y1, 0, lastPoint.getX() + x2, lastPoint.getY() + y2, 0, lastPoint.getX() + x, lastPoint.getY() + y, 0); pathPoints.add(b); currentSubPath.add(b); }
/** * Static method for computing vertices of an annular segment. * * @param center * @param innerRadius * @param outerRadius * @param startAngle * @param endAngle * @param segments * @return */ public static Vertex[] computeVertices( Vector3D center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments) { if (segments <= 0) { throw new IllegalArgumentException("segments must be positive: " + segments); } List<Vertex> vertices = new ArrayList<Vertex>(); final float rmin = Math.min(innerRadius, outerRadius); final float rmax = Math.max(innerRadius, outerRadius); startAngle = fixAngle(startAngle); endAngle = fixAngle(endAngle); final float startRadians = (float) Math.toRadians(startAngle); final float endRadians = (float) Math.toRadians(endAngle); float arc = (float) Math.toRadians(computeArcDegrees(startAngle, endAngle)); segments = (int) Math.round(segments * arc / (Math.PI / 2.0)); if (segments == 0) { segments = 1; } final float radInc = arc / segments; float currentRadians = endRadians; float minX = Float.MAX_VALUE; float maxX = 0f; float minY = Float.MAX_VALUE; float maxY = 0f; for (int i = 0; i <= segments; i++, currentRadians -= radInc) { float x = -rmax * (float) Math.cos(currentRadians) + center.x; float y = -rmax * (float) Math.sin(currentRadians) + center.y; if (x < minX) minX = x; if (x > maxX) maxX = x; if (y < minY) minY = y; if (y > maxY) maxY = y; vertices.add(new Vertex(x, y, center.z)); } currentRadians = startRadians; for (int i = 0; i <= segments; i++, currentRadians += radInc) { float x = -rmin * (float) Math.cos(currentRadians) + center.x; float y = -rmin * (float) Math.sin(currentRadians) + center.y; if (x < minX) minX = x; if (x > maxX) maxX = x; if (y < minY) minY = y; if (y > maxY) maxY = y; vertices.add(new Vertex(x, y, center.z)); } Vertex[] varray = vertices.toArray(new Vertex[vertices.size()]); float xRange = maxX - minX; float yRange = maxY - minY; // Set the texture X and Y for (Vertex v : varray) { float texU = 0f, texV = 0f; if (xRange > 0) { texU = (v.x - minX) / xRange; } if (yRange > 0) { texV = (v.y - minY) / yRange; } v.setTexCoordU(texU); v.setTexCoordV(texV); } return varray; }
/** * Uses the faces attached to this group during the parsing process and the lists with all * vertex and all texture coordinates of the obj file to create arrays for this group with * vertices and texture coords that only belong to this single group. * * @param allFileVerts * @param allTexCoords */ public void compileItsOwnLists(Vertex[] allFileVerts, float[][] allTexCoords) { indexArray = new int[faces.size() * 3]; if (allTexCoords.length > 0) { texCoordIndexArray = new int[faces.size() * 3]; } for (int i = 0; i < faces.size(); i++) { AFace currentFace = faces.get(i); Vertex v0 = allFileVerts[currentFace.p0]; Vertex v1 = allFileVerts[currentFace.p1]; Vertex v2 = allFileVerts[currentFace.p2]; if (allTexCoords.length > currentFace.t0 && allTexCoords.length > currentFace.t1 && allTexCoords.length > currentFace.t2) { float[] texV0 = allTexCoords[currentFace.t0]; float[] texV1 = allTexCoords[currentFace.t1]; float[] texV2 = allTexCoords[currentFace.t2]; // Etwas redundant immer wieder zu machen beim gleichen vertex..whatever v0.setTexCoordU(texV0[0]); v0.setTexCoordV(texV0[1]); v1.setTexCoordU(texV1[0]); v1.setTexCoordV(texV1[1]); v2.setTexCoordU(texV2[0]); v2.setTexCoordV(texV2[1]); // Check if there is a texture index in the hashtable at the faces texture pointer // if not, create a new index = the end of thexcoords list, and put the pointer into the // hash // if yes, point the faces texture pointer to the pointer in the hash // This process maps the texture coords and indices of all the groups in the obj // file to only this groups texture coord list and texture indices, the indices // are created from the index in the thex coord list when they are put in // Only the texture coordinates are added to the list that have not been adressed // in the texture indices pointers in the faces // Same texture pointers will point to the same texcoord in the list Integer oldToNewT0 = oldTexIndexToNewTexIndex.get(currentFace.t0); if (oldToNewT0 != null) { currentFace.t0 = oldToNewT0; } else { int newIndex = texCoordsForGroup.size(); texCoordsForGroup.add(texV0); oldTexIndexToNewTexIndex.put(currentFace.t0, newIndex); currentFace.t0 = newIndex; } Integer oldToNewT1 = oldTexIndexToNewTexIndex.get(currentFace.t1); if (oldToNewT1 != null) { currentFace.t1 = oldToNewT1; } else { int newIndex = texCoordsForGroup.size(); texCoordsForGroup.add(texV1); oldTexIndexToNewTexIndex.put(currentFace.t1, newIndex); currentFace.t1 = newIndex; } Integer oldToNewT2 = oldTexIndexToNewTexIndex.get(currentFace.t2); if (oldToNewT2 != null) { currentFace.t2 = oldToNewT2; } else { int newIndex = texCoordsForGroup.size(); texCoordsForGroup.add(texV2); oldTexIndexToNewTexIndex.put(currentFace.t2, newIndex); currentFace.t2 = newIndex; } } // Do the same for the vertices. // Create a new vertex pointer when adding the vertex to the list Integer oldToNewP0 = oldIndexToNewIndex.get(currentFace.p0); if (oldToNewP0 != null) { // index of the old vertex list has already been mapped to a new one here -> use the new // index in the face currentFace.p0 = oldToNewP0; } else { int newIndex = verticesForGroup.size(); verticesForGroup.add(v0); // mark that the former index (for exmample 323) is now at new index (f.e. 1) oldIndexToNewIndex.put(currentFace.p0, newIndex); currentFace.p0 = newIndex; } Integer oldToNewP1 = oldIndexToNewIndex.get(currentFace.p1); if (oldToNewP1 != null) { currentFace.p1 = oldToNewP1; } else { int newIndex = verticesForGroup.size(); verticesForGroup.add(v1); oldIndexToNewIndex.put(currentFace.p1, newIndex); currentFace.p1 = newIndex; } Integer oldToNewP2 = oldIndexToNewIndex.get(currentFace.p2); if (oldToNewP2 != null) { currentFace.p2 = oldToNewP2; } else { int newIndex = verticesForGroup.size(); verticesForGroup.add(v2); oldIndexToNewIndex.put(currentFace.p2, newIndex); currentFace.p2 = newIndex; } indexArray[i * 3] = currentFace.p0; indexArray[i * 3 + 1] = currentFace.p1; indexArray[i * 3 + 2] = currentFace.p2; if (allTexCoords.length > 0) { texCoordIndexArray[i * 3] = currentFace.t0; texCoordIndexArray[i * 3 + 1] = currentFace.t1; texCoordIndexArray[i * 3 + 2] = currentFace.t2; } } }
/** * scales the Vertex[] around the scalingpoint by the factors given for each dimension. * * @param inputArray the input array * @param scalingPoint the scaling point * @param X the x * @param Y the y * @param Z the z * @return the resulting vector array */ public static Vertex[] scaleVectorArray( Vertex[] inputArray, Vector3D scalingPoint, float X, float Y, float Z) { return Vertex.transFormArray(Matrix.getScalingMatrix(scalingPoint, X, Y, Z), inputArray); }
/** * rotates the Vertex array around the rotationpoint by the given degree. * * @param rotationPoint the rotation point * @param degree the degree * @param inputArray the input array * @return the rotated vector3D array */ public static Vertex[] zRotateVectorArray( Vertex[] inputArray, Vector3D rotationPoint, float degree) { return Vertex.transFormArray(Matrix.getZRotationMatrix(rotationPoint, degree), inputArray); }
/** * translates an array of Vertex by the given amounts in the directionvector. * * @param inputArray the input array * @param directionVector the direction vector * @return the vertex[] */ public static Vertex[] translateArray(Vertex[] inputArray, Vector3D directionVector) { return Vertex.transFormArray( Matrix.getTranslationMatrix( directionVector.getX(), directionVector.getY(), directionVector.getZ()), inputArray); }
/** * Multiplicates all Vector3D of the Vector3D array with the given transformation matrix, thus * transforming them. <br> * Make a deepcopy of the vectors first if you dont want the originals being altered! * * @param points the points * @param transformMatrix the transform matrix * @return the transformed vector array */ public static Vertex[] transFormArray(Matrix transformMatrix, Vertex[] points) { for (Vertex v : points) v.transform(transformMatrix); return points; }
/** * Gets the vertices. * * @param resolution the resolution * @return the vertices */ protected Vertex[] getVertices(int resolution) { Vertex[] verts; if (degrees < (float) Math.toRadians(360) && arcMode == pie) verts = new Vertex[resolution + 2]; else verts = new Vertex[resolution + 1]; float t; float inc = degrees / (float) resolution; double cosTheta = Math.cos(theta); double sinTheta = Math.sin(theta); MTColor fillColor = this.getFillColor(); for (int i = 0; i < resolution; i++) { t = 0 + (i * inc); // float x = (float) (centerPoint.x + (radiusX * Math.cos(t) * cosTheta) //TODO remove theta // stuff? oder enablen als parameter? // - (radiusY * Math.sin(t) * sinTheta) ); // float y = (float) (centerPoint.y + (radiusX * Math.cos(t) * sinTheta) // + (radiusY * Math.sin(t) * cosTheta) ); float x = (float) (centerPoint.x - (radiusX * Math.cos(t) * cosTheta) + (radiusY * Math.sin(t) * sinTheta)); float y = (float) (centerPoint.y - (radiusX * Math.cos(t) * sinTheta) - (radiusY * Math.sin(t) * cosTheta)); verts[i] = new Vertex( x, y, centerPoint.z, fillColor.getR(), fillColor.getG(), fillColor.getB(), fillColor.getAlpha()); } if (degrees < (float) Math.toRadians(360) && arcMode == pie) verts[verts.length - 2] = new Vertex( centerPoint.x, centerPoint.y, centerPoint.z, fillColor.getR(), fillColor.getG(), fillColor.getB(), fillColor.getAlpha()); verts[verts.length - 1] = (Vertex) verts[0] .getCopy(); // NEED TO USE COPY BECAUSE TEX COORDS MAY GET SCALED DOUBLE IF SAME // VERTEX OBJECT! // System.out.println("Points: " + verts.length); // Create tex coords float width = radiusX * 2; float height = radiusY * 2; float upperLeftX = centerPoint.x - radiusX; float upperLeftY = centerPoint.y - radiusY; for (int i = 0; i < verts.length; i++) { Vertex vertex = verts[i]; vertex.setTexCoordU((vertex.x - upperLeftX) / width); vertex.setTexCoordV((vertex.y - upperLeftY) / height); // System.out.println("TexU:" + vertex.getTexCoordU() + " TexV:" + vertex.getTexCoordV()); } return verts; }