Esempio n. 1
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            HeGraph3d graph       = null;
            double    layerHeigth = 0;
            double    length      = 0;

            if (!DA.GetData(0, ref graph))
            {
                return;
            }
            if (!DA.GetData(1, ref layerHeigth))
            {
                return;
            }
            if (!DA.GetData(2, ref length))
            {
                return;
            }

            var f       = new DataTree <Plane>();
            var tparams = new DataTree <double>();

            List <GH_Path> branches = new List <GH_Path>();

            for (int i = 0; i < graph.Edges.Count; i++)
            {
                branches.Add(new GH_Path(i));
            }

            for (int i = 0; i < graph.Vertices.Count; i++)
            {
                for (int j = 0; j < graph.Vertices[i].ConnectedVertices.ToList().Count; j++)
                {
                    var v0 = graph.Vertices[i].Position;
                    var v1 = graph.Vertices[i].ConnectedVertices.ToList()[j].Position;

                    var eVec = (v0 - v1).Unit;
                    var dist = v0.DistanceTo(v1);

                    var zUnit = new Vec3d(1, 0, 0);
                    var n     = Vec3d.Cross(eVec, zUnit).Unit;
                    var bn    = Vec3d.Cross(eVec, n).Unit;
                    var bbn   = Vec3d.Cross(eVec, bn).Unit;

                    var frames = new List <Rhino.Geometry.Plane>();
                    var edgeId = graph.Vertices[i].FindHalfedgeTo(graph.Vertices[i].ConnectedVertices.ToList()[j]).Index >> 1;

                    var branch = new GH_Path(edgeId);

                    int    cnt = 0;
                    double l   = 0;

                    do
                    {
                        Point3d pt = v0 - eVec * cnt * layerHeigth;
                        l += v0.DistanceTo((Vec3d)pt);

                        var frame = new Rhino.Geometry.Plane((Point3d)pt, (Vector3d)bn, (Vector3d)bbn);

                        frames.Add(frame);
                        cnt++;
                    }while (length > l);

                    f.AddRange(frames, branch);
                }
            }

            for (int i = 0; i < graph.Edges.Count; i++)
            {
                var count = f.Branch(i).Count;
                var t0    = 1.0 / (double)count;

                for (int j = 0; j < count; j++)
                {
                    tparams.Add((j * t0), new GH_Path(i));
                }
            }

            DA.SetDataTree(0, f);
            DA.SetDataTree(1, tparams);
        }
Esempio n. 2
0
 /// <summary>
 /// Applies this rotation to the given vector.
 /// </summary>
 /// <param name="vector"></param>
 /// <returns></returns>
 public Vector3d Apply(Vector3d vector)
 {
     return(_cosAngle * vector + _sinAngle * Vector3d.Cross(_axis, vector) + Vector3d.Dot(_axis, vector) * (1.0 - _cosAngle) * _axis);
 }
Esempio n. 3
0
            /// <summary>
            /// Performs a singular value decomposition of the given matrix A.
            /// Returns the rank of A.
            /// Note that this implementation ensures that U and V are proper rotations (i.e. no reflections).
            /// </summary>
            public static int SingularValue(ref Matrix3d A, out Matrix3d U, out Vector3d sigma, out Matrix3d V, double epsilon = D.ZeroTolerance)
            {
                // U -> proper rotation (no reflection)
                // sigma -> singular values
                // V -> proper rotation (no reflection)

                // impl ref
                // https://www.math.ucla.edu/~jteran/papers/ITF04.pdf

                var AtA = A.ApplyTranspose(ref A);

                EigenSymmetricPSD(AtA, out V, out sigma, epsilon);

                // handle reflection in V
                if (V.Determinant < 0.0)
                {
                    V.Column2 *= -1.0;
                }

                // U = A V inv(sigma)
                // must handle cases where singular values are zero
                if (sigma.X < epsilon)
                {
                    // all zero singular values

                    //     | 0  -  - |
                    // Σ = | -  0  - |
                    //     | -  -  0 |

                    sigma.X = sigma.Y = sigma.Z = 0.0;
                    U       = Identity;

                    return(0);
                }
                else if (sigma.Y < epsilon)
                {
                    // one non-zero singular value

                    //     | x  -  - |
                    // Σ = | -  0  - |
                    //     | -  -  0 |

                    sigma.X = Math.Sqrt(sigma.X);
                    sigma.Y = sigma.Z = 0.0;

                    var u0 = A.Apply(V.Column0 / sigma.X);
                    var u1 = u0.Y > 0.0 ? u0.CrossX : u0.CrossY;

                    u1.Unitize();
                    U = new Matrix3d(u0, u1, Vector3d.Cross(u0, u1));

                    return(1);
                }
                else if (sigma.Z < epsilon)
                {
                    // two non-zero singular values

                    //     | x  -  - |
                    // Σ = | -  y  - |
                    //     | -  -  0 |

                    sigma.X = Math.Sqrt(sigma.X);
                    sigma.Y = Math.Sqrt(sigma.Y);
                    sigma.Z = 0.0;

                    var u0 = A.Apply(V.Column0 / sigma.X);
                    var u1 = A.Apply(V.Column1 / sigma.Y);
                    U = new Matrix3d(u0, u1, Vector3d.Cross(u0, u1));

                    return(2);
                }

                // all non-zero singular values

                //     | x  -  - |
                // Σ = | -  y  - |
                //     | -  -  z |

                sigma.X = Math.Sqrt(sigma.X);
                sigma.Y = Math.Sqrt(sigma.Y);
                sigma.Z = Math.Sqrt(sigma.Z);

                U = new Matrix3d(
                    A.Apply(V.Column0 / sigma.X),
                    A.Apply(V.Column1 / sigma.Y),
                    A.Apply(V.Column2 / sigma.Z));

                // handle reflection in U
                if (U.Determinant < 0.0)
                {
                    U.Column2 *= -1.0;
                    sigma.Z   *= -1.0;
                }

                return(3);
            }
Esempio n. 4
0
 /// <summary>
 /// Assumes the given vectors are orthonormal.
 /// </summary>
 /// <param name="z"></param>
 /// <param name="x"></param>
 private void SetOrthoZX(Vector3d z, Vector3d x)
 {
     _x = x;
     _y = Vector3d.Cross(z, x);
     _z = z;
 }
Esempio n. 5
0
 /// <summary>
 /// Assumes the given vectors are orthonormal.
 /// </summary>
 /// <param name="y"></param>
 /// <param name="z"></param>
 private void SetOrthoYZ(Vector3d y, Vector3d z)
 {
     _x = Vector3d.Cross(y, z);
     _y = y;
     _z = z;
 }
Esempio n. 6
0
 /// <summary>
 /// Assumes the given vectors are orthonormal.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 private void SetOrthoXY(Vector3d x, Vector3d y)
 {
     _x = x;
     _y = y;
     _z = Vector3d.Cross(x, y);
 }