static public double FindTilt(EPObj.MemorySafe_CartVect normalVector) { double calculatedTilt = -999; //may need to also take into account other factors that, at this stage, seem to not be important //building Direction of Relative North //zone Direction of Relative North //GlobalGeometryRules coordinate system //I may need to know this in the future then rotate the axis vectors I am making below //x-axis [1 0 0] points east, y-axis [0 1 0] points north, z-axis[0 0 1] points up to the sky //alignment with y axis means north pointing, alignment with z-axis means it is pointing up to the sky (like a flat roof) double nX = 0; double nY = 1; double nZ = 0; EPObj.MemorySafe_CartVect northVector = new EPObj.MemorySafe_CartVect(nX, nY, nZ); double uX = 0; double uY = 0; double uZ = 1; EPObj.MemorySafe_CartVect upVector = new EPObj.MemorySafe_CartVect(uX, uY, uZ); //rotate the axis vectors for the future //ensure the vector passed into the function is a unit vector normalVector = EPObj.UnitVector(normalVector); //get tilt: cross product of normal vector and upVector //since parallel and anti parallel vectors will return the same cross product [0,0,0] I need to filter out the antiparalll case if (normalVector.X == upVector.X * -1 && normalVector.Y == upVector.Y * -1 && normalVector.Z == upVector.Z * -1) { calculatedTilt = 180; return(calculatedTilt); } else { EPObj.MemorySafe_CartVect tiltVector = EPObj.CrossProduct(normalVector, upVector); double tiltVectorMagnitude = EPObj.VectorMagnitude(tiltVector); calculatedTilt = Math.Round(Math.Asin(tiltVectorMagnitude) * 180 / Math.PI, 2); return(calculatedTilt); } }
public static double FindTilt(EPObj.MemorySafe_CartVect normalVector) { double calculatedTilt = -999; //may need to also take into account other factors that, at this stage, seem to not be important //building Direction of Relative North //zone Direction of Relative North //GlobalGeometryRules coordinate system //I may need to know this in the future then rotate the axis vectors I am making below //x-axis [1 0 0] points east, y-axis [0 1 0] points north, z-axis[0 0 1] points up to the sky //alignment with y axis means north pointing, alignment with z-axis means it is pointing up to the sky (like a flat roof) double nX = 0; double nY = 1; double nZ = 0; EPObj.MemorySafe_CartVect northVector = new EPObj.MemorySafe_CartVect(nX, nY, nZ); double uX = 0; double uY = 0; double uZ = 1; EPObj.MemorySafe_CartVect upVector = new EPObj.MemorySafe_CartVect(uX, uY, uZ); //rotate the axis vectors for the future //ensure the vector passed into the function is a unit vector normalVector = EPObj.UnitVector(normalVector); //get tilt: cross product of normal vector and upVector //since parallel and anti parallel vectors will return the same cross product [0,0,0] I need to filter out the antiparalll case if (normalVector.X == upVector.X * -1 && normalVector.Y == upVector.Y * -1 && normalVector.Z == upVector.Z * -1) { calculatedTilt = 180; return calculatedTilt; } else { EPObj.MemorySafe_CartVect tiltVector = EPObj.CrossProduct(normalVector, upVector); double tiltVectorMagnitude = EPObj.VectorMagnitude(tiltVector); calculatedTilt = Math.Round(Math.Asin(tiltVectorMagnitude) * 180 / Math.PI, 2); return calculatedTilt; } }
public static double FindAzimuth(EPObj.MemorySafe_CartVect normalVector) { double calculatedAzimuth = -999; //may need to also take into account other factors that, at this stage, seem to not be important //building Direction of Relative North //zone Direction of Relative North //GlobalGeometryRules coordinate system //I may need to know this in the future then rotate the axis vectors I am making below //x-axis [1 0 0] points east, y-axis [0 1 0] points north, z-axis[0 0 1] points up to the sky //alignment with y axis means north pointing, alignment with z-axis means it is pointing up to the sky (like a flat roof) EPObj.MemorySafe_CartVect northVector = new EPObj.MemorySafe_CartVect(0,1,0); EPObj.MemorySafe_CartVect southVector = new EPObj.MemorySafe_CartVect(0,-1,0); EPObj.MemorySafe_CartVect eastVector = new EPObj.MemorySafe_CartVect(1,0,0); EPObj.MemorySafe_CartVect westVector = new EPObj.MemorySafe_CartVect(-1,0,0); EPObj.MemorySafe_CartVect upVector = new EPObj.MemorySafe_CartVect(0,0,1); //rotate the axis vectors for the future //ensure the vector passed into the function is a unit vector normalVector = EPObj.UnitVector(normalVector); //get X-Y projection of the normal vector //normalVector.Z = 0; //get azimuth: cross product of normal vector x-y projection and northVector //1st quadrant if ((normalVector.X == 0 && normalVector.Y == 1) || (normalVector.X == 1 && normalVector.Y == 0) || (normalVector.X > 0 && normalVector.Y > 0)) { //get azimuth: cross product of normal vector x-y projection and northVector EPObj.MemorySafe_CartVect azVector = EPObj.CrossProduct(normalVector, northVector); double azVectorMagnitude = EPObj.VectorMagnitude(azVector); //modification for when the vector is in different quadrants calculatedAzimuth = Math.Round(Math.Asin(azVectorMagnitude) * 180 / Math.PI, 2); return calculatedAzimuth; } //second quadrant else if (normalVector.X < 0 && normalVector.Y > 0) { EPObj.MemorySafe_CartVect azVector = EPObj.CrossProduct(normalVector, westVector); double azVectorMagnitude = EPObj.VectorMagnitude(azVector); //modification for when the vector is in different quadrants calculatedAzimuth = Math.Round(Math.Asin(azVectorMagnitude) * 180 / Math.PI, 2) + 270; return calculatedAzimuth; } //quadrant 3 else if ((normalVector.X < 0 && normalVector.Y < 0) || (normalVector.X == -1 && normalVector.Y == 0)) { EPObj.MemorySafe_CartVect azVector = EPObj.CrossProduct(normalVector, southVector); double azVectorMagnitude = EPObj.VectorMagnitude(azVector); //modification for when the vector is in different quadrants calculatedAzimuth = Math.Round(Math.Asin(azVectorMagnitude) * 180 / Math.PI, 2) + 180; return calculatedAzimuth; } //quadrant 4 else if ((normalVector.X > 0 && normalVector.Y < 0) || (normalVector.X == 0 && normalVector.Y == -1)) { EPObj.MemorySafe_CartVect azVector = EPObj.CrossProduct(normalVector, eastVector); double azVectorMagnitude = EPObj.VectorMagnitude(azVector); //modification for when the vector is in different quadrants calculatedAzimuth = Math.Round(Math.Asin(azVectorMagnitude) * 180 / Math.PI, 2) + 90; return calculatedAzimuth; } //this will happen to vectors that point straight down or straight up because we are only interested in the X-Y projection and set the Z to zero anyways else if (normalVector.X == 0 && normalVector.Y == 0) { calculatedAzimuth = 0; return calculatedAzimuth; } //get the return calculatedAzimuth; }
static public Dictionary <string, double> GetWidthandHeight(EPObj.MemorySafe_Surface epsurface, surfaceTypeEnum surftype) { Dictionary <string, double> WH = new Dictionary <string, double>(); List <EPObj.MemorySafe_CartCoord> coords = epsurface.SurfaceCoords; //we use a very simple algorithm where we find the area and the max height //we divide the area by the max height, and this is our width. //this helps us cover the case of non-vertical surfaces, and polygons that //are not rectangles double width = 0; double height = 0; for (int i = 0; i < (coords.Count() - 1); i++) { double dx = Math.Abs(coords[i].X - coords[i + 1].X); double dy = Math.Abs(coords[i].Y - coords[i + 1].Y); double dz = Math.Abs(coords[i].Z - coords[i + 1].Z); //get the height if (surftype == surfaceTypeEnum.ExteriorWall || surftype == surfaceTypeEnum.InteriorWall || surftype == surfaceTypeEnum.UndergroundWall) { if (dz == 0) { continue; } else { if (dx == 0 && dy == 0) { if (dz > height) { height = dz; } else { continue; } } else { //can you prove this somehow? double dist = Math.Sqrt(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)) + Math.Pow(dz, 2)); if (dist > height) { height = dist; } else { continue; } } } } else { if (dz == 0) { double dist = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)); if (dist > height) { height = dist; } else { continue; } } else //it is tilted { double dist = Math.Sqrt(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)) + Math.Pow(dz, 2)); if (dist > height) { height = dist; } else { continue; } } } //this simplifies the definition of width and area greatly double area = EPObj.GetAreaofSurface(epsurface); if (height != 0) { width = area / height; } } WH.Add("width", width); WH.Add("height", height); return(WH); }
public static Surface SetUpSurfaceFromIDF(EPObj.MemorySafe_Surface epsurface, PlanarGeometry pg) { Surface retsurface = new Surface(); retsurface.PlanarGeometry = pg; if (epsurface._sunExposureVar == "SunExposed") { retsurface.AdjacentSpaceId = new AdjacentSpaceId[1]; if (epsurface.tilt > 45 && epsurface.tilt < 135) { Dictionary<string, double> WH = new Dictionary<string, double>(); //it can be considered an exterior wall retsurface.surfaceType = surfaceTypeEnum.ExteriorWall; retsurface.constructionIdRef = "something"; retsurface.Name = epsurface.name; AdjacentSpaceId adj = new AdjacentSpaceId(); adj.spaceIdRef = epsurface.zoneName; retsurface.AdjacentSpaceId[0] = adj; RectangularGeometry rg = new RectangularGeometry(); rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth); //find lower left hand corner of exterior wall //for now, we will just arbitrarily choose a point rg.CartesianPoint = pg.PolyLoop.Points[0]; rg.Tilt = gb.FormatDoubleToString(epsurface.tilt); //get width and height WH = GetWidthandHeight(epsurface, retsurface.surfaceType); rg.Width = gb.FormatDoubleToString(WH["width"]); rg.Height = gb.FormatDoubleToString(WH["height"]); retsurface.RectangularGeometry = rg; retsurface.PlanarGeometry = pg; retsurface.exposedToSunField = true; } //it can be a roof else if (epsurface.tilt >= 0 && epsurface.tilt <= 45) { Dictionary<string, double> WH = new Dictionary<string, double>(); //it can be considered an exterior wall retsurface.surfaceType = surfaceTypeEnum.Roof; retsurface.constructionIdRef = "something"; retsurface.Name = epsurface.name; AdjacentSpaceId adj = new AdjacentSpaceId(); adj.spaceIdRef = epsurface.zoneName; retsurface.AdjacentSpaceId[0] = adj; RectangularGeometry rg = new RectangularGeometry(); rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth); //find lower left hand corner of exterior wall //for now, we will just arbitrarily choose a point rg.CartesianPoint = pg.PolyLoop.Points[0]; rg.Tilt = gb.FormatDoubleToString(epsurface.tilt); //get width and height WH = GetWidthandHeight(epsurface, retsurface.surfaceType); rg.Width = gb.FormatDoubleToString(WH["width"]); rg.Height = gb.FormatDoubleToString(WH["height"]); retsurface.RectangularGeometry = rg; retsurface.PlanarGeometry = pg; retsurface.exposedToSunField = true; } //it can be an exposed floor else { Dictionary<string, double> WH = new Dictionary<string, double>(); //it can be considered an exterior wall retsurface.surfaceType = surfaceTypeEnum.UndergroundSlab; retsurface.constructionIdRef = "something"; retsurface.Name = epsurface.name; AdjacentSpaceId adj = new AdjacentSpaceId(); adj.spaceIdRef = epsurface.zoneName; retsurface.AdjacentSpaceId[0] = adj; RectangularGeometry rg = new RectangularGeometry(); rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth); //find lower left hand corner of exterior wall //for now, we will just arbitrarily choose a point rg.CartesianPoint = pg.PolyLoop.Points[0]; rg.Tilt = gb.FormatDoubleToString(epsurface.tilt); //get width and height WH = GetWidthandHeight(epsurface, retsurface.surfaceType); rg.Width = gb.FormatDoubleToString(WH["width"]); rg.Height = gb.FormatDoubleToString(WH["height"]); retsurface.RectangularGeometry = rg; retsurface.PlanarGeometry = pg; retsurface.exposedToSunField = true; } } else if (epsurface._sunExposureVar == "NoSun" && epsurface._outsideBoundaryCondition == "Ground") { if (epsurface.tilt > 45 && epsurface.tilt < 135) { Dictionary<string, double> WH = new Dictionary<string, double>(); //it can be considered an underground wall retsurface.surfaceType = surfaceTypeEnum.UndergroundWall; retsurface.constructionIdRef = "something"; retsurface.Name = epsurface.name; AdjacentSpaceId adj1 = new AdjacentSpaceId(); adj1.spaceIdRef = epsurface.zoneName; AdjacentSpaceId adj2 = new AdjacentSpaceId(); adj2.spaceIdRef = epsurface.zoneName; retsurface.AdjacentSpaceId[0] = adj1; retsurface.AdjacentSpaceId[1] = adj2; RectangularGeometry rg = new RectangularGeometry(); rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth); //find lower left hand corner of exterior wall //for now, we will just arbitrarily choose a point rg.CartesianPoint = pg.PolyLoop.Points[0]; rg.Tilt = gb.FormatDoubleToString(epsurface.tilt); //get width and height WH = GetWidthandHeight(epsurface, retsurface.surfaceType); rg.Width = gb.FormatDoubleToString(WH["width"]); rg.Height = gb.FormatDoubleToString(WH["height"]); retsurface.RectangularGeometry = rg; retsurface.PlanarGeometry = pg; retsurface.exposedToSunField = false; } else if (epsurface.tilt >= 0 && epsurface.tilt <= 45) { Dictionary<string, double> WH = new Dictionary<string, double>(); //it can be considered an underground ceiling retsurface.surfaceType = surfaceTypeEnum.UndergroundCeiling; retsurface.constructionIdRef = "something"; retsurface.Name = epsurface.name; AdjacentSpaceId adj1 = new AdjacentSpaceId(); adj1.spaceIdRef = epsurface.zoneName; AdjacentSpaceId adj2 = new AdjacentSpaceId(); adj2.spaceIdRef = epsurface.zoneName; retsurface.AdjacentSpaceId[0] = adj1; retsurface.AdjacentSpaceId[1] = adj2; RectangularGeometry rg = new RectangularGeometry(); rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth); //find lower left hand corner of exterior wall //for now, we will just arbitrarily choose a point rg.CartesianPoint = pg.PolyLoop.Points[0]; rg.Tilt = gb.FormatDoubleToString(epsurface.tilt); //get width and height WH = GetWidthandHeight(epsurface, retsurface.surfaceType); rg.Width = gb.FormatDoubleToString(WH["width"]); rg.Height = gb.FormatDoubleToString(WH["height"]); retsurface.RectangularGeometry = rg; retsurface.PlanarGeometry = pg; retsurface.exposedToSunField = false; } else { Dictionary<string, double> WH = new Dictionary<string, double>(); //it can be considered an underground slab or slab on grade retsurface.surfaceType = surfaceTypeEnum.UndergroundSlab; retsurface.constructionIdRef = "something"; retsurface.Name = epsurface.name; AdjacentSpaceId adj1 = new AdjacentSpaceId(); adj1.spaceIdRef = epsurface.zoneName; AdjacentSpaceId adj2 = new AdjacentSpaceId(); adj2.spaceIdRef = epsurface.zoneName; retsurface.AdjacentSpaceId[0] = adj1; retsurface.AdjacentSpaceId[1] = adj2; RectangularGeometry rg = new RectangularGeometry(); rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth); //find lower left hand corner of exterior wall //for now, we will just arbitrarily choose a point rg.CartesianPoint = pg.PolyLoop.Points[0]; rg.Tilt = gb.FormatDoubleToString(epsurface.tilt); //get width and height WH = GetWidthandHeight(epsurface, retsurface.surfaceType); rg.Width = gb.FormatDoubleToString(WH["width"]); rg.Height = gb.FormatDoubleToString(WH["height"]); retsurface.RectangularGeometry = rg; retsurface.PlanarGeometry = pg; retsurface.exposedToSunField = false; } } else { retsurface.AdjacentSpaceId = new AdjacentSpaceId[2]; //some new code associated with finding the order of the two spaces if (epsurface.tilt > 45 && epsurface.tilt < 135) { Dictionary<string, double> WH = new Dictionary<string, double>(); //it can be considered an underground wall retsurface.surfaceType = surfaceTypeEnum.UndergroundWall; retsurface.constructionIdRef = "something"; retsurface.Name = epsurface.name; //this is wrong AdjacentSpaceId adj1 = new AdjacentSpaceId(); adj1.spaceIdRef = epsurface.zoneName; AdjacentSpaceId adj2 = new AdjacentSpaceId(); adj2.spaceIdRef = epsurface.zoneName; retsurface.AdjacentSpaceId[0] = adj1; retsurface.AdjacentSpaceId[1] = adj2; RectangularGeometry rg = new RectangularGeometry(); rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth); //find lower left hand corner of exterior wall //for now, we will just arbitrarily choose a point rg.CartesianPoint = pg.PolyLoop.Points[0]; rg.Tilt = gb.FormatDoubleToString(epsurface.tilt); //get width and height WH = GetWidthandHeight(epsurface, retsurface.surfaceType); rg.Width = gb.FormatDoubleToString(WH["width"]); rg.Height = gb.FormatDoubleToString(WH["height"]); retsurface.RectangularGeometry = rg; retsurface.PlanarGeometry = pg; retsurface.exposedToSunField = false; } else if (epsurface.tilt >= 0 && epsurface.tilt <= 45) { Dictionary<string, double> WH = new Dictionary<string, double>(); //it can be considered an underground ceiling retsurface.surfaceType = surfaceTypeEnum.UndergroundCeiling; retsurface.constructionIdRef = "something"; retsurface.Name = epsurface.name; //this is wrong AdjacentSpaceId adj1 = new AdjacentSpaceId(); adj1.spaceIdRef = epsurface.zoneName; AdjacentSpaceId adj2 = new AdjacentSpaceId(); adj2.spaceIdRef = epsurface.zoneName; retsurface.AdjacentSpaceId[0] = adj1; retsurface.AdjacentSpaceId[1] = adj2; RectangularGeometry rg = new RectangularGeometry(); rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth); //find lower left hand corner of exterior wall //for now, we will just arbitrarily choose a point rg.CartesianPoint = pg.PolyLoop.Points[0]; rg.Tilt = gb.FormatDoubleToString(epsurface.tilt); //get width and height WH = GetWidthandHeight(epsurface, retsurface.surfaceType); rg.Width = gb.FormatDoubleToString(WH["width"]); rg.Height = gb.FormatDoubleToString(WH["height"]); retsurface.RectangularGeometry = rg; retsurface.PlanarGeometry = pg; retsurface.exposedToSunField = false; } else { Dictionary<string, double> WH = new Dictionary<string, double>(); //it can be considered an underground slab or slab on grade retsurface.surfaceType = surfaceTypeEnum.UndergroundSlab; retsurface.constructionIdRef = "something"; retsurface.Name = epsurface.name; //this is wrong AdjacentSpaceId adj1 = new AdjacentSpaceId(); adj1.spaceIdRef = epsurface.zoneName; AdjacentSpaceId adj2 = new AdjacentSpaceId(); adj2.spaceIdRef = epsurface.zoneName; retsurface.AdjacentSpaceId[0] = adj1; retsurface.AdjacentSpaceId[1] = adj2; RectangularGeometry rg = new RectangularGeometry(); rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth); //find lower left hand corner of exterior wall //for now, we will just arbitrarily choose a point rg.CartesianPoint = pg.PolyLoop.Points[0]; rg.Tilt = gb.FormatDoubleToString(epsurface.tilt); //get width and height WH = GetWidthandHeight(epsurface, retsurface.surfaceType); rg.Width = gb.FormatDoubleToString(WH["width"]); rg.Height = gb.FormatDoubleToString(WH["height"]); retsurface.RectangularGeometry = rg; retsurface.PlanarGeometry = pg; retsurface.exposedToSunField = false; } } return retsurface; }
public static Dictionary<string, double> GetWidthandHeight(EPObj.MemorySafe_Surface epsurface, surfaceTypeEnum surftype) { Dictionary<string, double> WH = new Dictionary<string, double>(); List<EPObj.MemorySafe_CartCoord> coords = epsurface.SurfaceCoords; //we use a very simple algorithm where we find the area and the max height //we divide the area by the max height, and this is our width. //this helps us cover the case of non-vertical surfaces, and polygons that //are not rectangles double width = 0; double height = 0; for (int i = 0; i < (coords.Count() - 1); i++) { double dx = Math.Abs(coords[i].X - coords[i + 1].X); double dy = Math.Abs(coords[i].Y - coords[i + 1].Y); double dz = Math.Abs(coords[i].Z - coords[i + 1].Z); //get the height if (surftype == surfaceTypeEnum.ExteriorWall || surftype == surfaceTypeEnum.InteriorWall || surftype == surfaceTypeEnum.UndergroundWall) { if (dz == 0) continue; else { if (dx == 0 && dy == 0) { if (dz > height) { height = dz; } else continue; } else { //can you prove this somehow? double dist = Math.Sqrt(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)) + Math.Pow(dz, 2)); if (dist > height) { height = dist; } else continue; } } } else { if (dz == 0) { double dist = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)); if (dist > height) { height = dist; } else continue; } else //it is tilted { double dist = Math.Sqrt(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)) + Math.Pow(dz, 2)); if (dist > height) { height = dist; } else continue; } } //this simplifies the definition of width and area greatly double area = EPObj.GetAreaofSurface(epsurface); if (height != 0) { width = area / height; } } WH.Add("width", width); WH.Add("height", height); return WH; }
static public double FindAzimuth(EPObj.MemorySafe_CartVect normalVector) { double calculatedAzimuth = -999; //may need to also take into account other factors that, at this stage, seem to not be important //building Direction of Relative North //zone Direction of Relative North //GlobalGeometryRules coordinate system //I may need to know this in the future then rotate the axis vectors I am making below //x-axis [1 0 0] points east, y-axis [0 1 0] points north, z-axis[0 0 1] points up to the sky //alignment with y axis means north pointing, alignment with z-axis means it is pointing up to the sky (like a flat roof) EPObj.MemorySafe_CartVect northVector = new EPObj.MemorySafe_CartVect(0, 1, 0); EPObj.MemorySafe_CartVect southVector = new EPObj.MemorySafe_CartVect(0, -1, 0); EPObj.MemorySafe_CartVect eastVector = new EPObj.MemorySafe_CartVect(1, 0, 0); EPObj.MemorySafe_CartVect westVector = new EPObj.MemorySafe_CartVect(-1, 0, 0); EPObj.MemorySafe_CartVect upVector = new EPObj.MemorySafe_CartVect(0, 0, 1); //rotate the axis vectors for the future //ensure the vector passed into the function is a unit vector normalVector = EPObj.UnitVector(normalVector); //get X-Y projection of the normal vector //normalVector.Z = 0; //get azimuth: cross product of normal vector x-y projection and northVector //1st quadrant if ((normalVector.X == 0 && normalVector.Y == 1) || (normalVector.X == 1 && normalVector.Y == 0) || (normalVector.X > 0 && normalVector.Y > 0)) { //get azimuth: cross product of normal vector x-y projection and northVector EPObj.MemorySafe_CartVect azVector = EPObj.CrossProduct(normalVector, northVector); double azVectorMagnitude = EPObj.VectorMagnitude(azVector); //modification for when the vector is in different quadrants calculatedAzimuth = Math.Round(Math.Asin(azVectorMagnitude) * 180 / Math.PI, 2); return(calculatedAzimuth); } //second quadrant else if (normalVector.X < 0 && normalVector.Y > 0) { EPObj.MemorySafe_CartVect azVector = EPObj.CrossProduct(normalVector, westVector); double azVectorMagnitude = EPObj.VectorMagnitude(azVector); //modification for when the vector is in different quadrants calculatedAzimuth = Math.Round(Math.Asin(azVectorMagnitude) * 180 / Math.PI, 2) + 270; return(calculatedAzimuth); } //quadrant 3 else if ((normalVector.X < 0 && normalVector.Y < 0) || (normalVector.X == -1 && normalVector.Y == 0)) { EPObj.MemorySafe_CartVect azVector = EPObj.CrossProduct(normalVector, southVector); double azVectorMagnitude = EPObj.VectorMagnitude(azVector); //modification for when the vector is in different quadrants calculatedAzimuth = Math.Round(Math.Asin(azVectorMagnitude) * 180 / Math.PI, 2) + 180; return(calculatedAzimuth); } //quadrant 4 else if ((normalVector.X > 0 && normalVector.Y < 0) || (normalVector.X == 0 && normalVector.Y == -1)) { EPObj.MemorySafe_CartVect azVector = EPObj.CrossProduct(normalVector, eastVector); double azVectorMagnitude = EPObj.VectorMagnitude(azVector); //modification for when the vector is in different quadrants calculatedAzimuth = Math.Round(Math.Asin(azVectorMagnitude) * 180 / Math.PI, 2) + 90; return(calculatedAzimuth); } //this will happen to vectors that point straight down or straight up because we are only interested in the X-Y projection and set the Z to zero anyways else if (normalVector.X == 0 && normalVector.Y == 0) { calculatedAzimuth = 0; return(calculatedAzimuth); } //get the return(calculatedAzimuth); }