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

com.io7m.jtensors.VectorM4L 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. *

* * @since 5.3.0 */ @NotThreadSafe public class VectorM4L implements VectorReadable4L { /** * 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 VectorM4L absolute( final @Nonnull VectorReadable4L v, final @Nonnull VectorM4L out) { final long x = CheckedMath.absolute(v.getXL()); final long y = CheckedMath.absolute(v.getYL()); final long z = CheckedMath.absolute(v.getZL()); final long w = CheckedMath.absolute(v.getWL()); 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 VectorM4L absoluteInPlace( final @Nonnull VectorM4L v) { return VectorM4L.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 VectorM4L add( final @Nonnull VectorReadable4L v0, final @Nonnull VectorReadable4L v1, final @Nonnull VectorM4L out) { final long x = CheckedMath.add(v0.getXL(), v1.getXL()); final long y = CheckedMath.add(v0.getYL(), v1.getYL()); final long z = CheckedMath.add(v0.getZL(), v1.getZL()); final long w = CheckedMath.add(v0.getWL(), v1.getWL()); 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 VectorM4L addInPlace( final @Nonnull VectorM4L v0, final @Nonnull VectorReadable4L v1) { return VectorM4L.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 VectorM4L addScaled( final @Nonnull VectorReadable4L v0, final @Nonnull VectorReadable4L v1, final double r, final @Nonnull VectorM4L out) { final long mx = CheckedMath.multiply(v1.getXL(), r); final long my = CheckedMath.multiply(v1.getYL(), r); final long mz = CheckedMath.multiply(v1.getZL(), r); final long mw = CheckedMath.multiply(v1.getWL(), r); final long x = CheckedMath.add(v0.getXL(), mx); final long y = CheckedMath.add(v0.getYL(), my); final long z = CheckedMath.add(v0.getZL(), mz); final long w = CheckedMath.add(v0.getWL(), 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 VectorM4L addScaledInPlace( final @Nonnull VectorM4L v0, final @Nonnull VectorReadable4L v1, final double r) { return VectorM4L.addScaled(v0, v1, r, v0); } private final static long cast( final double x) { return 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 VectorM4L clamp( final @Nonnull VectorReadable4L v, final long minimum, final long maximum, final @Nonnull VectorM4L out) { final long x = Math.min(Math.max(v.getXL(), minimum), maximum); final long y = Math.min(Math.max(v.getYL(), minimum), maximum); final long z = Math.min(Math.max(v.getZL(), minimum), maximum); final long w = Math.min(Math.max(v.getWL(), 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 VectorM4L clampByVector( final @Nonnull VectorReadable4L v, final @Nonnull VectorReadable4L minimum, final @Nonnull VectorReadable4L maximum, final @Nonnull VectorM4L out) { final long x = Math.min(Math.max(v.getXL(), minimum.getXL()), maximum.getXL()); final long y = Math.min(Math.max(v.getYL(), minimum.getYL()), maximum.getYL()); final long z = Math.min(Math.max(v.getZL(), minimum.getZL()), maximum.getZL()); final long w = Math.min(Math.max(v.getWL(), minimum.getWL()), maximum.getWL()); 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 VectorM4L clampByVectorInPlace( final @Nonnull VectorM4L v, final @Nonnull VectorReadable4L minimum, final @Nonnull VectorReadable4L maximum) { return VectorM4L.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 VectorM4L clampInPlace( final @Nonnull VectorM4L v, final long minimum, final long maximum) { return VectorM4L.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 VectorM4L clampMaximum( final @Nonnull VectorReadable4L v, final long maximum, final @Nonnull VectorM4L out) { final long x = Math.min(v.getXL(), maximum); final long y = Math.min(v.getYL(), maximum); final long z = Math.min(v.getZL(), maximum); final long w = Math.min(v.getWL(), 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 VectorM4L clampMaximumByVector( final @Nonnull VectorReadable4L v, final @Nonnull VectorReadable4L maximum, final @Nonnull VectorM4L out) { final long x = Math.min(v.getXL(), maximum.getXL()); final long y = Math.min(v.getYL(), maximum.getYL()); final long z = Math.min(v.getZL(), maximum.getZL()); final long w = Math.min(v.getWL(), maximum.getWL()); 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 VectorM4L clampMaximumByVectorInPlace( final @Nonnull VectorM4L v, final @Nonnull VectorReadable4L maximum) { return VectorM4L.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 VectorM4L clampMaximumInPlace( final @Nonnull VectorM4L v, final long maximum) { return VectorM4L.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 VectorM4L clampMinimum( final @Nonnull VectorReadable4L v, final long minimum, final @Nonnull VectorM4L out) { final long x = Math.max(v.getXL(), minimum); final long y = Math.max(v.getYL(), minimum); final long z = Math.max(v.getZL(), minimum); final long w = Math.max(v.getWL(), 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 VectorM4L clampMinimumByVector( final @Nonnull VectorReadable4L v, final @Nonnull VectorReadable4L minimum, final @Nonnull VectorM4L out) { final long x = Math.max(v.getXL(), minimum.getXL()); final long y = Math.max(v.getYL(), minimum.getYL()); final long z = Math.max(v.getZL(), minimum.getZL()); final long w = Math.max(v.getWL(), minimum.getWL()); 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 VectorM4L clampMinimumByVectorInPlace( final @Nonnull VectorM4L v, final @Nonnull VectorReadable4L minimum) { return VectorM4L.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 VectorM4L clampMinimumInPlace( final @Nonnull VectorM4L v, final long minimum) { return VectorM4L.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 VectorM4L copy( final @Nonnull VectorReadable4L input, final @Nonnull VectorM4L output) { output.x = input.getXL(); output.y = input.getYL(); output.z = input.getZL(); output.w = input.getWL(); 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 long distance( final @Nonnull VectorReadable4L v0, final @Nonnull VectorReadable4L v1) { final @Nonnull VectorM4L vr = new VectorM4L(); return VectorM4L.magnitude(VectorM4L.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 long dotProduct( final @Nonnull VectorReadable4L v0, final @Nonnull VectorReadable4L v1) { final long mx = CheckedMath.multiply(v0.getXL(), v1.getXL()); final long my = CheckedMath.multiply(v0.getYL(), v1.getYL()); final long mz = CheckedMath.multiply(v0.getZL(), v1.getZL()); final long mw = CheckedMath.multiply(v0.getWL(), v1.getWL()); 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 VectorM4L interpolateLinear( final @Nonnull VectorReadable4L v0, final @Nonnull VectorReadable4L v1, final double alpha, final @Nonnull VectorM4L r) { final @Nonnull VectorM4L w0 = new VectorM4L(); final @Nonnull VectorM4L w1 = new VectorM4L(); VectorM4L.scale(v0, 1.0 - alpha, w0); VectorM4L.scale(v1, alpha, w1); return VectorM4L.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 long magnitude( final @Nonnull VectorReadable4L v) { return VectorM4L.cast(Math.sqrt(VectorM4L.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 long magnitudeSquared( final @Nonnull VectorReadable4L v) { return VectorM4L.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 VectorM4L projection( final @Nonnull VectorReadable4L p, final @Nonnull VectorReadable4L q, final @Nonnull VectorM4L r) { final long dot = VectorM4L.dotProduct(p, q); final long qms = VectorM4L.magnitudeSquared(q); final long s = dot / qms; return VectorM4L.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 VectorM4L scale( final @Nonnull VectorReadable4L v, final double r, final @Nonnull VectorM4L out) { final long mx = CheckedMath.multiply(v.getXL(), r); final long my = CheckedMath.multiply(v.getYL(), r); final long mz = CheckedMath.multiply(v.getZL(), r); final long mw = CheckedMath.multiply(v.getWL(), 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 VectorM4L scaleInPlace( final @Nonnull VectorM4L v, final long r) { return VectorM4L.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 VectorM4L subtract( final @Nonnull VectorReadable4L v0, final @Nonnull VectorReadable4L v1, final @Nonnull VectorM4L out) { final long mx = CheckedMath.subtract(v0.getXL(), v1.getXL()); final long my = CheckedMath.subtract(v0.getYL(), v1.getYL()); final long mz = CheckedMath.subtract(v0.getZL(), v1.getZL()); final long mw = CheckedMath.subtract(v0.getWL(), v1.getWL()); 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 VectorM4L subtractInPlace( final @Nonnull VectorM4L v0, final @Nonnull VectorReadable4L v1) { return VectorM4L.subtract(v0, v1, v0); } public long x = 0; public long y = 0; public long z = 0; public long w = 1; /** * Default constructor, initializing the vector with values * [0, 0, 0, 1]. */ public VectorM4L() { } /** * Construct a vector initialized with the given values. */ public VectorM4L( final long x, final long y, final long z, final long 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 VectorM4L( final @Nonnull VectorReadable4L v) { this.x = v.getXL(); this.y = v.getYL(); this.z = v.getZL(); this.w = v.getWL(); } @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 VectorM4L other = (VectorM4L) 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 long getWL() { return this.w; } @Override public final long getXL() { return this.x; } @Override public final long getYL() { return this.y; } @Override public final long getZL() { return this.z; } @Override public final int hashCode() { final long prime = 31; long result = 1; result = (prime * result) + this.w; result = (prime * result) + this.x; result = (prime * result) + this.y; result = (prime * result) + this.z; return (int) result; } @Override public final String toString() { final StringBuilder builder = new StringBuilder(); builder.append("[VectorM4L "); 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