/* This file is part of the source code for 3D-XplorMath-J, Version 1.0 (January 2008). * Copyright (c) 2008 The 3D-XplorMath Consortium (http://3d-xplormath.org). * This source code is released under a BSD License, which allows redistribution * in source and binary form, with or without modification, provided copyright * and license information are included, and with no warranty or guarantee of * any kind. For details, see http://3d-xplormath.org/j/source/BSDLicense.txt */ package vmm.core.render; import java.awt.Graphics2D; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; import vmm.core.Transform; public class Curve2D extends GeometryElement2D { private double[] x,y; boolean closed; public Curve2D(Point2D[] points, int startindex, int endindex) { while (points[startindex] == null && startindex < endindex) startindex++; while (points[endindex] == null && startindex < endindex) endindex--; boolean gap = false; x = new double[endindex - startindex + 1]; y = new double[endindex - startindex + 1]; for (int i = startindex; i <= endindex; i++) if (points[i] == null || Double.isNaN(points[i].getY())) { x[i-startindex] = Double.NaN; gap = true; } else { x[i-startindex] = points[i].getX(); y[i-startindex] = points[i].getY(); } if (!gap && Math.abs(x[x.length-1] - x[0]) + Math.abs(y[y.length-1] - y[0]) < 1e-8) closed = true; else closed = false; } public Curve2D(Point2D[] points) { this(points,0,points.length-1); } protected void draw(Transform transform, Graphics2D g) { if (x.length < 2) return; GeneralPath curve = new GeneralPath(); double maxJumpX = Math.abs(transform.getXmax() - transform.getXmin())/4; double maxJumpY = Math.abs(transform.getYmax() - transform.getYmin())/4; if (transform.appliedTransform2D()) maxJumpX = maxJumpY = Math.max(maxJumpX,maxJumpY); Point2D.Float tempPoint = new Point2D.Float(); boolean starting = true; boolean jumped = false; int i; for (i = 0; i < x.length-1; i++) { if (! Double.isNaN(x[i]) ) { if (starting) { tempPoint.setLocation(x[i],y[i]); transform.windowToDrawingCoords(tempPoint); curve.moveTo(tempPoint.x, tempPoint.y); starting = false; } else if (Math.abs(x[i] - x[i-1]) > maxJumpX || Math.abs(y[i] - y[i-1]) > maxJumpY) { jumped = true; starting = true; } else { tempPoint.setLocation(x[i],y[i]); transform.windowToDrawingCoords(tempPoint); curve.lineTo(tempPoint.x, tempPoint.y); } } } // i == points.length-1 if (closed && !jumped && Math.abs(x[i] - x[i-1]) <= maxJumpX && Math.abs(y[i] - y[i-1]) <= maxJumpY) curve.closePath(); else if (!starting) { tempPoint.setLocation(x[i],y[i]); transform.windowToDrawingCoords(tempPoint); curve.lineTo(tempPoint.x, tempPoint.y); } g.draw(curve); } }