How to get only the true intersection points of lines in Python 3?

Hi,

I am new to Python. I am trying to get some points of line intersections with rhynoscriptsyntax. Therefore, I simply used LineLineIntersection(), but the result is actually a bunch of other points generated without line intersections (it is shown in the help tab about the LineLineIntersection() process, but I do not get the idea…):

import rhinoscriptsyntax as rs
import math as mt
import numpy as np
import itertools as it

center=rs.CreatePoint(xaxis,yaxis)
def elp1(t):
    x = a * mt.cos(t)+xaxis
    y = b * mt.sin(t)+yaxis
    return [x,y]

def elp2(t):
    x = b * mt.cos(t)+xaxis
    y = a * mt.sin(t)+yaxis
    return [x,y]

domain=np.linspace(0, mt.pi*2, n, False).tolist()

ellipse1=[]
for i in domain:
    ellipse1.append(rs.CreatePoint(elp1(i)[0],elp1(i)[1]))

ellipse2=[]
for i in domain:
    ellipse2.append(rs.CreatePoint(elp2(i)[0],elp2(i)[1],h))

ellipse2r=rs.RotateObjects(ellipse2,center, 180, None, False)

lines=[]
for i in ellipse1:
    lines.append(rs.AddLine(i,ellipse2[ellipse1.index(i)]))

iterator=list(it.combinations(lines,2))

intersections=[]
for i in iterator:
        intersections.append(rs.LineLineIntersection(i[0],i[1]))

chaininter=[]
for i in intersections:
    for j in i:
        chaininter.append(j)

cullpts=rs.CullDuplicatePoints(chaininter)

(the script is trying to generate a type of hyperboloid of revolution, and there are some intersecting lines in this ruled surface type, as you can see in this video, at minute 41:15.


(as you can see in the image, there is points generated not from intersections, actually)

In other words, how does the LineLineIntersection() function work and how to get only the true intersection points of lines?

kind of a hyperboloid of revolution.gh (13.6 KB)

Thanks in advance!

It looks like the rhinoscriptsyntax function doesn’t implement the RhinoCommon overload that has the finiteSegments input parameter (i.e. you might use that instead):

Vs:

Also, I changed to headline a bit (GhPython is the older IronPython component).

Edit: Just looked up the source code. Indeed the rhinoscriptsyntax function uses the basic overload:

1 Like

Try to translate (general case: objects of Type Curve) this:

ClearTextDots();

    cList = cList.Where(x => x != null && x.IsValid).ToList();
    if(!cList.Any()) return;

    if(respectEpsilon) {Print("Note: End/End ccx events are also skipped"); Print(" ");}

    //----------------------------------------------------------------------------
    Init();
    ShatterCurvesCommon(cList, respectEpsilon, reportSkipped);
    CTree = cTree;
    PTree = pTree;
    TTree = tTree;
    isolatedCurves = isolatedCrvs;
    if(isolatedCrvs.Any()) GetDots(dotC, dotH);
 private void ClearTextDots(){
    RhinoObject[] objsPrev = RhinoDocument.Objects.FindByUserString("TextDot", Component.ComponentGuid.ToString(), false, false, true, ObjectType.TextDot);
    if (objsPrev != null){
      foreach (RhinoObject obj in objsPrev)RhinoDocument.Objects.Delete(obj, true);
    }
  }

  public DataTree<Curve> cTree;
  public DataTree<Point3d> pTree;
  public DataTree<double> tTree;
  public List<Curve> isolatedCrvs;

  static double tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;

  public void Init(){
    cTree = new DataTree<Curve>();
    pTree = new DataTree<Point3d>();
    tTree = new DataTree<double>();
    isolatedCrvs = new List<Curve>();
  }

  public void ShatterCurvesCommon(List < Curve > cList, bool respectTol, bool report){

    bool[] isolated = new bool[cList.Count];
    for (int i = 0; i < cList.Count; i++) {

      List<double> T = new List<double>();
      List<Point3d> P = new List<Point3d>();

      Curve curr = cList[i];
      for (int j = 0; j <= cList.Count - 1; j++) {
        if (i == j || isolated[j]) continue;
        Curve other = cList[j];
        var events = Rhino.Geometry.Intersect.Intersection.CurveCurve(curr, other, tol, tol);
        if (events != null){
          for (int ev = 0; ev < events.Count; ev++){
            var ccx_event = events[ev];
            if(respectTol){
              if (ccx_event.PointA.DistanceTo(ccx_event.PointB) > double.Epsilon){
                T.Add(ccx_event.ParameterA);
                P.Add(ccx_event.PointA);
              }
              else if(report)Print("Skipped ccx at: {0,-2}, {1}", i, j);
            }
            else{
              T.Add(ccx_event.ParameterA);
              P.Add(ccx_event.PointA);
            }
          }
        }
      }

      if(T.Any()){
        double[] TA = T.ToArray(); Point3d[] PA = P.ToArray();
        Array.Sort(TA, PA);

        Curve[] pieces = curr.Split(TA);
        cTree.AddRange(pieces, new GH_Path(i));
        tTree.AddRange(TA, new GH_Path(i));
        pTree.AddRange(PA, new GH_Path(i));
      }
      else{
        isolated[i] = true;
        isolatedCrvs.Add(curr);
        Print("Crv: {0,-2} is isolated", i);

        cTree.Add(curr, new GH_Path(i));
        tTree.EnsurePath(new GH_Path(i));
        pTree.EnsurePath(new GH_Path(i));
      }
    }
  }

  public void GetDots(Color C, int H){
    List<TextDot> dots = new List<TextDot>();
    foreach(GH_Path path in tTree.Paths){
      List<double> tv = tTree.Branch(path);
      if(tv.Any()) continue;
      Curve crv = cTree.Branch(path)[0];
      Point3d p = crv.PointAtNormalizedLength(0.5);
      TextDot dot = new TextDot(path.ToString(false), p); dot.FontHeight = H;
      dots.Add(dot);
    }

    Rhino.DocObjects.ObjectAttributes attr = new Rhino.DocObjects.ObjectAttributes();
    attr.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject;
    attr.ObjectColor = C;
    attr.SetUserString("TextDot", Component.ComponentGuid.ToString());

    for(int i = 0;i < dots.Count;i++){
      doc.Objects.AddTextDot(dots[i], attr);
    }
  }


2 Likes

Here’s a quick go:


kind of a hyperboloid of revolution_Anders.gh (15.4 KB)

1 Like

Sorry, I did not even know about it.

That’s great!

I think I will need some time to decode this. :astonished: But, the script, as I could see, returns a lot of other interesting information about the lines, although this data is not needed for me at the moment. Thank you very much!

Thank you, Anders, I will use that for now!

1 Like