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

com.io7m.jtensors.VectorI2I 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.Immutable;

import com.io7m.jaux.CheckedMath;

/**
 * 

* A two-dimensional immutable vector type with integer elements. *

*

* Values of this type are immutable and can therefore be safely accessed from * multiple threads. *

*/ @Immutable public class VectorI2I implements VectorReadable2I { /** * The zero vector. */ public static final @Nonnull VectorI2I ZERO = new VectorI2I(0, 0); /** * Calculate the absolute values of the elements in vector v. * * @param v * The input vector * * @return (abs v.x, abs v.y, abs v.z) * * @since 5.0.0 * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorI2I absolute( final @Nonnull VectorReadable2I v) { final int x = CheckedMath.absolute(v.getXI()); final int y = CheckedMath.absolute(v.getYI()); return new VectorI2I(x, y); } /** * Calculate the element-wise sum of the vectors v0 and * v1. * * @param v0 * The left input vector * @param v1 * The right input vector * * @return (v0.x + v1.x, v0.y + v1.y) * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorI2I add( final @Nonnull VectorReadable2I v0, final @Nonnull VectorReadable2I v1) { final int x = CheckedMath.add(v0.getXI(), v1.getXI()); final int y = CheckedMath.add(v0.getYI(), v1.getYI()); return new VectorI2I(x, y); } /** * Calculate the element-wise sum of the vectors v0 and the * element-wise product of v1 and r. * * @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)) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorI2I addScaled( final @Nonnull VectorReadable2I v0, final @Nonnull VectorReadable2I v1, final double r) { final int mx = CheckedMath.multiply(v1.getXI(), r); final int my = CheckedMath.multiply(v1.getYI(), r); final int x = CheckedMath.add(v0.getXI(), mx); final int y = CheckedMath.add(v0.getYI(), my); return new VectorI2I(x, y); } /** * Calculate the angle between the vectors v0 and * v1 in radians. * * @param v0 * The left input vector * @param v1 * The right input vector * * @return The angle between the two vectors, in radians. */ public final static double angle( final @Nonnull VectorReadable2I v0, final @Nonnull VectorReadable2I v1) { final double m0 = VectorI2I.magnitude(v0); final double m1 = VectorI2I.magnitude(v1); return Math.acos(VectorI2I.dotProduct(v0, v1) / (m0 * m1)); } 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. * * @param v * The input vector * @param minimum * The minimum allowed value * @param maximum * The maximum allowed value * @since 5.0.0 * @return A vector with both elements equal to at most maximum * and at least minimum */ public final static @Nonnull VectorI2I clamp( final @Nonnull VectorReadable2I v, final int minimum, final int maximum) { final int x = Math.min(Math.max(v.getXI(), minimum), maximum); final int y = Math.min(Math.max(v.getYI(), minimum), maximum); return new VectorI2I(x, y); } /** * Clamp the elements of the vector v to the inclusive range * given by the corresponding elements in minimum and * maximum. * * @param v * The input vector * @param minimum * The vector containing the minimum acceptable values * @param maximum * The vector containing the maximum acceptable values * @since 5.0.0 * @return (min(max(v.x, minimum.x), maximum.x), min(max(v.y, minimum.y), maximum.y)) */ public final static @Nonnull VectorI2I clampByVector( final @Nonnull VectorReadable2I v, final @Nonnull VectorReadable2I minimum, final @Nonnull VectorReadable2I maximum) { 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()); return new VectorI2I(x, y); } /** * Clamp the elements of the vector v to the range * [-Infinity .. maximum] inclusive. * * @param v * The input vector * @param maximum * The maximum allowed value * @since 5.0.0 * @return A vector with both elements equal to at most maximum */ public final static @Nonnull VectorI2I clampMaximum( final @Nonnull VectorReadable2I v, final int maximum) { final int x = Math.min(v.getXI(), maximum); final int y = Math.min(v.getYI(), maximum); return new VectorI2I(x, y); } /** * Clamp the elements of the vector v to the inclusive range * given by the corresponding elements in maximum. * * @param v * The input vector * @param maximum * The vector containing the maximum acceptable values * @since 5.0.0 * @return (min(v.x, maximum.x), min(v.y, maximum.y)) */ public final static @Nonnull VectorI2I clampMaximumByVector( final @Nonnull VectorReadable2I v, final @Nonnull VectorReadable2I maximum) { final int x = Math.min(v.getXI(), maximum.getXI()); final int y = Math.min(v.getYI(), maximum.getYI()); return new VectorI2I(x, y); } /** * Clamp the elements of the vector v to the range * [minimum .. Infinity] inclusive. * * @param v * The input vector * @param minimum * The minimum allowed value * @since 5.0.0 * @return A vector with both elements equal to at least * minimum */ public final static @Nonnull VectorI2I clampMinimum( final @Nonnull VectorReadable2I v, final int minimum) { final int x = Math.max(v.getXI(), minimum); final int y = Math.max(v.getYI(), minimum); return new VectorI2I(x, y); } /** * Clamp the elements of the vector v to the inclusive range * given by the corresponding elements in minimum. * * @param v * The input vector * @param minimum * The vector containing the minimum acceptable values * @since 5.0.0 * * @return (max(v.x, minimum.x), max(v.y, minimum.y)) */ public final static @Nonnull VectorI2I clampMinimumByVector( final @Nonnull VectorReadable2I v, final @Nonnull VectorReadable2I minimum) { final int x = Math.max(v.getXI(), minimum.getXI()); final int y = Math.max(v.getYI(), minimum.getYI()); return new VectorI2I(x, y); } /** * 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. * * @since 5.0.0 * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static int distance( final @Nonnull VectorReadable2I v0, final @Nonnull VectorReadable2I v1) { return VectorI2I.magnitude(VectorI2I.subtract(v0, v1)); } /** * 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 * * @since 5.0.0 * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static int dotProduct( final @Nonnull VectorReadable2I v0, final @Nonnull VectorReadable2I v1) { final int mx = CheckedMath.multiply(v0.getXI(), v1.getXI()); final int my = CheckedMath.multiply(v0.getYI(), v1.getYI()); return CheckedMath.add(mx, my); } /** * Linearly interpolate between v0 and v1 by the * amount alpha. * * 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. * * @since 5.0.0 * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer * overflow. */ public final static @Nonnull VectorI2I interpolateLinear( final @Nonnull VectorReadable2I v0, final @Nonnull VectorReadable2I v1, final double alpha) { final VectorI2I w0 = VectorI2I.scale(v0, 1.0 - alpha); final VectorI2I w1 = VectorI2I.scale(v1, alpha); return VectorI2I.add(w0, w1); } /** * 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 * * @since 5.0.0 * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static int magnitude( final @Nonnull VectorReadable2I v) { return VectorI2I.cast(Math.sqrt(VectorI2I.magnitudeSquared(v))); } /** * Calculate the squared magnitude of the vector v. * * @param v * The input vector * * @return The squared magnitude of the input vector * * @since 5.0.0 * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static int magnitudeSquared( final @Nonnull VectorReadable2I v) { return VectorI2I.dotProduct(v, v); } /** * Calculate the projection of the vector p onto the vector * q. * * @return ((dotProduct p q) / magnitudeSquared q) * q * @since 5.0.0 * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorI2I projection( final @Nonnull VectorReadable2I p, final @Nonnull VectorReadable2I q) { final int dot = VectorI2I.dotProduct(p, q); final int qms = VectorI2I.magnitudeSquared(q); final int s = dot / qms; return VectorI2I.scale(p, s); } /** * Scale the vector v by the scalar r. * * @param v * The input vector * @param r * The scaling value * * @return (v.x * r, v.y * r) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorI2I scale( final @Nonnull VectorReadable2I v, final double r) { final int mx = CheckedMath.multiply(v.getXI(), r); final int my = CheckedMath.multiply(v.getYI(), r); return new VectorI2I(mx, my); } /** * Subtract the vector v1 from the vector v0. * * @param v0 * The left input vector * @param v1 * The right input vector * * @return (v0.x - v1.x, v0.y - v1.y) * * @throws ArithmeticException * Iff an internal arithmetic operation causes an integer overflow */ public final static @Nonnull VectorI2I subtract( final @Nonnull VectorReadable2I v0, final @Nonnull VectorReadable2I v1) { final int x = CheckedMath.subtract(v0.getXI(), v1.getXI()); final int y = CheckedMath.subtract(v0.getYI(), v1.getYI()); return new VectorI2I(x, y); } public final int x; public final int y; /** * Default constructor, initializing the vector with values * [0, 0, 0]. */ public VectorI2I() { this.x = 0; this.y = 0; } /** * Construct a vector initialized with the given values. */ public VectorI2I( final int x, final int y) { this.x = x; this.y = y; } /** * Construct a vector initialized with the values given in the vector * v. */ public VectorI2I( final @Nonnull VectorReadable2I v) { this.x = v.getXI(); this.y = v.getYI(); } @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 VectorI2I other = (VectorI2I) obj; if (this.x != other.x) { return false; } if (this.y != other.y) { return false; } return true; } @Override public final int getXI() { return this.x; } @Override public final int getYI() { return this.y; } @Override public final int hashCode() { final int prime = 31; int result = 1; result = (prime * result) + this.x; result = (prime * result) + this.y; return result; } @Override public final String toString() { final StringBuilder builder = new StringBuilder(); builder.append("[VectorI2I "); builder.append(this.x); builder.append(" "); builder.append(this.y); builder.append("]"); return builder.toString(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy