package com.bioxx.jmapgen; import java.util.ArrayList; import net.minecraft.util.math.BlockPos; public class Spline3D { /** * Array representing the relative proportion of the total distance * of each point in the line ( i.e. first point is 0.0, end point is * 1.0, a point halfway on line is 0.5 ). */ private double[] t; private Spline splineX; private Spline splineY; private Spline splineZ; /** * Total length tracing the points on the spline */ private double length; /** * Creates a new Spline2D. * @param points */ public Spline3D(ArrayList<BlockPos> points) { double[] x = new double[points.size()]; double[] y = new double[points.size()]; double[] z = new double[points.size()]; for(int i = 0; i< points.size(); i++) { x[i] = points.get(i).getX(); y[i] = points.get(i).getY(); z[i] = points.get(i).getZ(); } init(x, y, z); } /** * Creates a new Spline2D. * @param x * @param y */ public Spline3D(double[] x, double[] y, double[] z) { init(x, y, z); } private void init(double[] x, double[] y, double[] z) { if (x.length != y.length || x.length != z.length || y.length != z.length) { throw new IllegalArgumentException("Arrays must have the same length."); } if (x.length < 2) { throw new IllegalArgumentException("Spline edges must have at least two points."); } t = new double[x.length]; t[0] = 0.0; // start point is always 0.0 // Calculate the partial proportions of each section between each set // of points and the total length of sum of all sections for (int i = 1; i < t.length; i++) { double lx = x[i] - x[i-1]; double ly = y[i] - y[i-1]; double lz = z[i] - z[i-1]; // If either diff is zero there is no point performing the square root if ( 0.0 == lx ) { t[i] = Math.abs(lz); } else if ( 0.0 == lz ) { t[i] = Math.abs(lx); } else { t[i] = Math.sqrt(lx*lx+ly*ly+lz*lz); } length += t[i]; t[i] += t[i-1]; } for(int i = 1; i< (t.length)-1; i++) { t[i] = t[i] / length; } t[(t.length)-1] = 1.0; // end point is always 1.0 splineX = new Spline(t, x); splineY = new Spline(t, y); splineZ = new Spline(t, z); } /** * @param t 0 <= t <= 1 */ public BlockPos getPoint(double t) { return new BlockPos(splineX.getValue(t), splineY.getValue(t), splineZ.getValue(t)); } /** * Used to check the correctness of this spline */ public boolean checkValues() { return (splineX.checkValues() && splineY.checkValues() && splineZ.checkValues()); } public double getDx(double t) { return splineX.getDx(t); } public double getDy(double t) { return splineY.getDx(t); } public double getDz(double t) { return splineZ.getDx(t); } public Spline getSplineX() { return splineX; } public Spline getSplineY() { return splineY; } public Spline getSplineZ() { return splineZ; } public double getLength() { return length; } }