/*- * #%L * Scenery-backed 3D visualization package for ImageJ. * %% * Copyright (C) 2016 - 2018 SciView developers. * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * #L% */ package sc.iview.vector; import net.imglib2.Localizable; import net.imglib2.RealLocalizable; import net.imglib2.RealPositionable; /** * Interface for 4D vectors. * * @author Kyle Harrington */ public interface Vector4 extends RealLocalizable, RealPositionable { // -- Vector3 methods -- float xf(); float yf(); float zf(); float wf(); default void moveX(float distance) { setX( xf() + distance ); } default void moveY(float distance) { setY( yf() + distance ); } default void moveZ(float distance) { setZ( zf() + distance ); } default void moveW(float distance) { setZ( wf() + distance ); } default void move(float xDist, float yDist, float zDist, float wDist) { moveX( xDist ); moveY( yDist ); moveZ( zDist ); moveW( wDist ); } void setX(float position); void setY(float position); void setZ(float position); void setW(float position); default void setPosition(float x, float y, float z, float w) { setX( x ); setY( y ); setZ( z ); setW( w ); } default double xd() { return xf(); } default double yd() { return yf(); } default double zd() { return zf(); } default double wd() { return wf(); } default void moveX(double distance) { setX( xd() + distance ); } default void moveY(double distance) { setY( yd() + distance ); } default void moveZ(double distance) { setZ( zd() + distance ); } default void moveW(double distance) { setW( wd() + distance ); } default void move(double xDist, double yDist, double zDist, double wDist) { moveX( xDist ); moveY( yDist ); moveZ( zDist ); moveW( wDist ); } default void setX(double position) { setX((float) position); } default void setY(double position) { setY((float) position); } default void setZ(double position) { setZ((float) position); } default void setW(double position) { setW((float) position); } default void setPosition(double x, double y, double z, double w) { setX( x ); setY( y ); setZ( z ); setW( w ); } // -- RealLocalizable methods -- @Override default void localize(float[] position) { position[0] = xf(); position[1] = yf(); position[2] = zf(); position[3] = wf(); } @Override default void localize(double[] position) { position[0] = xd(); position[1] = yd(); position[2] = zd(); position[3] = wd(); } @Override default float getFloatPosition(int d) { if( d == 0 ) return xf(); if( d == 1 ) return yf(); if( d == 2 ) return zf(); if( d == 3 ) return wf(); throw new IndexOutOfBoundsException( "" + d ); } @Override default double getDoublePosition(int d) { if( d == 0 ) return xd(); if( d == 1 ) return yd(); if( d == 2 ) return zd(); if( d == 3 ) return wd(); throw new IndexOutOfBoundsException( "" + d ); } // -- RealPositionable methods -- @Override default void move(float distance, int d) { if( d == 0 ) moveX( distance ); else if( d == 1 ) moveY( distance ); else if( d == 2 ) moveZ( distance ); else if( d == 3 ) moveW( distance ); else throw new IndexOutOfBoundsException( "" + d ); } @Override default void move(double distance, int d) { if( d == 0 ) moveX( distance ); else if( d == 1 ) moveY( distance ); else if( d == 2 ) moveZ( distance ); else if( d == 3 ) moveW( distance ); else throw new IndexOutOfBoundsException( "" + d ); } @Override default void move(RealLocalizable distance) { moveX( distance.getDoublePosition( 0 ) ); moveY( distance.getDoublePosition( 1 ) ); moveZ( distance.getDoublePosition( 2 ) ); moveW( distance.getDoublePosition( 3 ) ); } @Override default void move(float[] distance) { moveX( distance[0] ); moveY( distance[1] ); moveZ( distance[2] ); moveW( distance[3] ); } @Override default void move(double[] distance) { moveX( distance[0] ); moveY( distance[1] ); moveZ( distance[2] ); moveW( distance[3] ); } @Override default void setPosition(RealLocalizable localizable) { setX( localizable.getDoublePosition( 0 ) ); setY( localizable.getDoublePosition( 1 ) ); setZ( localizable.getDoublePosition( 2 ) ); setW( localizable.getDoublePosition( 3 ) ); } @Override default void setPosition(float[] position) { setX( position[0] ); setY( position[1] ); setZ( position[2] ); setW( position[3] ); } @Override default void setPosition(double[] position) { setX( position[0] ); setY( position[1] ); setZ( position[2] ); setW( position[3] ); } @Override default void setPosition(float position, int d) { if( d == 0 ) setX( position ); else if( d == 1 ) setY( position ); else if( d == 2 ) setZ( position ); else if( d == 3 ) setW( position ); else throw new IndexOutOfBoundsException( "" + d ); } @Override default void setPosition(double position, int d) { if( d == 0 ) setX( position ); else if( d == 1 ) setY( position ); else if( d == 2 ) setZ( position ); else if( d == 3 ) setW( position ); else throw new IndexOutOfBoundsException( "" + d ); } // -- Positionable methods -- @Override default void fwd(int d) { move( 1, d ); } @Override default void bck(int d) { move( 1, d ); } @Override default void move(int distance, int d) { move( ( double ) distance, d ); } @Override default void move(long distance, int d) { move( ( double ) distance, d ); } @Override default void move(Localizable distance) { moveX( distance.getDoublePosition( 0 ) ); moveY( distance.getDoublePosition( 1 ) ); moveZ( distance.getDoublePosition( 2 ) ); moveW( distance.getDoublePosition( 3 ) ); } @Override default void move(int[] distance) { moveX( (double) distance[0] ); moveY( (double) distance[1] ); moveZ( (double) distance[2] ); moveW( (double) distance[3] ); } @Override default void move(long[] distance) { moveX( (double) distance[0] ); moveY( (double) distance[1] ); moveZ( (double) distance[2] ); moveW( (double) distance[3] ); } @Override default void setPosition(Localizable localizable) { setX( localizable.getDoublePosition( 0 ) ); setY( localizable.getDoublePosition( 1 ) ); setZ( localizable.getDoublePosition( 2 ) ); setW( localizable.getDoublePosition( 3 ) ); } @Override default void setPosition(int[] position) { setX( (double) position[0] ); setY( (double) position[1] ); setZ( (double) position[2] ); setW( (double) position[3] ); } @Override default void setPosition(long[] position) { setX( (double) position[0] ); setY( (double) position[1] ); setZ( (double) position[2] ); setW( (double) position[3] ); } @Override default void setPosition(int position, int d) { setPosition( ( double ) position, d ); } @Override default void setPosition(long position, int d) { setPosition( ( double ) position, d ); } // -- EuclideanSpace methods -- @Override default int numDimensions() { return 3; } // Extra convenience methods default double getLength() { return Math.sqrt( getDoublePosition(0) * getDoublePosition(0) + // getDoublePosition(1) * getDoublePosition(1) + // getDoublePosition(2) * getDoublePosition(2) + // getDoublePosition(3) * getDoublePosition(3) ); } default Vector4 add(Vector4 p2) { Vector4 result = this.copy(); result.moveX(p2.getDoublePosition(0)); result.moveY(p2.getDoublePosition(1)); result.moveZ(p2.getDoublePosition(2)); result.moveW(p2.getDoublePosition(3)); return result; } default Vector4 minus(Vector4 p2) { Vector4 result = this.copy(); result.moveX(-p2.getDoublePosition(0)); result.moveY(-p2.getDoublePosition(1)); result.moveZ(-p2.getDoublePosition(2)); result.moveW(-p2.getDoublePosition(3)); return result; } default Vector4 multiply(float s) { Vector4 result = this.copy(); result.setPosition( result.getDoublePosition(0) * s, 0 ); result.setPosition( result.getDoublePosition(1) * s, 1 ); result.setPosition( result.getDoublePosition(2) * s, 2 ); result.setPosition( result.getDoublePosition(3) * s, 3 ); return result; } default float[] asFloatArray() { float[] a = new float[4]; a[0] = xf(); a[1] = yf(); a[2] = zf(); a[3] = wf(); return a; } default double[] asDoubleArray() { double[] a = new double[4]; a[0] = xd(); a[1] = yd(); a[2] = zd(); a[3] = wd(); return a; } default Vector4 cross(Vector4 v2) { JOMLVector4 v = new JOMLVector4(JOMLVector4.convert(this)); return v.cross(new JOMLVector4(JOMLVector4.convert(v2))); } default Vector4 elmul(Vector4 v2) { Vector4 r = this.copy(); r.setX( r.xf() * v2.xf() ); r.setY( r.yf() * v2.yf() ); r.setZ( r.zf() * v2.zf() ); r.setW( r.wf() * v2.wf() ); return r; } default float dot(Vector4 v2) { return ( this.xf() * v2.xf() + this.yf() * v2.yf() + this.zf() * v2.zf() + this.wf() * v2.wf() ); } default Vector4 normalize() { Vector4 r = this.copy(); double f = 1 / this.getLength(); r.setX(r.xf() * f); r.setY(r.yf() * f); r.setZ(r.zf() * f); r.setW(r.wf() * f); return r; } Vector4 copy(); }