Пример #1
0
 /// <summary>
 /// Intersects two lines.
 /// </summary>
 /// <param name="lineA">First line for intersection.</param>
 /// <param name="lineB">Second line for intersection.</param>
 /// <param name="a">
 /// Parameter on lineA that is closest to LineB. 
 /// The shortest distance between the lines is the chord from lineA.PointAt(a) to lineB.PointAt(b)
 /// </param>
 /// <param name="b">
 /// Parameter on lineB that is closest to LineA. 
 /// The shortest distance between the lines is the chord from lineA.PointAt(a) to lineB.PointAt(b)
 /// </param>
 /// <param name="tolerance">
 /// If tolerance > 0.0, then an intersection is reported only if the distance between the points is &lt;= tolerance. 
 /// If tolerance &lt;= 0.0, then the closest point between the lines is reported.
 /// </param>
 /// <param name="finiteSegments">
 /// If true, the input lines are treated as finite segments. 
 /// If false, the input lines are treated as infinite lines.
 /// </param>
 /// <returns>
 /// true if a closest point can be calculated and the result passes the tolerance parameter test; otherwise false.
 /// </returns>
 /// <remarks>
 /// If the lines are exactly parallel, meaning the system of equations used to find a and b 
 /// has no numerical solution, then false is returned. If the lines are nearly parallel, which 
 /// is often numerically true even if you think the lines look exactly parallel, then the 
 /// closest points are found and true is returned. So, if you care about weeding out "parallel" 
 /// lines, then you need to do something like the following:
 /// <code lang="cs">
 /// bool rc = Intersect.LineLine(lineA, lineB, out a, out b, tolerance, segments);
 /// if (rc)
 /// {
 ///   double angle_tol = RhinoMath.ToRadians(1.0); // or whatever
 ///   double parallel_tol = Math.Cos(angle_tol);
 ///   if ( Math.Abs(lineA.UnitTangent * lineB.UnitTangent) >= parallel_tol )
 ///   {
 ///     ... do whatever you think is appropriate
 ///   }
 /// }
 /// </code>
 /// <code lang="vb">
 /// Dim rc As Boolean = Intersect.LineLine(lineA, lineB, a, b, tolerance, segments)
 /// If (rc) Then
 ///   Dim angle_tol As Double = RhinoMath.ToRadians(1.0) 'or whatever
 ///   Dim parallel_tolerance As Double = Math.Cos(angle_tol)
 ///   If (Math.Abs(lineA.UnitTangent * lineB.UnitTangent) >= parallel_tolerance) Then
 ///     ... do whatever you think is appropriate
 ///   End If
 /// End If
 /// </code>
 /// </remarks>
 public static bool LineLine(Line lineA, Line lineB, out double a, out double b, double tolerance, bool finiteSegments)
 {
   bool rc = LineLine(lineA, lineB, out a, out b);
   if (rc)
   {
     if (finiteSegments)
     {
       if (a < 0.0)
         a = 0.0;
       else if (a > 1.0)
         a = 1.0;
       if (b < 0.0)
         b = 0.0;
       else if (b > 1.0)
         b = 1.0;
     }
     if (tolerance > 0.0)
     {
       rc = (lineA.PointAt(a).DistanceTo(lineB.PointAt(b)) <= tolerance);
     }
   }
   return rc;
 }
Пример #2
0
    /// <summary>
    /// Gets the parameter along the polyline which is closest to a test-point.
    /// </summary>
    /// <param name="testPoint">Point to approximate.</param>
    /// <returns>The parameter along the polyline closest to testPoint.</returns>
    public double ClosestParameter(Point3d testPoint)
    {
      int count = Count;
      if (count < 2) { return 0.0; }

      int s_min = 0;
      double t_min = 0.0;
      double d_min = double.MaxValue;

      for (int i = 0; i < count - 1; i++)
      {
        Line seg = new Line(this[i], this[i + 1]);
        double d;
        double t;

        if (seg.Direction.IsTiny(1e-32))
        {
          t = 0.0;
          d = this[i].DistanceTo(testPoint);
        }
        else
        {
          t = seg.ClosestParameter(testPoint);
          if (t <= 0.0) { t = 0.0; }
          else if (t > 1.0) { t = 1.0; }
          d = seg.PointAt(t).DistanceTo(testPoint);
        }

        if (d < d_min)
        {
          d_min = d;
          t_min = t;
          s_min = i;
        }
      }

      return s_min + t_min;
    }
Пример #3
0
 public Polyline QuadFaceOffset(Point3d p1, Point3d p2, Point3d p3, Point3d p4, Vector3d N, double distance)
 {
     Point3d cen = (p1 + p2 + p3 + p4) / 4;
     Line lcen = new Line(cen, cen + N);
     double u, v;
     Line l1 = new Line(p1, p2);
     Rhino.Geometry.Intersect.Intersection.LineLine(lcen, l1, out u, out v);
     Vector3d v1 = lcen.PointAt(u) - l1.PointAt(v);
     v1.Unitize(); v1 *= distance;
     l1.Transform(Transform.Translation(v1));
     Line l2 = new Line(p2, p3);
     Rhino.Geometry.Intersect.Intersection.LineLine(lcen, l2, out u, out v);
     v1 = lcen.PointAt(u) - l2.PointAt(v);
     v1.Unitize(); v1 *= distance;
     l2.Transform(Transform.Translation(v1));
     Line l3 = new Line(p3, p4);
     Rhino.Geometry.Intersect.Intersection.LineLine(lcen, l3, out u, out v);
     v1 = lcen.PointAt(u) - l3.PointAt(v);
     v1.Unitize(); v1 *= distance;
     l3.Transform(Transform.Translation(v1));
     Line l4 = new Line(p4, p1);
     Rhino.Geometry.Intersect.Intersection.LineLine(lcen, l4, out u, out v);
     v1 = lcen.PointAt(u) - l4.PointAt(v);
     v1.Unitize(); v1 *= distance;
     l4.Transform(Transform.Translation(v1));
     Polyline output = new Polyline();
     Rhino.Geometry.Intersect.Intersection.LineLine(l1, l4, out u, out v);
     output.Add((l1.PointAt(u) + l4.PointAt(v)) / 2);
     Rhino.Geometry.Intersect.Intersection.LineLine(l2, l1, out u, out v);
     output.Add((l2.PointAt(u) + l1.PointAt(v)) / 2);
     Rhino.Geometry.Intersect.Intersection.LineLine(l3, l2, out u, out v);
     output.Add((l3.PointAt(u) + l2.PointAt(v)) / 2);
     Rhino.Geometry.Intersect.Intersection.LineLine(l4, l3, out u, out v);
     output.Add((l4.PointAt(u) + l3.PointAt(v)) / 2);
     return output;
 }
Пример #4
0
        ///// MeshCreation
        public Mesh MeshWindow(Mesh mesh, double t)
        {
            Mesh output = new Mesh();
            mesh.FaceNormals.ComputeFaceNormals();
            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                MeshFace mf = mesh.Faces[i];
                if (mf.IsTriangle)
                {
                    Point3d p1 = mesh.Vertices[mf.A];
                    Point3d p2 = mesh.Vertices[mf.B];
                    Point3d p3 = mesh.Vertices[mf.C];
                    Line l1 = new Line(p1, p2);
                    Line l2 = new Line(p2, p3);
                    Line l3 = new Line(p3, p1);
                    Vector3d v1 = Vector3d.CrossProduct(p2 - p1, mesh.FaceNormals[i]);
                    v1.Unitize(); v1 *= -t;
                    Vector3d v2 = Vector3d.CrossProduct(p3 - p2, mesh.FaceNormals[i]);
                    v2.Unitize(); v2 *= -t;
                    Vector3d v3 = Vector3d.CrossProduct(p1 - p3, mesh.FaceNormals[i]);
                    v3.Unitize(); v3 *= -t;
                    l1.Transform(Transform.Translation(v1));
                    l2.Transform(Transform.Translation(v2));
                    l3.Transform(Transform.Translation(v3));
                    double t1, t2, t3;
                    Rhino.Geometry.Intersect.Intersection.LineLine(l1, l2, out t1, out t2);
                    p2 = (l1.PointAt(t1) + l2.PointAt(t2)) / 2;
                    Rhino.Geometry.Intersect.Intersection.LineLine(l2, l3, out t2, out t3);
                    p3 = (l3.PointAt(t3) + l2.PointAt(t2)) / 2;
                    Rhino.Geometry.Intersect.Intersection.LineLine(l3, l1, out t3, out t1);
                    p1 = (l1.PointAt(t1) + l3.PointAt(t3)) / 2;
                    int index1 = output.Vertices.Count;
                    output.Vertices.Add(p1);
                    output.Vertices.Add(p2);
                    output.Vertices.Add(p3);

                    output.Faces.AddFace(index1, index1 + 1, index1 + 2);
                }
                if (mf.IsQuad)
                {
                    Point3d p1 = mesh.Vertices[mesh.Faces[i].A];
                    Point3d p2 = mesh.Vertices[mesh.Faces[i].B];
                    Point3d p3 = mesh.Vertices[mesh.Faces[i].C];
                    Point3d p4 = mesh.Vertices[mesh.Faces[i].D];
                    Line l1 = new Line(p1, p2);
                    Line l2 = new Line(p2, p3);
                    Line l3 = new Line(p3, p4);
                    Line l4 = new Line(p4, p1);

                    Vector3d v1 = Vector3d.CrossProduct(p2 - p1, mesh.FaceNormals[i]);
                    v1.Unitize(); v1 *= -t;
                    Vector3d v2 = Vector3d.CrossProduct(p3 - p2, mesh.FaceNormals[i]);
                    v2.Unitize(); v2 *= -t;
                    Vector3d v3 = Vector3d.CrossProduct(p4 - p3, mesh.FaceNormals[i]);
                    v3.Unitize(); v3 *= -t;
                    Vector3d v4 = Vector3d.CrossProduct(p1 - p4, mesh.FaceNormals[i]);
                    v4.Unitize(); v4 *= -t;
                    l1.Transform(Transform.Translation(v1));
                    l2.Transform(Transform.Translation(v2));
                    l3.Transform(Transform.Translation(v3));
                    l4.Transform(Transform.Translation(v4));
                    double t1, t2, t3, t4;
                    Rhino.Geometry.Intersect.Intersection.LineLine(l1, l2, out t1, out t2);
                    p2 = (l1.PointAt(t1) + l2.PointAt(t2)) / 2;
                    Rhino.Geometry.Intersect.Intersection.LineLine(l2, l3, out t2, out t3);
                    p3 = (l3.PointAt(t3) + l2.PointAt(t2)) / 2;
                    Rhino.Geometry.Intersect.Intersection.LineLine(l3, l4, out t3, out t4);
                    p4 = (l4.PointAt(t4) + l3.PointAt(t3)) / 2;
                    Rhino.Geometry.Intersect.Intersection.LineLine(l4, l1, out t4, out t1);
                    p1 = (l1.PointAt(t1) + l4.PointAt(t4)) / 2;

                    int index1 = output.Vertices.Count;
                    output.Vertices.Add(p1);
                    output.Vertices.Add(p2);
                    output.Vertices.Add(p3);
                    output.Vertices.Add(p4);

                    output.Faces.AddFace(index1, index1 + 1, index1 + 2, index1 + 3);
                }

            }
            output.UnifyNormals();
            return output;
        }
Пример #5
0
        /// <summary>
        /// Morphs cell topology to UVWI node map (morphed struts).
        /// </summary>
        public void MorphMapping(UnitCell cell, DataTree<GeometryBase> spaceTree, float[] N)
        {
            for (int u = 0; u <= N[0]; u++)
            {
                for (int v = 0; v <= N[1]; v++)
                {
                    for (int w = 0; w <= N[2]; w++)
                    {
                        // We're inside a unit cell
                        // Loop through all pairs of nodes that make up struts
                        foreach (IndexPair nodePair in cell.NodePairs)
                        {
                            // Prepare the path of the nodes (path in tree)
                            // First, get relative paths of nodes (with respect to current unit cell)
                            int[] IRel = cell.NodePaths[nodePair.I];
                            int[] JRel = cell.NodePaths[nodePair.J];
                            // Next, compute absolute paths
                            GH_Path IPath = new GH_Path(u + IRel[0], v + IRel[1], w + IRel[2]);
                            GH_Path JPath = new GH_Path(u + JRel[0], v + JRel[1], w + JRel[2]);

                            // Make sure the cell exists
                            // No cells exist beyond the boundary + 1
                            if (Nodes.PathExists(IPath) && Nodes.PathExists(JPath))
                            {
                                LatticeNode node1 = Nodes[IPath, IRel[3]];
                                LatticeNode node2 = Nodes[JPath, JRel[3]];
                                // Make sure both nodes exist:
                                // Null nodes either belong to other cells, or are beyond the upper uvw boundary.
                                if (node1 != null && node2 != null)
                                {
                                    GH_Path spacePath;

                                    // If strut is along boundary, we must use the previous morph space 
                                    // Since one does not exist beyond the boundary) 
                                    if (u == N[0] && v == N[1])
                                    {
                                        spacePath = new GH_Path(u - 1, v - 1);
                                    }
                                    else if (u == N[0])
                                    {
                                        spacePath = new GH_Path(u - 1, v);
                                    }
                                    else if (v == N[1])
                                    {
                                        spacePath = new GH_Path(u, v - 1);
                                    }                                        
                                    else
                                    {
                                        spacePath = new GH_Path(u, v);
                                    }

                                    // Retrieve uv cell space (will be casted in the tempPt loop)
                                    GeometryBase ss1 = spaceTree[spacePath, 0];
                                    GeometryBase ss2 = spaceTree[spacePath, 1];

                                    // Discretize the unit cell line for morph mapping
                                    int ptCount = 16;
                                    // Template points are unitized cell points (x,y of these points are u,v of sub-surface)
                                    var templatePts = new List<Point3d>();  
                                    Line templateLine = new Line(cell.Nodes[nodePair.I], cell.Nodes[nodePair.J]);
                                    for (int ptIndex = 0; ptIndex <= ptCount; ptIndex++)
                                    {
                                        templatePts.Add(templateLine.PointAt(ptIndex / (double)ptCount));
                                    }

                                    // We will map the lines' points to its uvw cell-space
                                    // Control points are the interpolation points in space
                                    var controlPoints = new List<Point3d>();

                                    foreach (Point3d tempPt in templatePts)
                                    {
                                        Point3d surfPt;
                                        Vector3d[] surfDerivs;
                                        // UV params on unitized sub-surface are simply the xy coordinate of the template point
                                        double uParam = tempPt.X;
                                        double vParam = tempPt.Y;
                                        // If at boundary, we're using a previous morph space, so reverse the parameter(s)
                                        if (u == N[0])
                                        {
                                            uParam = 1 - uParam;
                                        }
                                        if (v == N[1])
                                        {
                                            vParam = 1 - vParam;
                                        }

                                        // Now, we will map the template point to the uvw-space
                                        ((Surface)ss1).Evaluate(uParam, vParam, 0, out surfPt, out surfDerivs);
                                        Vector3d wVect = Vector3d.Unset;
                                        switch (ss2.ObjectType)
                                        {
                                            case ObjectType.Point:
                                                wVect = ((Point)ss2).Location - surfPt; ;
                                                break;
                                            case ObjectType.Curve:
                                                wVect = ((Curve)ss2).PointAt(uParam) - surfPt;
                                                break;
                                            case ObjectType.Surface: 
                                                Point3d surfPt2;
                                                Vector3d[] surfDerivs2;
                                                ((Surface)ss2).Evaluate(uParam, vParam, 0, out surfPt2, out surfDerivs2);
                                                wVect = surfPt2 - surfPt;
                                                break;
                                        }
                                        // The mapped point
                                        Point3d uvwPt = surfPt + wVect * (w + tempPt.Z) / N[2];
                                        controlPoints.Add(uvwPt);

                                    }

                                    // Now create interpolated curve based on control points
                                    Curve curve = Curve.CreateInterpolatedCurve(controlPoints, 3);

                                    if (curve != null && curve.IsValid)
                                    {
                                        Struts.Add(curve);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #6
0
 public void intersect(Plane p)
 {
     for (int i = 0; i < pts.Count; i++)
     {
         double db = p.DistanceTo(pts[i].pos);
         if (Math.Abs(db) < RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) { pts[i].condition = 1; }
         else if (db > 0) { pts[i].condition = 2; }
         else if (db < 0) { pts[i].condition = 0; }
     }
     ///////////////////////
     int ii = 0;
     while (ii < edges.Count)
     {
         if (edges[ii].p1.condition == 0 && edges[ii].p2.condition == 0)
         {
             edges.RemoveAt(ii);
         }
         else if (edges[ii].p1.condition == 1 && edges[ii].p2.condition == 0)
         {
             edges.RemoveAt(ii);
         }
         else if (edges[ii].p1.condition == 1 && edges[ii].p2.condition == 1)
         {
             edges.RemoveAt(ii);
         }
         else if (edges[ii].p1.condition == 0 && edges[ii].p2.condition == 1)
         {
             edges.RemoveAt(ii);
         }
         else if (edges[ii].p1.condition == 0 && edges[ii].p2.condition == 2)
         {
             double u; Line line = new Line(edges[ii].p1.pos, edges[ii].p2.pos);
             Rhino.Geometry.Intersect.Intersection.LinePlane(line, p, out u);
             pts.Add(new vertex(line.PointAt(u), this.center.DistanceTo(line.PointAt(u))));
             edges[ii].p1 = pts[pts.Count - 1];
             ii++;
         }
         else if (edges[ii].p1.condition == 2 && edges[ii].p2.condition == 0)
         {
             double u; Line line = new Line(edges[ii].p1.pos, edges[ii].p2.pos);
             Rhino.Geometry.Intersect.Intersection.LinePlane(line, p, out u);
             pts.Add(new vertex(line.PointAt(u), this.center.DistanceTo(line.PointAt(u))));
             edges[ii].p2 = pts[pts.Count - 1];
             ii++;
         }
         else { ii++; }
     }
     clearnull();
     //////////////////////////////////
     Transform w2p = Transform.PlaneToPlane(Plane.WorldXY, p);
     Transform p2w = Transform.PlaneToPlane(p, Plane.WorldXY);
     Grasshopper.Kernel.Geometry.Node2List ls = new Grasshopper.Kernel.Geometry.Node2List();
     List<int> count = new List<int>();
     for (int i = 0; i < pts.Count; i++)
     {
         if (pts[i].condition == 1 || pts[i].condition == -1)
         {
             pts[i].pos.Transform(w2p);
             ls.Append(new Grasshopper.Kernel.Geometry.Node2(pts[i].pos.X, pts[i].pos.Y));
             pts[i].pos.Transform(p2w);
             count.Add(i);
         }
     }
     if (count.Count == 2) edges.Add(new edge(pts[count[0]], pts[count[1]]));
     else if (count.Count > 2)
     {
         List<int> count2 = new List<int>();
         Grasshopper.Kernel.Geometry.ConvexHull.Solver.Compute(ls, count2);
         for (int i = 0; i < count2.Count; i++)
         {
             int c = i + 1; if (c == count2.Count) c = 0;
             edges.Add(new edge(pts[count[count2[i]]], pts[count[count2[c]]]));
         }
     }
 }