// // (C) Copyright 2003-2019 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // using System; using System.Collections.Generic; using System.Text; namespace Revit.SDK.Samples.ObjectViewer.CS { /// /// Point class use to store point coordinate value /// and get the value via (x, y ,z)property /// public struct Vector { //private member private double m_x; //x coordinate of vector private double m_y; //y coordinate of vector private double m_z; //z coordinate of vector /// /// Property to get X coordinate /// public double X { get { return m_x; } set { m_x = value; } } /// /// Property to get Y coordinate /// public double Y { get { return m_y; } set { m_y = value; } } /// /// Property to get Z coordinate /// public double Z { get { return m_z; } set { m_z = value; } } /// /// Property to get x, y, z coordinate bu index 1, 2, 3 /// public double this[int index] { get { switch (index) { case 0: return m_x; case 1: return m_y; case 2: return m_z; default: throw new ArgumentOutOfRangeException(); } } set { switch (index) { case 0: m_x = value; break; case 1: m_y = value; break; case 2: m_z = value; break; default: throw new ArgumentOutOfRangeException(); } } } /// /// copy constructor /// public Vector(Vector rhs) { m_x = rhs.X; m_y = rhs.Y; m_z = rhs.Z; } /// /// constructor /// /// x coordinate of point /// y coordinate of point /// z coordinate of point public Vector(double x, double y, double z) { m_x = x; m_y = y; m_z = z; } /// /// get Normal by vector /// public Vector GetNormal() { Vector direct = new Vector(); double len = GetLength(); if (len < double.Epsilon) { return new Vector(); } direct.X = m_x / len; direct.Y = m_y / len; direct.Z = m_z / len; return direct; } /// /// add two vector /// /// first vector /// second vector /// add two vector public static Vector operator +(Vector lhs, Vector rhs) { Vector result = new Vector(lhs); result.X += rhs.X; result.Y += rhs.Y; result.Z += rhs.Z; return result; } /// /// subtraction of two vector /// /// first vector /// second vector /// subtraction of two vector public static Vector operator -(Vector lhs, Vector rhs) { Vector result = new Vector(lhs); result.X -= rhs.X; result.Y -= rhs.Y; result.Z -= rhs.Z; return result; } /// /// negative of vector /// /// vector /// negative of vector public static Vector operator -(Vector lhs) { Vector result = new Vector(lhs); result.X = -lhs.X; result.Y = -lhs.Y; result.Z = -lhs.Z; return result; } /// /// get normal vector of two vector /// /// first vector /// second vector /// normal vector of two vector public static Vector operator &(Vector lhs, Vector rhs) { double v1 = lhs.X; double v2 = lhs.Y; double v3 = lhs.Z; double u1 = rhs.X; double u2 = rhs.Y; double u3 = rhs.Z; double x = v2 * u3 - v3 * u2; double y = v3 * u1 - v1 * u3; double z = v1 * u2 - v2 * u1; return new Vector(x, y, z); } /// /// get cross vector of two vector /// /// first vector /// second vector /// cross vector of two vector public static double operator *(Vector lhs, Vector rhs) { return lhs.X * rhs.X + lhs.Y * rhs.Y + lhs.Z * rhs.Z; } /// /// get vector multiply by an double value /// /// vector /// double value /// vector multiply by an double value public static Vector operator *(Vector lhs, double rhs) { return new Vector(lhs.X * rhs, lhs.Y * rhs, lhs.Z * rhs); } /// /// estimate whether two are unequal /// /// first vector /// second vector /// whether two are unequal public static bool operator !=(Vector lhs, Vector rhs) { return !IsEqual(lhs, rhs); } /// /// estimate whether two are equal /// /// first vector /// second vector /// whether two are equal public static bool operator ==(Vector lhs, Vector rhs) { return IsEqual(lhs, rhs); } /// /// get the length of vector /// /// vector /// length of vector public static double operator ~(Vector lhs) { return lhs.GetLength(); } /// /// get vector divided by an double value /// /// vector /// double value /// vector divided by an double value public static Vector operator /(Vector lhs, double rhs) { return new Vector(lhs.m_x / rhs, lhs.m_y / rhs, lhs.m_z / rhs); } /// /// get angle of two vector /// /// first vector /// second vector /// /// indicate whether get the acute angle of two angles between two vectors /// /// angle of two vector public static double GetAngleOf2Vectors(Vector lhs, Vector rhs, bool acuteAngleDesired) { double angle = Math.Acos(lhs.GetNormal() * rhs.GetNormal()); if (acuteAngleDesired && angle > Math.PI / 2) { angle = Math.PI - angle; } return angle; } /// /// estimate whether two are equal /// /// object which compare with /// whether two are equal public override bool Equals(object obj) { try { Vector rhs = (Vector)obj; return IsEqual(this, rhs); } catch { } return false; } /// /// Get HashCode /// public override int GetHashCode() { return m_x.GetHashCode() ^ m_y.GetHashCode() ^ m_z.GetHashCode(); } /// /// Get Length of vector /// public double GetLength() { return Math.Sqrt(m_x*m_x + m_y*m_y + m_z*m_z); } /// /// estimate whether two vector are equal /// /// first vector /// second vector /// whether two are equal private static bool IsEqual(Vector lhs, Vector rhs) { if (lhs.X == rhs.X && lhs.X == rhs.X && lhs.X == rhs.X) { return true; } else { return false; } } /// /// Cross multiply 2 3*3 Matrix /// /// /// /// result 3*3 Matrix public static Vector[] MultiCross3X3Matrix(Vector[] m1, Vector[] m2) { Vector[] result = new Vector[3]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { switch (j) { case 0: (result[i]).X += (m1[i])[k] * (m2[k])[j]; break; case 1: (result[i]).Y += (m1[i])[k] * (m2[k])[j]; break; case 2: (result[i]).Z += (m1[i])[k] * (m2[k])[j]; break; default: break; } } } } return result; } } }