/// <summary>Return the maximum element value in 'v'</summary> public static float MaxElement(v4 v) { var i = v.x >= v.y ? v.x : v.y; var j = v.z >= v.w ? v.z : v.w; return(i >= j ? i : j); }
/// <summary>Convert a vector to an align direction</summary> public static EAlignDirection FromAxis(v4 direction) { if (direction == +v4.XAxis) { return(EAlignDirection.PosX); } if (direction == -v4.XAxis) { return(EAlignDirection.NegX); } if (direction == +v4.YAxis) { return(EAlignDirection.PosY); } if (direction == -v4.YAxis) { return(EAlignDirection.NegY); } if (direction == +v4.ZAxis) { return(EAlignDirection.PosZ); } if (direction == -v4.ZAxis) { return(EAlignDirection.NegZ); } return(EAlignDirection.None); }
// Ldr element helpers public static string Position(v4 position, bool newline = false) { return (position == v4.Zero ? string.Empty : position == v4.Origin ? string.Empty : "*o2w{*pos{" + Vec3(position) + "}}" + (newline?"\n":"")); }
public AnchorPoint(Node?node, v4 loc, v4 norm, int uid) { m_node = node; m_location = loc; m_normal = norm; UID = uid; }
/// <summary>Return the index of the maximum element in 'v'</summary> public static int MaxElementIndex(v4 v) { int i = v.x >= v.y ? 0 : 1; int j = v.z >= v.w ? 2 : 3; return(v[i] >= v[j] ? i : j); }
/// <summary>Return the index of the minimum element in 'v'</summary> public static int MinElementIndex(v4 v) { int i = v.x <= v.y ? 0 : 1; int j = v.z <= v.w ? 2 : 3; return(v[i] <= v[j] ? i : j); }
/// <summary>Return the minimum element value in 'v'</summary> public static float MinElement(v4 v) { var i = v.x <= v.y ? v.x : v.y; var j = v.z <= v.w ? v.z : v.w; return(i <= j ? i : j); }
/// <summary>Approximate equal</summary> public static bool FEqlAbsolute(v4 a, v4 b, float tol) { return (FEqlAbsolute(a.x, b.x, tol) && FEqlAbsolute(a.y, b.y, tol) && FEqlAbsolute(a.z, b.z, tol) && FEqlAbsolute(a.w, b.w, tol)); }
public v4 Cross(v4 rhs) { return(new v4( v[1] * rhs.v[2] - v[2] * rhs.v[1], v[2] * rhs.v[0] - v[0] * rhs.v[2], v[0] * rhs.v[1] - v[1] * rhs.v[0], 0)); }
/// <summary>Return the component-wise division 'a/b', or 'def' if 'b' contains zeros</summary> public static v4 Div(v4 a, v4 b, v4 def) { return(new v4( Div(a.x, b.x, def.x), Div(a.y, b.y, def.y), Div(a.z, b.z, def.z), Div(a.w, b.w, def.w))); }
/// <summary>Component-wise absolute value</summary> public static v4 Abs(v4 vec) { return(new v4( Math.Abs(vec.x), Math.Abs(vec.y), Math.Abs(vec.z), Math.Abs(vec.w))); }
/// <summary>Returns a vector perpendicular to 'vec'</summary> public static v4 Perpendicular(v4 vec) { Debug.Assert(vec != v4.Zero, "Cannot make a perpendicular to a zero vector"); var v = Cross(vec, CreateNotParallelTo(vec)); v *= (float)Math.Sqrt(vec.LengthSq / v.LengthSq); return(v); }
/// <summary>Clamp the components of 'vec' within the ranges of 'min' and 'max'</summary> public static v4 Clamp(v4 vec, v4 min, v4 max) { return(new v4( Clamp(vec.x, min.x, max.x), Clamp(vec.y, min.y, max.y), Clamp(vec.z, min.z, max.z), Clamp(vec.w, min.w, max.w))); }
public static v4 Max(v4 x, params v4[] vecs) { foreach (var v in vecs) { x = Max(x, v); } return(x); }
/// <summary>Return a vector containing the maximum components</summary> public static v4 Max(v4 lhs, v4 rhs) { return(new v4( Math.Max(lhs.x, rhs.x), Math.Max(lhs.y, rhs.y), Math.Max(lhs.z, rhs.z), Math.Max(lhs.w, rhs.w))); }
/// <summary>Return the component-wise square root of a vector</summary> public static v4 Sqrt(v4 a) { return(new v4( (float)Math.Sqrt(a.x), (float)Math.Sqrt(a.y), (float)Math.Sqrt(a.z), (float)Math.Sqrt(a.w))); }
/// <summary>Return the axis and angle from a quaternion</summary> public static void AxisAngle(quat quat, out v4 axis, out float angle) { angle = (float)(2.0 * Math.Acos(quat.w)); var s = (float)Math.Sqrt(1.0f - quat.w * quat.w); axis = FEql(s, 0.0f) ? Normalise(new v4(quat.x, quat.y, quat.z, 0.0f)) : new v4(quat.x / s, quat.y / s, quat.z / s, 0.0f); }
/// <summary>Normalise 'vec' by the length of the XYZW components or return 'def' if zero</summary> public static v4 Normalise(v4 vec, v4 def) { if (vec == v4.Zero) { return(def); } var norm = Normalise(vec); return(norm != v4.Zero ? norm : def); }
// Notes: // - A node is a chart element set up for connecting to other node elements via connectors. // - 'Node' has support for text and size, but does not imply a particular shape (2d or 3d). /// <summary>Base node constructor</summary> /// <param name="id">Globally unique id for the element</param> /// <param name="size">The initial dimensions of the node</param> /// <param name="text">The text of the node</param> /// <param name="position">The position of the node on the diagram</param> /// <param name="style">Style properties for the node</param> protected Node(v4 size, Guid id, string text, m4x4?position = null, NodeStyle?style = null) : base(id, text, position) { Text = text; Style = style ?? new NodeStyle(); SizeMax = v4.MaxValue; SizeMin = v4.Zero; Size = size; Connectors = new BindingListEx <Connector>(); TextFormat = new StringFormat(0); }
public override void Execute() { Value = new v4[Count]; for (var i = 0; i < count; ++i) { Value[i] = new v4( random.NextDouble(), random.NextDouble(), random.NextDouble(), random.NextDouble()); } }
/// <summary>Rotate a vector by a quaternion. This is an optimised version of: 'r = q*v*conj(q) for when v.w == 0'</summary> public static v4 Rotate(quat lhs, v4 rhs) { float xx = lhs.x * lhs.x, xy = lhs.x * lhs.y, xz = lhs.x * lhs.z, xw = lhs.x * lhs.w; float yy = lhs.y * lhs.y, yz = lhs.y * lhs.z, yw = lhs.y * lhs.w; float zz = lhs.z * lhs.z, zw = lhs.z * lhs.w; float ww = lhs.w * lhs.w; return(new v4( ww * rhs.x + 2 * yw * rhs.z - 2 * zw * rhs.y + xx * rhs.x + 2 * xy * rhs.y + 2 * xz * rhs.z - zz * rhs.x - yy * rhs.x, 2 * xy * rhs.x + yy * rhs.y + 2 * yz * rhs.z + 2 * zw * rhs.x - zz * rhs.y + ww * rhs.y - 2 * xw * rhs.z - xx * rhs.y, 2 * xz * rhs.x + 2 * yz * rhs.y + zz * rhs.z - 2 * yw * rhs.x - yy * rhs.z + 2 * xw * rhs.y - xx * rhs.z + ww * rhs.z, rhs.w)); }
public void TestOriFromDir() { var dir = new v4(0, 1, 0, 0); { var ori = Math_.OriFromDir(EAxisId.PosZ, dir, v4.ZAxis); Assert.True(dir == ori.z); Assert.True(Math_.IsOrthonormal(ori)); } { var ori = Math_.OriFromDir(EAxisId.NegX, dir); Assert.True(dir == -ori.x); Assert.True(Math_.IsOrthonormal(ori)); } }
public static bool FEqlRelative(v4 a, v4 b, float tol) { var max_a = MaxElement(Abs(a)); var max_b = MaxElement(Abs(b)); if (max_b == 0) { return(max_a < tol); } if (max_a == 0) { return(max_b < tol); } var abs_max_element = Max(max_a, max_b); return(FEqlAbsolute(a, b, tol * abs_max_element)); }
/// <summary>Returns a vector perpendicular to 'vec' favouring 'previous' as the preferred perpendicular</summary> public static v4 Perpendicular(v4 vec, v4 previous) { Debug.Assert(!FEql(vec, v4.Zero), "Cannot make a perpendicular to a zero vector"); // If 'previous' is parallel to 'vec', choose a new perpendicular (includes previous == zero) if (Parallel(vec, previous)) { return(Perpendicular(vec)); } // If 'previous' is still perpendicular, keep it if (FEql(Dot(vec, previous), 0)) { return(previous); } // Otherwise, make a perpendicular that is close to 'previous' var v = Cross(Cross(vec, previous), vec); v *= (float)Math.Sqrt(vec.LengthSq / v.LengthSq); return(v); }
public override void Execute() { try { Length = 0; Size = new v2(); Raw = new byte[] { }; BGRA = new v4[] { }; if (!string.IsNullOrEmpty(Path) && File.Exists(Path)) { // TODO NODE ImageFile.Write // read var bitmapImage = new BitmapImage(new Uri(Path, UriKind.RelativeOrAbsolute)); Size = new v2(bitmapImage.PixelWidth, bitmapImage.PixelHeight); Raw = new byte[bitmapImage.PixelWidth * bitmapImage.PixelHeight * 4]; bitmapImage.CopyPixels(Raw, bitmapImage.PixelWidth * 4, 0); BGRA = new v4[bitmapImage.PixelWidth * bitmapImage.PixelHeight]; for (var i = 0; i < BGRA.Length; i++) { BGRA[i] = new v4( (double)Raw[i * 4 + 0] / 255.0, (double)Raw[i * 4 + 1] / 255.0, (double)Raw[i * 4 + 2] / 255.0, (double)Raw[i * 4 + 3] / 255.0); } } Length = Raw?.Length ?? 0; } catch (Exception ex) { Log.WriteLine(ex.ToString()); } }
/// <summary>Return the angle between two vectors</summary> public static float Angle(v4 lhs, v4 rhs) { return((float)Math.Acos(CosAngle(lhs, rhs))); }
/// <summary>Return the cosine of the angle between two vectors</summary> public static float CosAngle(v4 lhs, v4 rhs) { Debug.Assert(lhs.w == 0 && rhs.w == 0, "CosAngle is intended for 3-vectors"); Debug.Assert(lhs.LengthSq != 0 && rhs.LengthSq != 0, "CosAngle undefined for zero vectors"); return(Clamp(Dot(lhs, rhs) / (float)Math.Sqrt(lhs.LengthSq * rhs.LengthSq), -1f, 1f)); }
/// <summary>Returns a 3 bit bitmask of the octant the vector is in where X = 0x1, Y = 0x2, Z = 0x4</summary> public static uint Octant(v4 vec) { return((uint)(((int)SignF(vec.x >= 0.0f)) | ((int)SignF(vec.y >= 0.0f) << 1) | ((int)SignF(vec.z >= 0.0f) << 2))); }
/// <summary>Returns a vector guaranteed to not be parallel to 'vec'</summary> public static v4 CreateNotParallelTo(v4 vec) { bool x_aligned = Abs(vec.x) > Abs(vec.y) && Abs(vec.x) > Abs(vec.z); return(new v4(SignF(!x_aligned), 0.0f, SignF(x_aligned), vec.w)); }
/// <summary>Linearly interpolate between two vectors</summary> public static v4 Lerp(v4 lhs, v4 rhs, float frac) { return(lhs * (1f - frac) + rhs * (frac)); }