All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.io7m.jtensors.VectorM4I Maven / Gradle / Ivy

/*
 * Copyright © 2013  http://io7m.com
 * 
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package com.io7m.jtensors;

import javax.annotation.Nonnull;
import javax.annotation.concurrent.NotThreadSafe;

import com.io7m.jaux.CheckedMath;

/**
 * 

* A four-dimensional mutable vector type with integer elements. *

*

* Values of this type cannot be accessed safely from multiple threads without * explicit synchronization. *

*/ @NotThreadSafe public class VectorM4I implements VectorReadable4I { /** * Calculate the absolute values of the elements in vector v, * saving the result to out. * * @param v * The input vector * @param out * The output vector * * @return (abs v.x, abs v.y, abs v.z, abs.w) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I absolute( final @Nonnull VectorReadable4I v, final @Nonnull VectorM4I out) { final int x = CheckedMath.absolute(v.getXI()); final int y = CheckedMath.absolute(v.getYI()); final int z = CheckedMath.absolute(v.getZI()); final int w = CheckedMath.absolute(v.getWI()); out.x = x; out.y = y; out.z = z; out.w = w; return out; } /** * Calculate the absolute values of the elements in vector v, * saving the result to v. * * @param v * The input vector * * @return (abs v.x, abs v.y, abs v.z, abs.w) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I absoluteInPlace( final @Nonnull VectorM4I v) { return VectorM4I.absolute(v, v); } /** * Calculate the element-wise sum of the vectors v0 and * v1, saving the result to out. * * @param v0 * The left input vector * @param v1 * The right input vector * @param out * The output vector * * @return (v0.x + v1.x, v0.y + v1.y, v0.z + v1.z, v0.w + v1.w) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I add( final @Nonnull VectorReadable4I v0, final @Nonnull VectorReadable4I v1, final @Nonnull VectorM4I out) { final int x = CheckedMath.add(v0.getXI(), v1.getXI()); final int y = CheckedMath.add(v0.getYI(), v1.getYI()); final int z = CheckedMath.add(v0.getZI(), v1.getZI()); final int w = CheckedMath.add(v0.getWI(), v1.getWI()); out.x = x; out.y = y; out.z = z; out.w = w; return out; } /** * Calculate the element-wise sum of the vectors v0 and * v1, saving the result to v0. * * @param v0 * The left input vector * @param v1 * The right input vector * * @return (v0.x + v1.x, v0.y + v1.y, v0.z + v1.z, v0.w + v1.w) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I addInPlace( final @Nonnull VectorM4I v0, final @Nonnull VectorReadable4I v1) { return VectorM4I.add(v0, v1, v0); } /** * Calculate the element-wise sum of the vectors v0 and the * element-wise product of v1 and r, saving the * result to out. * * @param v0 * The left input vector * @param v1 * The right input vector * @param out * The output vector * @param r * The scaling value * * @return (v0.x + (v1.x * r), v0.y + (v1.y * r), v0.z + (v1.z * r), v0.w + (v1.w * r)) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I addScaled( final @Nonnull VectorReadable4I v0, final @Nonnull VectorReadable4I v1, final double r, final @Nonnull VectorM4I out) { final int mx = CheckedMath.multiply(v1.getXI(), r); final int my = CheckedMath.multiply(v1.getYI(), r); final int mz = CheckedMath.multiply(v1.getZI(), r); final int mw = CheckedMath.multiply(v1.getWI(), r); final int x = CheckedMath.add(v0.getXI(), mx); final int y = CheckedMath.add(v0.getYI(), my); final int z = CheckedMath.add(v0.getZI(), mz); final int w = CheckedMath.add(v0.getWI(), mw); out.x = x; out.y = y; out.z = z; out.w = w; return out; } /** * Calculate the element-wise sum of the vectors v0 and the * element-wise product of v1 and r, saving the * result to v0. * * @param v0 * The left input vector * @param v1 * The right input vector * @param r * The scaling value * * @return (v0.x + (v1.x * r), v0.y + (v1.y * r), v0.z + (v1.z * r), v0.w + (v1.w * r)) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I addScaledInPlace( final @Nonnull VectorM4I v0, final @Nonnull VectorReadable4I v1, final double r) { return VectorM4I.addScaled(v0, v1, r, v0); } private final static int cast( final double x) { return (int) Math.round(x); } /** * Clamp the elements of the vector v to the range * [minimum .. maximum] inclusive, saving the result to * out. * * @param v * The input vector * @param minimum * The minimum allowed value * @param maximum * The maximum allowed value * @param out * The output vector * * @return A vector with both elements equal to at most maximum * and at least minimum */ public final static @Nonnull VectorM4I clamp( final @Nonnull VectorReadable4I v, final int minimum, final int maximum, final @Nonnull VectorM4I out) { final int x = Math.min(Math.max(v.getXI(), minimum), maximum); final int y = Math.min(Math.max(v.getYI(), minimum), maximum); final int z = Math.min(Math.max(v.getZI(), minimum), maximum); final int w = Math.min(Math.max(v.getWI(), minimum), maximum); out.x = x; out.y = y; out.z = z; out.w = w; return out; } /** * Clamp the elements of the vector v to the inclusive range * given by the corresponding elements in minimum and * maximum, saving the result to out. * * @param v * The input vector * @param minimum * The vector containing the minimum acceptable values * @param maximum * The vector containing the maximum acceptable values * @param out * The output vector * * @return (min(max(v.x, minimum.x), maximum.x), min(max(v.y, minimum.y), maximum.y), min(max(v.z, minimum.z), maximum.z), min(max(v.w, minimum.w), maximum.w)) */ public final static @Nonnull VectorM4I clampByVector( final @Nonnull VectorReadable4I v, final @Nonnull VectorReadable4I minimum, final @Nonnull VectorReadable4I maximum, final @Nonnull VectorM4I out) { final int x = Math.min(Math.max(v.getXI(), minimum.getXI()), maximum.getXI()); final int y = Math.min(Math.max(v.getYI(), minimum.getYI()), maximum.getYI()); final int z = Math.min(Math.max(v.getZI(), minimum.getZI()), maximum.getZI()); final int w = Math.min(Math.max(v.getWI(), minimum.getWI()), maximum.getWI()); out.x = x; out.y = y; out.z = z; out.w = w; return out; } /** * Clamp the elements of the vector v to the inclusive range * given by the corresponding elements in minimum and * maximum, saving the result to v. * * @param v * The input vector * @param minimum * The vector containing the minimum acceptable values * @param maximum * The vector containing the maximum acceptable values * * @return (min(max(v.x, minimum.x), maximum.x), min(max(v.y, minimum.y), maximum.y), min(max(v.z, minimum.z), maximum.z), min(max(v.w, minimum.w), maximum.w)) */ public final static @Nonnull VectorM4I clampByVectorInPlace( final @Nonnull VectorM4I v, final @Nonnull VectorReadable4I minimum, final @Nonnull VectorReadable4I maximum) { return VectorM4I.clampByVector(v, minimum, maximum, v); } /** * Clamp the elements of the vector v to the range * [minimum .. maximum] inclusive, saving the result to * v. * * @param v * The input vector * @param minimum * The minimum allowed value * @param maximum * The maximum allowed value * * @return A vector with both elements equal to at most maximum * and at least minimum, in v */ public final static @Nonnull VectorM4I clampInPlace( final @Nonnull VectorM4I v, final int minimum, final int maximum) { return VectorM4I.clamp(v, minimum, maximum, v); } /** * Clamp the elements of the vector v to the range * [-Infinity .. maximum] inclusive, saving the result to * out. * * @param v * The input vector * @param out * The output vector * @param maximum * The maximum allowed value * * @return A vector with both elements equal to at most maximum */ public final static @Nonnull VectorM4I clampMaximum( final @Nonnull VectorReadable4I v, final int maximum, final @Nonnull VectorM4I out) { final int x = Math.min(v.getXI(), maximum); final int y = Math.min(v.getYI(), maximum); final int z = Math.min(v.getZI(), maximum); final int w = Math.min(v.getWI(), maximum); out.x = x; out.y = y; out.z = z; out.w = w; return out; } /** * Clamp the elements of the vector v to the inclusive range * given by the corresponding elements in maximum, saving the * result to out. * * @param v * The input vector * @param maximum * The vector containing the maximum acceptable values * @param out * The output vector * * @return (min(v.x, maximum.x), min(v.y, maximum.y), min(v.z, maximum.z), min(v.w, maximum.w)) */ public final static @Nonnull VectorM4I clampMaximumByVector( final @Nonnull VectorReadable4I v, final @Nonnull VectorReadable4I maximum, final @Nonnull VectorM4I out) { final int x = Math.min(v.getXI(), maximum.getXI()); final int y = Math.min(v.getYI(), maximum.getYI()); final int z = Math.min(v.getZI(), maximum.getZI()); final int w = Math.min(v.getWI(), maximum.getWI()); out.x = x; out.y = y; out.z = z; out.w = w; return out; } /** * Clamp the elements of the vector v to the inclusive range * given by the corresponding elements in maximum, saving the * result to v. * * @param v * The input vector * @param maximum * The vector containing the maximum acceptable values * * @return (min(v.x, maximum.x), min(v.y, maximum.y), min(v.z, maximum.z), min(v.w, maximum.w)) */ public final static @Nonnull VectorM4I clampMaximumByVectorInPlace( final @Nonnull VectorM4I v, final @Nonnull VectorReadable4I maximum) { return VectorM4I.clampMaximumByVector(v, maximum, v); } /** * Clamp the elements of the vector v to the range * [-Infinity .. maximum] inclusive, saving the result to * v. * * @param v * The input vector * @param maximum * The maximum allowed value * * @return A vector with both elements equal to at most maximum * , in v */ public final static @Nonnull VectorM4I clampMaximumInPlace( final @Nonnull VectorM4I v, final int maximum) { return VectorM4I.clampMaximum(v, maximum, v); } /** * Clamp the elements of the vector v to the range * [minimum .. Infinity] inclusive, saving the result to * out. * * @param v * The input vector * @param out * The output vector * @param minimum * The minimum allowed value * * @return A vector with both elements equal to at least * minimum */ public final static @Nonnull VectorM4I clampMinimum( final @Nonnull VectorReadable4I v, final int minimum, final @Nonnull VectorM4I out) { final int x = Math.max(v.getXI(), minimum); final int y = Math.max(v.getYI(), minimum); final int z = Math.max(v.getZI(), minimum); final int w = Math.max(v.getWI(), minimum); out.x = x; out.y = y; out.z = z; out.w = w; return out; } /** * Clamp the elements of the vector v to the inclusive range * given by the corresponding elements in minimum, saving the * result to out. * * @param v * The input vector * @param out * The output vector * @param minimum * The vector containing the minimum acceptable values * * @return (max(v.x, minimum.x), max(v.y, minimum.y), max(v.z, minimum.z), max(v.w, minimum.w)) */ public final static @Nonnull VectorM4I clampMinimumByVector( final @Nonnull VectorReadable4I v, final @Nonnull VectorReadable4I minimum, final @Nonnull VectorM4I out) { final int x = Math.max(v.getXI(), minimum.getXI()); final int y = Math.max(v.getYI(), minimum.getYI()); final int z = Math.max(v.getZI(), minimum.getZI()); final int w = Math.max(v.getWI(), minimum.getWI()); out.x = x; out.y = y; out.z = z; out.w = w; return out; } /** * Clamp the elements of the vector v to the inclusive range * given by the corresponding elements in minimum, saving the * result to v. * * @param v * The input vector * @param minimum * The vector containing the minimum acceptable values * * @return (max(v.x, minimum.x), max(v.y, minimum.y), max(v.z, minimum.z), max(v.w, minimum.w)) * , in v */ public final static @Nonnull VectorM4I clampMinimumByVectorInPlace( final @Nonnull VectorM4I v, final @Nonnull VectorReadable4I minimum) { return VectorM4I.clampMinimumByVector(v, minimum, v); } /** * Clamp the elements of the vector v to the range * [minimum .. Infinity] inclusive, saving the result to * v. * * @param v * The input vector * @param minimum * The minimum allowed value * * @return A vector with both elements equal to at least * minimum, in v. */ public final static @Nonnull VectorM4I clampMinimumInPlace( final @Nonnull VectorM4I v, final int minimum) { return VectorM4I.clampMinimum(v, minimum, v); } /** * Copy all elements of the vector input to the vector * output. * * @param input * The input vector * @param output * The output vector * * @return output */ public final static @Nonnull VectorM4I copy( final @Nonnull VectorReadable4I input, final @Nonnull VectorM4I output) { output.x = input.getXI(); output.y = input.getYI(); output.z = input.getZI(); output.w = input.getWI(); return output; } /** * Calculate the distance between the two vectors v0 and * v1. * * @param v0 * The left input vector * @param v1 * The right input vector * * @return The distance between the two vectors. * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static int distance( final @Nonnull VectorReadable4I v0, final @Nonnull VectorReadable4I v1) { final @Nonnull VectorM4I vr = new VectorM4I(); return VectorM4I.magnitude(VectorM4I.subtract(v0, v1, vr)); } /** * Calculate the scalar product of the vectors v0 and * v1. * * @param v0 * The left input vector * @param v1 * The right input vector * * @return The scalar product of the two vectors * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static int dotProduct( final @Nonnull VectorReadable4I v0, final @Nonnull VectorReadable4I v1) { final int mx = CheckedMath.multiply(v0.getXI(), v1.getXI()); final int my = CheckedMath.multiply(v0.getYI(), v1.getYI()); final int mz = CheckedMath.multiply(v0.getZI(), v1.getZI()); final int mw = CheckedMath.multiply(v0.getWI(), v1.getWI()); return CheckedMath.add(CheckedMath.add(CheckedMath.add(mx, my), mz), mw); } /** * Linearly interpolate between v0 and v1 by the * amount alpha, saving the result to r. * * The alpha parameter controls the degree of interpolation, * such that: * *
    *
  • interpolateLinear(v0, v1, 0.0, r) -> r = v0
  • *
  • interpolateLinear(v0, v1, 1.0, r) -> r = v1
  • *
* * @param v0 * The left input vector. * @param v1 * The right input vector. * @param alpha * The interpolation value, between 0.0 and * 1.0. * @param r * The result vector. * * @return r * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I interpolateLinear( final @Nonnull VectorReadable4I v0, final @Nonnull VectorReadable4I v1, final double alpha, final @Nonnull VectorM4I r) { final @Nonnull VectorM4I w0 = new VectorM4I(); final @Nonnull VectorM4I w1 = new VectorM4I(); VectorM4I.scale(v0, 1.0 - alpha, w0); VectorM4I.scale(v1, alpha, w1); return VectorM4I.add(w0, w1, r); } /** * Calculate the magnitude of the vector v. * * Correspondingly, magnitude(normalize(v)) == 1.0. * * @param v * The input vector * * @return The magnitude of the input vector * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static int magnitude( final @Nonnull VectorReadable4I v) { return VectorM4I.cast(Math.sqrt(VectorM4I.magnitudeSquared(v))); } /** * Calculate the squared magnitude of the vector v. * * @param v * The input vector * * @return The squared magnitude of the input vector * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static int magnitudeSquared( final @Nonnull VectorReadable4I v) { return VectorM4I.dotProduct(v, v); } /** * Calculate the projection of the vector p onto the vector * q, saving the result in r. * * @return ((dotProduct p q) / magnitudeSquared q) * q * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I projection( final @Nonnull VectorReadable4I p, final @Nonnull VectorReadable4I q, final @Nonnull VectorM4I r) { final int dot = VectorM4I.dotProduct(p, q); final int qms = VectorM4I.magnitudeSquared(q); final int s = dot / qms; return VectorM4I.scale(p, s, r); } /** * Scale the vector v by the scalar r, saving the * result to out. * * @param v * The input vector * @param r * The scaling value * @param out * The output vector * * @return (v.x * r, v.y * r, v.z * r, v.w * r) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I scale( final @Nonnull VectorReadable4I v, final double r, final @Nonnull VectorM4I out) { final int mx = CheckedMath.multiply(v.getXI(), r); final int my = CheckedMath.multiply(v.getYI(), r); final int mz = CheckedMath.multiply(v.getZI(), r); final int mw = CheckedMath.multiply(v.getWI(), r); out.x = mx; out.y = my; out.z = mz; out.w = mw; return out; } /** * Scale the vector v by the scalar r, saving the * result to v. * * @param v * The input vector * @param r * The scaling value * * @return (v.x * r, v.y * r, v.z * r, v.w * r) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I scaleInPlace( final @Nonnull VectorM4I v, final int r) { return VectorM4I.scale(v, r, v); } /** * Subtract the vector v1 from the vector v0, * saving the result to out. * * @param v0 * The left input vector * @param v1 * The right input vector * @param out * The output vector * * @return (v0.x - v1.x, v0.y - v1.y, v0.z - v1.z, v0.w - v1.w) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I subtract( final @Nonnull VectorReadable4I v0, final @Nonnull VectorReadable4I v1, final @Nonnull VectorM4I out) { final int mx = CheckedMath.subtract(v0.getXI(), v1.getXI()); final int my = CheckedMath.subtract(v0.getYI(), v1.getYI()); final int mz = CheckedMath.subtract(v0.getZI(), v1.getZI()); final int mw = CheckedMath.subtract(v0.getWI(), v1.getWI()); out.x = mx; out.y = my; out.z = mz; out.w = mw; return out; } /** * Subtract the vector v1 from the vector v0, * saving the result to v0. * * @param v0 * The left input vector * @param v1 * The right input vector * * @return (v0.x - v1.x, v0.y - v1.y, v0.z - v1.z, v0.w - v1.w) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorM4I subtractInPlace( final @Nonnull VectorM4I v0, final @Nonnull VectorReadable4I v1) { return VectorM4I.subtract(v0, v1, v0); } public int x = 0; public int y = 0; public int z = 0; public int w = 1; /** * Default constructor, initializing the vector with values * [0, 0, 0, 1]. */ public VectorM4I() { } /** * Construct a vector initialized with the given values. */ public VectorM4I( final int x, final int y, final int z, final int w) { this.x = x; this.y = y; this.z = z; this.w = w; } /** * Construct a vector initialized with the values given in the vector * v. */ public VectorM4I( final @Nonnull VectorReadable4I v) { this.x = v.getXI(); this.y = v.getYI(); this.z = v.getZI(); this.w = v.getWI(); } @Override public final boolean equals( final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (this.getClass() != obj.getClass()) { return false; } final @Nonnull VectorM4I other = (VectorM4I) obj; if (this.w != other.w) { return false; } if (this.x != other.x) { return false; } if (this.y != other.y) { return false; } if (this.z != other.z) { return false; } return true; } @Override public final int getWI() { return this.w; } @Override public final int getXI() { return this.x; } @Override public final int getYI() { return this.y; } @Override public final int getZI() { return this.z; } @Override public final int hashCode() { final int prime = 31; int result = 1; result = (prime * result) + this.w; result = (prime * result) + this.x; result = (prime * result) + this.y; result = (prime * result) + this.z; return result; } @Override public final String toString() { final StringBuilder builder = new StringBuilder(); builder.append("[VectorM4I "); builder.append(this.x); builder.append(" "); builder.append(this.y); builder.append(" "); builder.append(this.z); builder.append(" "); builder.append(this.w); builder.append("]"); return builder.toString(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy