/// <summary> /// Construct Edge of line type by points and normal (localY). /// </summary> public Edge(FdPoint3d startPoint, FdPoint3d endPoint, FdVector3d localY) { this.Type = "line"; this.Points.Add(startPoint); this.Points.Add(endPoint); this.Normal = localY; }
/// <summary> /// Normalize FdVector3d (i.e. scale so that length equals 1). /// </summary> public FdVector3d Normalize() { double l = this.Length(); FdVector3d normal = new FdVector3d(this.X / l, this.Y / l, this.Z / l); return(normal); }
/// <summary> /// Rotate this vector by an angle around an axis /// </summary> /// <param name="axis"></param> /// <param name="angle"></param> /// <returns></returns> public FdVector3d RotateAroundAxis(double angle, FdVector3d axis) { // normalize vector FdVector3d _axis = axis.Normalize(); // https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle double[,] rotationMatrix = new double[3, 3]; rotationMatrix[0, 0] = Math.Cos(angle) + Math.Pow(_axis.X, 2) * (1 - Math.Cos(angle)); rotationMatrix[0, 1] = _axis.X * _axis.Y * (1 - Math.Cos(angle)) - _axis.Z * Math.Sin(angle); rotationMatrix[0, 2] = _axis.X * _axis.Z * (1 - Math.Cos(angle)) + _axis.Y * Math.Sin(angle); rotationMatrix[1, 0] = _axis.Y * _axis.X * (1 - Math.Cos(angle)) + _axis.Z * Math.Sin(angle); rotationMatrix[1, 1] = Math.Cos(angle) + Math.Pow(_axis.Y, 2) * (1 - Math.Cos(angle)); rotationMatrix[1, 2] = _axis.Y * _axis.Z * (1 - Math.Cos(angle)) - _axis.X * Math.Sin(angle); rotationMatrix[2, 0] = _axis.Z * _axis.X * (1 - Math.Cos(angle)) - _axis.Y * Math.Sin(angle); rotationMatrix[2, 1] = _axis.Z * _axis.Y * (1 - Math.Cos(angle)) + _axis.X * Math.Sin(angle); rotationMatrix[2, 2] = Math.Cos(angle) + Math.Pow(_axis.Z, 2) * (1 - Math.Cos(angle)); // matrix multiplication double x = this.X * rotationMatrix[0, 0] + this.Y * rotationMatrix[0, 1] + this.Z * rotationMatrix[0, 2]; double y = this.X * rotationMatrix[1, 0] + this.Y * rotationMatrix[1, 1] + this.Z * rotationMatrix[1, 2]; double z = this.X * rotationMatrix[2, 0] + this.Y * rotationMatrix[2, 1] + this.Z * rotationMatrix[2, 2]; // return new vector return(new FdVector3d(x, y, z)); }
public bool Equals(FdVector3d v) { if ((object)v == null) { return(false); } return((X == v.X) && (Y == v.Y) && (Z == v.Z)); }
public bool Equals(FdVector3d v, double tol) { if ((object)v == null) { return(false); } return((Math.Abs(X - v.X) < tol) && (Math.Abs(Y - v.Y) < tol) && (Math.Abs(Z - v.Z) < tol)); }
/// <summary> /// Create FdCoordinateSystem from Dynamo coordinate system of a Surface. /// No realignment neccessary. /// </summary> internal static FdCoordinateSystem FromDynamoCoordinateSystemSurface(Autodesk.DesignScript.Geometry.CoordinateSystem obj) { FdPoint3d origin = FdPoint3d.FromDynamo(obj.Origin); FdVector3d localX = FdVector3d.FromDynamo(obj.XAxis); FdVector3d localY = FdVector3d.FromDynamo(obj.YAxis); FdVector3d localZ = FdVector3d.FromDynamo(obj.ZAxis); return(new FdCoordinateSystem(origin, localX, localY, localZ)); }
/// <summary> /// /// Create FdCoordinateSystem from Dynamo coordinate system of a Arc or Circle. /// Dynamo Arcs and Circles follow left-hand rule. /// This method realignes the coordinate system. /// </summary> internal static FdCoordinateSystem FromDynamoCoordinateSystemArcOrCircle(Autodesk.DesignScript.Geometry.CoordinateSystem obj) { FdPoint3d origin = FdPoint3d.FromDynamo(obj.Origin); FdVector3d localX = FdVector3d.FromDynamo(obj.YAxis); FdVector3d localY = FdVector3d.FromDynamo(obj.XAxis); FdVector3d localZ = localX.Cross(localY).Normalize(); return(new FdCoordinateSystem(origin, localX, localY, localZ)); }
/// <summary> /// Calculate dot-product of this FdVector3d and v FdVector3d. /// </summary> public double Dot(FdVector3d v) { FdVector3d v0 = this; FdVector3d v1 = v; // https://en.wikipedia.org/wiki/Dot_product#Algebraic_definition double s = v0.X * v1.X + v0.Y * v1.Y + v0.Z * v1.Z; return(s); }
/// <summary> /// Check if val is a non zero 3d vector. /// </summary> /// <param name="val"></param> /// <returns></returns> internal static Geometry.FdVector3d NonZeroFdVector3d(Geometry.FdVector3d val) { if (val.IsZero()) { throw new System.ArgumentException("Vector must be non zero."); } else { return(val); } }
public static Cover OneWayCover(Autodesk.DesignScript.Geometry.Surface surface, [DefaultArgument("[]")] List <object> supportingStructures, Autodesk.DesignScript.Geometry.Vector loadBearingDirection = null, string identifier = "CO") { // create FlatSurface Geometry.Region region = Geometry.Region.FromDynamo(surface); // get loadBearingDirection Geometry.FdVector3d _loadBearingDirection = Geometry.FdVector3d.FromDynamo(loadBearingDirection).Normalize(); // return return(Cover.OneWayCover(region, supportingStructures, _loadBearingDirection, identifier)); }
/// <summary> /// Orient this coordinate system to GCS as if this coordinate system was constrained as a plane (i.e. x' and y' are constrianed by the plane) /// If plane is not vertical plane z' will be orientated up. /// If plane is vertical y' will be orientated up. /// </summary> public void OrientPlaneTypeLcsToGcs() { double dot = this.LocalZ.Normalize().Dot(FdVector3d.UnitZ()); if (dot == 1) { // the plane is horisontal and z' is equal to Z // set x' to X this.SetXAroundZ(FdVector3d.UnitX()); } else if (dot < 1 && dot > 0) { // the plane is not horisontal nor vertical but z' is pointing up // set x' to the cross-product of z' and Z // this.SetXAroundZ(FdVector3d.UnitZ().Cross(this.LocalZ)); } else if (dot == 0) { // the plane is vertical // set y' to Z. This is the equivalent as setting x' to the cross-product of z' and Z in this case. this.SetYAroundZ(FdVector3d.UnitZ()); } else if (dot < 0 && dot > -1) { // the plane is not horisontal nor vertical, z' is pointing down // flip coordinate system around x' so that z' points up this.SetZAroundX(this.LocalZ.Reverse()); // set x' to the cross-product of z' and Z // this.SetXAroundZ(FdVector3d.UnitZ().Cross(this.LocalZ)); } else if (dot == -1) { // the plane is horisontal but z' is equal to negative Z // flip coordinate system around x' so that z' points up this.SetZAroundX(this.LocalZ.Reverse()); // set x' to X // this.SetXAroundZ(FdVector3d.UnitX()); } else { throw new System.ArgumentException($"Impossible to orient axes. Dot product, {dot}, should be between -1 and 1"); } }
/// <summary> /// Create Edge (Arc1) from Dynamo Arc. /// </summary> public static Geometry.Edge FromDynamoArc1(Autodesk.DesignScript.Geometry.Arc obj) { double radius = obj.Radius; double startAngle = 0; double endAngle = startAngle + Degree.ToRadians(obj.SweepAngle); FdPoint3d centerPoint = FdPoint3d.FromDynamo(obj.CenterPoint); FdVector3d xAxis = new FdVector3d(centerPoint, FdPoint3d.FromDynamo(obj.StartPoint)).Normalize(); // lcs FdCoordinateSystem cs = FdCoordinateSystem.FromDynamoCurve(obj); // return return(new Geometry.Edge(radius, startAngle, endAngle, centerPoint, xAxis, cs)); }
public override bool Equals(System.Object obj) { if (obj == null) { return(false); } FdVector3d v = obj as FdVector3d; if ((System.Object)v == null) { return(false); } return((X == v.X) && (Y == v.Y) && (Z == v.Z)); }
/// <summary> /// Calculate cross-product of this FdVector3d and v FdVector3d. /// </summary> public FdVector3d Cross(FdVector3d v) { FdVector3d v0 = this; FdVector3d v1 = v; double i, j, k; // https://en.wikipedia.org/wiki/Cross_product#Coordinate_notation i = v0.Y * v1.Z - v0.Z * v1.Y; j = v0.Z * v1.X - v0.X * v1.Z; k = v0.X * v1.Y - v0.Y * v1.X; FdVector3d v2 = new FdVector3d(i, j, k);; return(v2); }
/// <summary> /// Construct FdCoordinateSystem from origin point and local x, y, z axes. /// </summary> public FdCoordinateSystem(FdPoint3d origin, FdVector3d localX, FdVector3d localY, FdVector3d localZ) { this.Origin = origin; this._localX = localX; this._localY = localY; this._localZ = localZ; if (!this.IsComplete()) { throw new System.ArgumentException("The defined coordinate system is not complete!"); } if (!this.IsOrthogonal()) { throw new System.ArgumentException($"The defined coordinate system is not orthogonal within the tolerance {Tolerance.DotProduct}"); } }
/// <summary> /// Check if this FdVector3d is parallel to v. /// Returns 1 if parallel, -1 if antiparallel, 0 if not parallel /// </summary> public int Parallel(FdVector3d v) { FdVector3d v0 = this.Normalize(); FdVector3d v1 = v.Normalize(); if (v0.Equals(v1, Tolerance.Point3d)) { return(1); } else if (v0.Scale(-1).Equals(v, Tolerance.Point3d)) { return(-1); } else { return(0); } }
/// <summary> /// Set Y-axis and rotate coordinate system accordingly around X-Axis. /// </summary> public void SetYAroundX(FdVector3d vector) { // try to set axis FdVector3d val = vector.Normalize(); FdVector3d x = this.LocalX; double dot = x.Dot(val); if (Math.Abs(dot) < Tolerance.DotProduct) { this._localY = val; this._localZ = x.Cross(val); // follows right-hand-rule } else { throw new System.ArgumentException($"The passed Y-axis is not perpendicular to X-axis. The dot-product is {dot}, but should be 0"); } }
/// <summary> /// Orient this coordinate system to GCS as if this coordinate system was constrained as an edge (i.e x' is constrained by the edge) /// </summary> public void OrientEdgeTypeLcsToGcs() { if (this.IsComplete()) { // if LocalX is parallell to UnitZ set (rotate) LocalY to UnitY int par = this.LocalX.Parallel(Geometry.FdVector3d.UnitZ()); if (par == 1 || par == -1) { this.SetYAroundX(FdVector3d.UnitY()); } // else set (rotate) LocalY to UnitZ cross LocalX else { this.SetYAroundX(FdVector3d.UnitZ().Cross(this.LocalX).Normalize()); } } else { throw new System.ArgumentException("Impossible to orient axes as the passed coordinate system is incomplete."); } }
/// <summary> /// Create region by points and coordinate system. /// </summary> /// <param name="points">List of sorted points defining the outer perimeter of the region.</param> /// <param name="coordinateSystem">Coordinate system of the region</param> public Region(List <FdPoint3d> points, FdCoordinateSystem coordinateSystem) { // edge normal FdVector3d edgeLocalY = coordinateSystem.LocalZ; List <Edge> edges = new List <Edge>(); for (int idx = 0; idx < points.Count; idx++) { // startPoint FdPoint3d p0 = p0 = points[idx]; // endPoint FdPoint3d p1; if (idx != points.Count - 1) { p1 = points[idx + 1]; } else { p1 = points[0]; } // create edge edges.Add(new Edge(p0, p1, edgeLocalY)); } // create contours Contour contour = new Contour(edges); // set properties this.Contours = new List <Contour> { contour }; this.CoordinateSystem = coordinateSystem; }
/// <summary> /// Create FdVector3d from Dynamo vector. /// </summary> public static FdVector3d FromDynamo(Autodesk.DesignScript.Geometry.Vector vector) { FdVector3d newVector = new FdVector3d(vector.X, vector.Y, vector.Z); return(newVector); }
/// <summary> /// Construct a cover /// </summary> /// <param name="region">Region of cover.</param> /// <param name="supportingStructures">Guidlist of supporting structure.</param> /// <param name="loadBearingDirection">Vector, if null a TwoWay cover is defined.</param> public Cover(Geometry.Region region, CoverReferenceList supportingStructures, Geometry.FdVector3d loadBearingDirection, string identifier) { this.EntityCreated(); this.Identifier = identifier; this.Region = region; this.SupportingStructures = supportingStructures; this.LoadBearingDirection = loadBearingDirection; }
/// Create OneWayCover. public static Cover OneWayCover(Geometry.Region region, List <object> supportingStructures, Geometry.FdVector3d loadBearingDirection, string identifier) { // get supportingStructures.guid CoverReferenceList _supportingStructures = CoverReferenceList.FromObjectList(supportingStructures); // create cover Cover _cover = new Cover(region, _supportingStructures, loadBearingDirection, identifier); return(_cover); }
/// <summary> /// Global coordinate system /// </summary> public static FdCoordinateSystem Global() { return(new FdCoordinateSystem(FdPoint3d.Origin(), FdVector3d.UnitX(), FdVector3d.UnitY())); }
internal static Rhino.Geometry.Vector3d ToRhino(this FemDesign.Geometry.FdVector3d vector) { return(new Rhino.Geometry.Vector3d(vector.X, vector.Y, vector.Z)); }
/// <summary> /// Translate a point by a vector. /// </summary> /// <param name="v">Vector.</param> /// <returns></returns> public FdPoint3d Translate(FdVector3d v) { return(new FdPoint3d(this.X + v.X, this.Y + v.Y, this.Z + v.Z)); }