public static IfcAxis2Placement3D ToAixs3D_LateralConnectPlate(IfcStore m, IfcLinearPlacement lp) { var origin = MakeCartesianPoint(m); var locZ = MakeDirection(m, 0, 0, -1); var locX = MakeDirection(m, 1, 0, 0); var locY = MakeDirection(m, 0, 1, 0); var curve = lp.PlacementRelTo; if (curve is IIfcOffsetCurveByDistances offsetCurve) { var basicCurve = offsetCurve.BasisCurve; double startDist = offsetCurve.OffsetValues[0].DistanceAlong + lp.Distance.DistanceAlong; double offsetLateral = offsetCurve.OffsetValues[0].OffsetLateral.Value + lp.Distance.OffsetLateral.Value; double offsetVertical = offsetCurve.OffsetValues[0].OffsetVertical.Value + lp.Distance.OffsetVertical.Value; if (basicCurve is IIfcAlignmentCurve ac) { var vz = new XbimVector3D(0, 0, 1); double height = ac.Vertical.Segments[0].StartHeight; var horSegs = ac.Horizontal.Segments; (var pt, var vy) = Utilities.GeometryEngine.GetPointByDistAlong(horSegs, startDist); var vx = vz.CrossProduct(vy); var position = pt + vy * offsetLateral + vz * (offsetVertical + height); origin = MakeCartesianPoint(m, position.X, position.Y, position.Z); locY = MakeDirection(m, vy.X, vy.Y, vy.Z); locX = MakeDirection(m, vx.X, vx.Y, vx.Z); } } return(MakeAxis2Placement3D(m, origin, locX, locZ)); }
/// <summary> /// Builds a windows Matrix3D from an ObjectPlacement /// Conversion fo c++ function CartesianTransform::ConvertMatrix3D from CartesianTransform.cpp /// </summary> /// <param name="objPlacement">IfcObjectPlacement object</param> /// <returns>Matrix3D</returns> protected XbimMatrix3D ConvertMatrix3D(IfcObjectPlacement objPlacement) { if (objPlacement is IfcLocalPlacement) { IfcLocalPlacement locPlacement = (IfcLocalPlacement)objPlacement; if (locPlacement.RelativePlacement is IfcAxis2Placement3D) { IfcAxis2Placement3D axis3D = (IfcAxis2Placement3D)locPlacement.RelativePlacement; XbimVector3D ucsXAxis = new XbimVector3D(axis3D.RefDirection.DirectionRatios[0], axis3D.RefDirection.DirectionRatios[1], axis3D.RefDirection.DirectionRatios[2]); XbimVector3D ucsZAxis = new XbimVector3D(axis3D.Axis.DirectionRatios[0], axis3D.Axis.DirectionRatios[1], axis3D.Axis.DirectionRatios[2]); ucsXAxis = ucsXAxis.Normalized(); ucsZAxis = ucsZAxis.Normalized(); XbimVector3D ucsYAxis = XbimVector3D.CrossProduct(ucsZAxis, ucsXAxis); ucsYAxis = ucsYAxis.Normalized(); XbimPoint3D ucsCentre = axis3D.Location.XbimPoint3D(); XbimMatrix3D ucsTowcs = new XbimMatrix3D(ucsXAxis.X, ucsXAxis.Y, ucsXAxis.Z, 0, ucsYAxis.X, ucsYAxis.Y, ucsYAxis.Z, 0, ucsZAxis.X, ucsZAxis.Y, ucsZAxis.Z, 0, ucsCentre.X, ucsCentre.Y, ucsCentre.Z, 1); if (locPlacement.PlacementRelTo != null) { return(XbimMatrix3D.Multiply(ucsTowcs, ConvertMatrix3D(locPlacement.PlacementRelTo))); } return(ucsTowcs); } throw new NotImplementedException("Support for Placements other than 3D not implemented"); } throw new NotImplementedException("Support for Placements other than Local not implemented"); }
/// <summary> /// Returns the normal of the triangle that contains the specified edge /// </summary> /// <param name="edge"></param> /// <returns></returns> public XbimVector3D TriangleNormal(XbimTriangleEdge edge) { var p1 = _vertices[edge.StartVertexIndex].Position; var p2 = _vertices[edge.NextEdge.StartVertexIndex].Position; var p3 = _vertices[edge.NextEdge.NextEdge.StartVertexIndex].Position; var a = new XbimPoint3D(p1.X, p1.Y, p1.Z); var b = new XbimPoint3D(p2.X, p2.Y, p2.Z); var c = new XbimPoint3D(p3.X, p3.Y, p3.Z); var cv = XbimVector3D.CrossProduct(b - a, c - a); cv.Normalize(); return(cv); }
/// <summary> /// returns the area of the polyloop /// </summary> /// <param name="loop"></param> /// <returns></returns> public static double Area(this IfcPolyLoop loop) { XbimVector3D sum = new XbimVector3D(0, 0, 0); IList <IfcCartesianPoint> pts = loop.Polygon; for (int i = 0; i < pts.Count - 1; i++) { XbimVector3D a = new XbimVector3D(pts[i].X, pts[i].Y, pts[i].Z); XbimVector3D b = new XbimVector3D(pts[i + 1].X, pts[i + 1].Y, pts[i + 1].Z); sum = sum + a.CrossProduct(b); } XbimVector3D n = loop.NewellsNormal(); return(n.DotProduct(sum) / 2); }
/// <summary> /// returns the area of the polyloop /// </summary> /// <param name="loop"></param> /// <returns></returns> public static double Area(this IfcPolyLoop loop) { var sum = new XbimVector3D(0, 0, 0); var pts = loop.Polygon; for (var i = 0; i < pts.Count - 1; i++) { var a = new XbimVector3D(pts[i].X, pts[i].Y, pts[i].Z); var b = new XbimVector3D(pts[i + 1].X, pts[i + 1].Y, pts[i + 1].Z); sum = sum + a.CrossProduct(b); } var n = loop.NewellsNormal(); return(n.DotProduct(sum) / 2); }
// 已知直线和其上一点距直线起点的沿线距离 public static (XbimPoint3D pt, XbimVector3D vec) GetPointOnCurve(IIfcLineSegment2D l, double dist) { var length = l.SegmentLength; if (dist > length + Tolerance) { throw new ArgumentOutOfRangeException("dist"); } var start = new XbimPoint3D(l.StartPoint.X, l.StartPoint.Y, 0); var startDir = ToVector3D((double)l.StartDirection.Value); var zAxis = new XbimVector3D(0, 0, 1); var lateral = zAxis.CrossProduct(startDir); return(start + dist * startDir, lateral); }
public double GetArea() { // the normal can be taken from the product of two segments on the polyline if (Count() < 3) { return(double.NaN); } var normal = Normal() * -1; var firstSegment = FirstSegment(); var up = XbimVector3D.CrossProduct(normal, firstSegment); var campos = new XbimVector3D( _geomPoints[0].Point.X, _geomPoints[0].Point.Y, _geomPoints[0].Point.Z ); var target = campos + normal; var m = XbimMatrix3D.CreateLookAt(campos, target, up); var point = new XbimPoint3D[Count()]; for (var i = 0; i < point.Length; i++) { var pBefore = new XbimPoint3D( _geomPoints[i].Point.X, _geomPoints[i].Point.Y, _geomPoints[i].Point.Z ); var pAft = m.Transform(pBefore); point[i] = pAft; } // http://stackoverflow.com/questions/2553149/area-of-a-irregular-shape // it assumes that the last point is NOT the same of the first one, but it tolerates the case. double area = 0.0f; var numVertices = Count(); for (var i = 0; i < numVertices - 1; ++i) { area += point[i].X * point[i + 1].Y - point[i + 1].X * point[i].Y; } area += point[numVertices - 1].X * point[0].Y - point[0].X * point[numVertices - 1].Y; area /= 2.0; return(area); }
public static XbimMatrix3D ToMatrix3D(this IIfcAxis2Placement3D axis3) { if (axis3.RefDirection != null && axis3.Axis != null) { var za = new XbimVector3D(axis3.Axis.X, axis3.Axis.Y, axis3.Axis.Z); za = za.Normalized(); var xa = new XbimVector3D(axis3.RefDirection.X, axis3.RefDirection.Y, axis3.RefDirection.Z); xa = xa.Normalized(); XbimVector3D ya = XbimVector3D.CrossProduct(za, xa); ya = ya.Normalized(); return(new XbimMatrix3D(xa.X, xa.Y, xa.Z, 0, ya.X, ya.Y, ya.Z, 0, za.X, za.Y, za.Z, 0, axis3.Location.X, axis3.Location.Y, axis3.Location.Z, 1)); } return(new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis3.Location.X, axis3.Location.Y, axis3.Location.Z, 1)); }
private static XbimMatrix3D ConvertAxis3D(IfcAxis2Placement3D axis3) { if (axis3.RefDirection != null && axis3.Axis != null) { XbimVector3D za = axis3.Axis.XbimVector3D(); za = za.Normalized(); XbimVector3D xa = axis3.RefDirection.XbimVector3D(); xa = xa.Normalized(); XbimVector3D ya = XbimVector3D.CrossProduct(za, xa); ya = ya.Normalized(); return(new XbimMatrix3D(xa.X, xa.Y, xa.Z, 0, ya.X, ya.Y, ya.Z, 0, za.X, za.Y, za.Z, 0, axis3.Location.X, axis3.Location.Y, axis3.Location.Z, 1)); } else { return(new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis3.Location.X, axis3.Location.Y, axis3.Location.Z, 1)); } }
/// <summary> /// Get point on arc by given start point, start direction, arc radius, /// is counter-clockwise and distance along. /// </summary> /// <param name="start"></param> /// <param name="dir"></param> /// <param name="radius"></param> /// <param name="isCCW"></param> /// <param name="dist"></param> /// <returns></returns> public static (XbimPoint3D pt, XbimVector3D vec) GetPointOnCurve(XbimPoint3D start, XbimVector3D dir, double radius, bool isCCW, double dist) { // Compute the location of arc center. var zAxis = new XbimVector3D(0, 0, 1); var start2center = isCCW ? zAxis.CrossProduct(dir) : dir.CrossProduct(zAxis); var center = start + radius * start2center; // Compute the location of arc end point var theta = isCCW ? dist / radius : -dist / radius; var center2start = start2center.Negated(); var mat = new XbimMatrix3D(); mat.RotateAroundZAxis(theta); var center2end = mat.Transform(center2start); var lateral = isCCW ? center2end.Negated() : center2end; return(center + radius * center2end, lateral); }
private XbimMatrix3D ConvertAxis3D() { if (RefDirection == null || Axis == null) { return(new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, Location.X, Location.Y, Location.Z, 1)); } var za = Axis.XbimVector3D(); za.Normalized(); var xa = RefDirection.XbimVector3D(); xa.Normalized(); var ya = XbimVector3D.CrossProduct(za, xa); ya.Normalized(); return(new XbimMatrix3D(xa.X, xa.Y, xa.Z, 0, ya.X, ya.Y, ya.Z, 0, za.X, za.Y, za.Z, 0, Location.X, Location.Y, Location.Z, 1)); }
internal IVector3D Normal() { IfcPolyLoop polyLoop = Bound as IfcPolyLoop; if (polyLoop != null) { int numPts = polyLoop.Polygon.Count; for (int i = 1; i < polyLoop.Polygon.Count; i++) { XbimPoint3D c = polyLoop.Polygon[i].XbimPoint3D(); XbimPoint3D p = polyLoop.Polygon[i - 1].XbimPoint3D(); XbimPoint3D n = polyLoop.Polygon[(i + 1 == numPts) ? 0 : i + 1].XbimPoint3D(); XbimVector3D left = c - p; XbimVector3D right = n - c; XbimVector3D cp = XbimVector3D.CrossProduct(left, right); cp.Normalize(); if (!double.IsNaN(cp.X)) //happens if the three points are in a straigh line { if (!Orientation) { cp.Negate(); } return(new IfcDirection(cp)); } else if (i == polyLoop.Polygon.Count - 1) { // if its the last round of for look then just return the last cp return(new IfcDirection(cp)); } } //srl removed the exception to stop invalid faces from causing a crash, an invalid normal is returned which can be checked for return(new IfcDirection(0, 0, 0)); //return an invalid normal as the face is either a line or a point //throw new Exception("IfcFaceBound:Normal has an Invalid face"); } else { //srl removed the exception to stop invalid faces from causing a crash, an invalid normal is returned which can be checked for return(new IfcDirection(0, 0, 0)); //return an invalid normal as the face is either a line or a point } // throw new Exception("IfcFaceBound:Normal has an undefined bound"); }
public static XbimPoint3D GetPlacementPoint(IIfcCurveSegment2D c, double dist, double verticalOffset, double lateraloffset) { XbimPoint3D Point3D = new XbimPoint3D(); if (c is IIfcLineSegment2D line) { (XbimPoint3D pointOnCurve, XbimVector3D vecOnCurve) = GetPointOnCurve(line, dist); var zAxis = new XbimVector3D(0, 0, 1); var vecoff = vecOnCurve.CrossProduct(zAxis); Point3D = (pointOnCurve + vecoff * lateraloffset + zAxis * verticalOffset); //return Point3D; } if (c is IIfcCircularArcSegment2D arc) { (XbimPoint3D pointOnCurve, XbimVector3D vecOnCurve) = GetPointOnCurve(arc, dist); var isCCW = (bool)arc.IsCCW.Value; var zAxis = new XbimVector3D(0, 0, 1); var start2center = isCCW ? zAxis.CrossProduct(vecOnCurve) : vecOnCurve.CrossProduct(zAxis); Point3D = (pointOnCurve + start2center * lateraloffset + zAxis * verticalOffset); //return Point3D; } return(Point3D); }