001/* 002 * Renderer 4. The MIT License. 003 * Copyright (c) 2022 rlkraft@pnw.edu 004 * See LICENSE for details. 005*/ 006 007package renderer.scene; 008 009/** 010 A {@code Vector} object holds three doubles, which makes it a vector 011 in 3-dimensional space. 012*/ 013public final class Vector 014{ 015 public final double x, y, z; 016 017 /** 018 Construct a new {@code Vector} using the given x, y, and z coordinates. 019 020 @param x x-coordinate of the new {@code Vector} 021 @param y y-coordinate of the new {@code Vector} 022 @param z z-coordinate of the new {@code Vector} 023 */ 024 public Vector(final double x, final double y, final double z) 025 { 026 this.x = x; 027 this.y = y; 028 this.z = z; 029 } 030 031 032 /** 033 Construct a new {@code Vector} from a {@link Vertex}. 034 035 @param v {@link Vertex} object to convert into a {@code Vector} 036 */ 037 public Vector(final Vertex v) 038 { 039 this(v.x, v.y, v.z); 040 } 041 042 043 /** 044 The dot-product of two {@code Vector}s returns a scalar. 045 046 @param v {@code Vector} object to multiply with this {@code Vector} 047 @return a double that is the dot-product of this {@code Vector} and {@code v} 048 */ 049 public double dotProduct(final Vector v) 050 { 051 return (x * v.x) + (y * v.y) + (z * v.z); 052 } 053 054 055 /** 056 The cross-product of two {@code Vector}s returns a (new) {@code Vector}. 057 058 @param v {@code Vector} object to multiply with this {@code Vector} 059 @return a new {@code Vector} object that is the cross-product of this {@code Vector} and {@code v} 060 */ 061 public Vector crossProduct(final Vector v) 062 { 063 return new Vector(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); 064 } 065 066 067 /** 068 A scalar times a {@code Vector} returns a (new) {@code Vector}. 069 070 @param s number to multiply this {@code Vector} by 071 @return a new {@code Vector} object that is the scalar times this {@code Vector} 072 */ 073 public Vector times(final double s) // return s * this 074 { 075 return new Vector(s*x, s*y, s*z); 076 } 077 078 079 /** 080 A {@code Vector} plus a {@code Vector} returns a (new) {@code Vector}. 081 082 @param v {@code Vector} object to add to this {@code Vector} 083 @return a new {@code Vector} object that is the sum of this {@code Vector} and {@code v} 084 */ 085 public Vector plus(final Vector v) // return this + v 086 { 087 return new Vector(x + v.x, y + v.y, z + v.z); 088 } 089 090 091 /** 092 A {@code Vector} minus a {@code Vector} returns a (new) {@code Vector}. 093 094 @param v {@code Vector} object to subtract from this {@code Vector} 095 @return a new {@code Vector} object that is this {@code Vector} minus {@code v} 096 */ 097 public Vector minus(final Vector v) // return this - v 098 { 099 return new Vector(x - v.x, y - v.y, z - v.z); 100 } 101 102 103 /** 104 Return the normalized version of this {@code Vector}. 105 <p> 106 That is, return the {@code Vector} with length 1 that 107 points in the same direction as this {@code Vector}. 108 109 @return a new {@code Vector} that has length one and has the same direction as this {@code Vector} 110 */ 111 public Vector normalize() // return this / |this| 112 { 113 final double norm = Math.sqrt( x*x + y*y + z*z ); 114 return new Vector(x/norm, y/norm, z/norm); 115 } 116 117 118 /** 119 A {@code Vector} plus a {@link Vertex} returns a (new) {@link Vertex}. 120 <p> 121 The vector translates the vertex to a new location. 122 123 @param v {@link Vertex} object to add to this {@code Vector} 124 @return a new {@link Vertex} object that is the translation of {@code v} by this {@code Vector} 125 */ 126 public Vertex plus(final Vertex v) 127 { 128 return new Vertex(x + v.x, y + v.y, z + v.z); 129 } 130 131 132 /** 133 For debugging. 134 135 @return {@link String} representation of this {@code Vector} object 136 */ 137 @Override 138 public String toString() 139 { 140 final int precision = 5; // the default precision for the format string 141 return toString(precision); 142 } 143 144 145 /** 146 For debugging. 147 <p> 148 Allow the precision of the formatted output to be specified. 149 150 @param precision precision value for the format string 151 @return {@link String} representation of this {@code Vector} object 152 */ 153 public String toString(final int precision) 154 { 155 final int iWidth = 3; // default width of integer part of the format string 156 return toString(precision, iWidth); 157 } 158 159 160 /** 161 For debugging. 162 <p> 163 Allow the precision and width of the formatted output to be specified. 164 By width, we mean the width of the integer part of each number. 165 166 @param precision precision value for the format string 167 @param iWidth width of the integer part of the format string 168 @return {@link String} representation of this {@code Vector} object 169 */ 170 public String toString(final int precision, final int iWidth) 171 { 172 // Here is one way to get programmable precision and width. 173 final int p = precision; // the precision for the following format string 174 final int t = p + iWidth + 2; // the width for the following format string 175 final String format = "[x,y,z] = [% "+t+"."+p+"f % "+t+"."+p+"f % "+t+"."+p+"f]"; 176 return String.format(format, x, y, z); 177 } 178}