Community
Civil 3D Customization
Welcome to Autodesk’s AutoCAD Civil 3D Forums. Share your knowledge, ask questions, and explore popular AutoCAD Civil 3D Customization topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Selecting a Civil 3D Corridor Feature Line

15 REPLIES 15
Reply
Message 1 of 16
andrew_milford
1868 Views, 15 Replies

Selecting a Civil 3D Corridor Feature Line

 

I'm looking to simply select a corridor feature line through the API. The following code generates an IndexOutOfRangeException.

Has anybody successfully selected a feature line from within a corridor object?

 

Thanks in advance

 

Andrew

 

public static bool SelectValidFeatureLine()
{
// Get the AutoCAD Editor
Editor ed = acApp.Application.DocumentManager.MdiActiveDocument.Editor;

 

// Select a feature line from a corridor
PromptEntityOptions selFL = new PromptEntityOptions("\nSelect Corridor Feature Line: ");
selFL.SetRejectMessage("\nOnly a Corridor Feature Line Object is allowed.");
selFL.AddAllowedClass(typeof(CorridorFeatureLine), true); // Errors here

PromptEntityResult resFL = ed.GetEntity(selFL);

if (resFL.Status != PromptStatus.OK) return false;

featureID = resFL.ObjectId;
return true;
}

Regards

Andrew Milford
Sr. Product Manager
Autodesk Pty Ltd
100 Commercial St,
Manchester NH 03101

15 REPLIES 15
Message 2 of 16
kbarnettza
in reply to: andrew_milford

I need the same ... to get the name of the FeaureLine on selecting it when it is part of a Corridor ... I guess that the code Andrew tried will only provide the Parent on GetEntity ... which is the Corridor. ... I guess we can only use the position of the get entity result to discover the name of the FeatureLine .. correct?

 

Message 3 of 16
hippe013
in reply to: andrew_milford

selFL.AddAllowedClass(GetType(CorridorFeatureLine), True)

 

 

 

Please disregard my above suggestion. I see the error that you are getting now.

 

 

Message 4 of 16
hippe013
in reply to: andrew_milford

The following worked for me. Sorry its in VB.net.

 

<CommandMethod("CorFLSelect")> _
        Public Sub CorFlSelect() ' This method can have any name
            Dim aDoc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = aDoc.Editor
            Dim db As Database = aDoc.Database

            Dim Opts As New PromptEntityOptions(vbCrLf + "Select Corridor Feature Line: ")
            Opts.SetRejectMessage(vbCrLf + "Only a Corridor Feature Line Object is Allowed.")
            Opts.AddAllowedClass(GetType(FeatureLine), False)

            Dim res As PromptEntityResult = ed.GetEntity(Opts)

            If res.Status = PromptStatus.OK Then
                ed.WriteMessage(vbCrLf + "All is Good in the World.")
            Else
                ed.WriteMessage(vbCrLf + "All is NOT Good in the World.")
            End If

        End Sub
Message 5 of 16
kbarnettza
in reply to: hippe013

: (   just tried that ... its not working for me, attached example corridor DWG, feature lines are yellow (Lane Point Code), Named View: 1.

Hip... please attach a Corridor DWG that worked with the code you used. Or .. maybe I have a variable value set incorrectly?

 

R10I.png

Message 6 of 16
hippe013
in reply to: kbarnettza

In the OP's original post he was trying to 'AddAllowedClass(typeof(CorridorFeatureLine),true)'. That is where his error was coming up. I suggested that he 'AddAllowedClass(typeof(FeatureLine), false)'. It is becoming apparent to me that the intention is to select a corridor to extract the feature line from the corridor. In which case one should use 'AddAllowedClass(typeof(Corridor), true)'. Then we need to work on what the OP (I'm assuming) originally wanted to achieve, which is to extract the corridor feature line by selecting a corridor. I'll wait for the OP to confirm this.

Message 7 of 16
andrew_milford
in reply to: hippe013

You are right, I am trying to select a feature line from within a corridor, extract its values and either report the values (or even display them in a profile view).

 

I have tried the code above, but unfortunately had no luck.

 

The main problem is that if just select a corridor object, I cannot dig into the corridor to extract the corridorfeatureline object.

 

 

Regards

Andrew Milford
Sr. Product Manager
Autodesk Pty Ltd
100 Commercial St,
Manchester NH 03101

Message 8 of 16

Here is some old code from the Civil 3D Reminders Pack. I haven't tested it since Civil 3D 2010. It's in COM, but the .NET version should be similar.

 

' (C) Copyright 2009 by Christopher Fugitt, Parts modified.
' (C) Copyright 2009 by Autodesk, Inc. 
'
' Permission to use, copy, modify, and distribute this software in
' object code form for any purpose and without fee is hereby granted, 
' provided that the above copyright notice appears in all copies and 
' that both that copyright notice and the limited warranty and
' restricted rights notice below appear in all supporting 
' documentation.
'
' AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. 
' AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
' MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. 
' DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
' UNINTERRUPTED OR ERROR FREE.
'
' Use, duplication, or disclosure by the U.S. Government is subject to 
' restrictions set forth in FAR 52.227-19 (Commercial Computer
' Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
' (Rights in Technical Data and Computer Software), as applicable.
'

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.Civil.Roadway.DatabaseServices
Imports Autodesk.AECC.Interop.Roadway
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports System.Collections.Generic
Imports Autodesk.AutoCAD.Geometry
Imports Quux.C3DUtilities

<Assembly: CommandClass(GetType(XrefCorridor3DpolylineApplication))> 

Public Class XrefCorridor3DpolylineApplication

    ' Here's where the heavy lifting happens...
    <CommandMethod("C3DRXREFCorridor3DPolyline")> _
    Public Sub XREFCorridor3DPoly()

        ' Have the user select a corridor.
        Try
            Dim oCivil As New AeccAppConnection

            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor

            Dim sPrompt As String = "Select corridor: "
            Dim entopts As New PromptEntityOptions(sPrompt)
            entopts.Message = sPrompt
            Dim entRes As PromptEntityResult = Nothing

            Try
                entRes = ed.GetEntity(entopts)
            Catch
                ed.WriteMessage("You did not select a valid entity")
            End Try

            If entRes.Status = PromptStatus.OK Then
                Dim tr As Transaction = db.TransactionManager.StartTransaction()
                Using tr
                    ' First get the currently selected object
                    ' and check whether it's a block reference
                    Dim objId As ObjectId = entRes.ObjectId

                    Dim br As BlockReference = TryCast(tr.GetObject(objId, OpenMode.ForRead), BlockReference)
                    If br IsNot Nothing Then
                        ' If so, we check whether the block table record
                        ' to which it refers is actually from an XRef

                        Dim btrId As ObjectId = br.BlockTableRecord
                        Dim btr As BlockTableRecord = TryCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)
                        If btr IsNot Nothing Then
                            If btr.IsFromExternalReference Then
                                ' If so, then we programmatically select the object
                                ' underneath the pick-point already used

                                Dim pneo As New PromptNestedEntityOptions("")
                                pneo.NonInteractivePickPoint = entRes.PickedPoint
                                pneo.UseNonInteractivePickPoint = True

                                Dim pner As PromptNestedEntityResult = ed.GetNestedEntity(pneo)

                                If pner.Status = PromptStatus.OK Then
                                    Try
                                        Dim selId As ObjectId = pner.ObjectId

                                        ' Let's look at this programmatically-selected
                                        ' object, to see what it is

                                        Dim obj As DBObject = tr.GetObject(selId, OpenMode.ForRead)

                                        ' Check to see if the object is a corridor, if it is not then exit the code.
                                        If Not (TypeOf obj Is Corridor) Then
                                            Exit Sub
                                        End If

                                        Dim ent As Entity = DirectCast(obj, Entity)
#If C3D2010 Then
                                        Dim objCorr As Object = oCivil.AeccDoc.ObjectIdToObject(CType(ent.ObjectId.OldIdPtr, Integer))
#Else
                                        Dim objCorr As Object = oCivil.AeccDoc.ObjectIdToObject(CType(ent.ObjectId.OldIdPtr, Long))
#End If


                                        Dim oCorridor As AeccCorridor
                                        oCorridor = objCorr

                                        ' Open the block table record for the current drawing.
                                        Dim oBlockTable As BlockTable
                                        oBlockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead)

                                        Dim oBTR As BlockTableRecord
                                        oBTR = tr.GetObject(oBlockTable(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                                        '''''''''''''''''''''''''''''''''''''''''''''''''''''''
                                        ' Need to add code here to prompt for code and then extract
                                        ' the 3DPolylines.
                                        Dim sCode As String
                                        Dim pr As PromptResult
                                        pr = ed.GetString(vbCrLf & "Enter code to extract: ")
                                        If pr.Status = PromptStatus.OK Then
                                            sCode = pr.StringResult
                                            Dim oBaseline As AeccBaseline
                                            For Each oBaseline In oCorridor.Baselines
                                                Dim oFeatureLines As AeccFeatureLines
                                                ' MsgBox(oBaseline.MainBaselineFeatureLines.FeatureLinesCol.Count)
                                                For Each oFeatureLines In oBaseline.MainBaselineFeatureLines.FeatureLinesCol
                                                    Dim oFeatureLine As AeccFeatureLine
                                                    For Each oFeatureLine In oFeatureLines
                                                        If String.Compare(oFeatureLine.CodeName, sCode, True) = 0 Then
                                                            Dim oFeatureLinePts As AeccFeatureLinePoints = oFeatureLine.FeatureLinePoints

                                                            Dim oFeatureLinePt As AeccFeatureLinePoint
                                                            Dim oPts As Point3dCollection = New Point3dCollection
                                                            For Each oFeatureLinePt In oFeatureLinePts
                                                                ' add the points of the feature line to the collection
                                                                oPts.Add(New Point3d(oFeatureLinePt.XYZ(0), oFeatureLinePt.XYZ(1), oFeatureLinePt.XYZ(2)))
                                                            Next

                                                            ' Create the 3DPolyline
                                                            Dim oPoly3d As New Polyline3d(New Poly3dType(), oPts, False)
                                                            oPoly3d.SetDatabaseDefaults()

                                                            ' Add the new object to the block table record and the transaction
                                                            oBTR.AppendEntity(oPoly3d)
                                                            tr.AddNewlyCreatedDBObject(oPoly3d, True)
                                                        End If
                                                    Next
                                                Next
                                            Next

                                        Else
                                            ed.WriteMessage(vbCrLf & "Incorrect entry")
                                            Exit Sub
                                        End If
                                    Catch
                                        tr.Abort()

                                    End Try
                                End If
                            End If
                        End If
                    End If
                    tr.Commit()
                End Using
            End If
        Catch ex As Exception

        End Try
    End Sub

End Class
Message 9 of 16
glaslp
in reply to: Civil3DReminders

Hi

is there now a stable solution which can be published?

Message 10 of 16

The source code may be found on this page: http://style.civil3dreminders.com/civil3dreminderspack feel free to download it, update the references, and rebuild using Visual Studio. 

 

The command is improved and in the SincPac where the Civil 3D Reminders went to live in retirement. http://quuxsoft.com/SincpacC3D_Download.aspx

Civil Reminders
http://blog.civil3dreminders.com/
http://www.CivilReminders.com/
Alumni
Message 11 of 16

Thanks - there is a lot of powerful stuff there Smiley Happy

Message 12 of 16

Many thanks Chris,

 

There are some nice examples in here.

 

I'm still looking into selecting an individual corridor feature line. I'm still looking into various ways to achieve this. So far, the PointMonitor is able to detect the featurelines under a selected point on a corridor, but I still need a way to drill down into the CorridorFeatureline itself.

 

The other method I am investigating is using a pickbox selection, drawing a crossing window around the pickbox, and then checking for an intersect of the individual featurelines (extracted as a 3d point collection).

 

 

 

Regards

Andrew Milford
Sr. Product Manager
Autodesk Pty Ltd
100 Commercial St,
Manchester NH 03101

Message 13 of 16
glaslp
in reply to: andrew_milford
Message 14 of 16
hippe013
in reply to: andrew_milford

@andrew.milford

 

We are able to get to the CorridorFeatureLines from the corridor itself.

 

 Dim cor As Corridor = trans.GetObject(res.ObjectId, OpenMode.ForWrite) 'Get the Corridor from Selection
Dim BaseLines As BaselineCollection = cor.Baselines 'Get the Baselines Collection
Dim Baseline As Baseline = BaseLines(0) 'For my Example I am grabbing the first one.
Dim MainBLFL As BaselineFeatureLines = Baseline.MainBaselineFeatureLines 'Get the MainBaselineFeatureLines
Dim FLColMap As FeatureLineCollectionMap = MainBLFL.FeatureLineCollectionMap 'Get the FeaturelineCollectionMap
Dim fl0 As FeatureLineCollection = FLColMap.Item(0) 'In my example this is Point Code "CL"
Dim fl1 As FeatureLineCollection = FLColMap.Item(1) 'In my example this is Point Code "EOR"
Dim fl_0 As CorridorFeatureLine = fl1(0) 'In my example this is Point Code "EOR" "Right"
Dim fl_1 As CorridorFeatureLine = fl1(1) 'In my example this is Point Code "EOR" "Left"
Dim objId As ObjectId = fl_1.ExportAsGradingFeatureLine(civilDoc.GetSiteIds(0), True) 'Extracted Corridor Featureline

 

 

I hope this helps what you were looking for. I was able to extract a feaureline from a selected corridor using the above code. Now the problem is to have the mouse select the appropriate featureline as you stated using PointMonitor or pickbox testing. 

Message 15 of 16
hippe013
in reply to: andrew_milford

 So far, the PointMonitor is able to detect the featurelines under a selected point on a corridor

 

Can you post this code?

 

I have created and tested the following functions for extracting a CorridorFeatureline from a Corridor.

 

Public Function ExtractAllFeaturelines(ByVal CorridorObjId As ObjectId, ByVal SiteObjId As ObjectId, ByVal isDynamic As Boolean) As Boolean
 Dim aDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
 Dim ed As Editor = aDoc.Editor
 Dim db As Database = aDoc.Database
 Dim extracted As Boolean = False
 Dim civilDoc As CivilDocument = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument
Using trans As Transaction = db.TransactionManager.StartTransaction Try Dim cor As Corridor = trans.GetObject(CorridorObjId, OpenMode.ForRead) For Each Baseline As Baseline In cor.Baselines Dim MainBlFl As BaselineFeatureLines = Baseline.MainBaselineFeatureLines Dim FlColMap As FeatureLineCollectionMap = MainBlFl.FeatureLineCollectionMap For Each FlCol As FeatureLineCollection In FlColMap For Each CorFl As CorridorFeatureLine In FlCol CorFl.ExportAsGradingFeatureLine(SiteObjId, isDynamic) extracted = True Next Next Next trans.Commit() If extracted Then Return True Else Return False End If Catch ex As Autodesk.AutoCAD.Runtime.Exception Return False End Try End Using End Function


Public Function ExtractFeaturelinesByCode(ByVal CorridorObjId As ObjectId, ByVal SiteObjId As ObjectId, ByVal isDynamic As Boolean, ByVal PointCode As String) As Boolean Dim aDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim ed As Editor = aDoc.Editor Dim db As Database = aDoc.Database Dim extracted As Boolean = False Dim civilDoc As CivilDocument = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument Using trans As Transaction = db.TransactionManager.StartTransaction Try Dim cor As Corridor = trans.GetObject(CorridorObjId, OpenMode.ForRead) For Each Baseline As Baseline In cor.Baselines Dim MainBlFl As BaselineFeatureLines = Baseline.MainBaselineFeatureLines Dim FlColMap As FeatureLineCollectionMap = MainBlFl.FeatureLineCollectionMap For Each FlCol As FeatureLineCollection In FlColMap For Each CorFl As CorridorFeatureLine In FlCol If CorFl.CodeName = PointCode Then CorFl.ExportAsGradingFeatureLine(SiteObjId, isDynamic) extracted = True End If Next Next Next trans.Commit() If extracted Then Return True Else Return False End If Catch ex As Autodesk.AutoCAD.Runtime.Exception Return False End Try End Using End Function


Message 16 of 16
andrew_milford
in reply to: hippe013

Thanks for your suggestion Hippe013, I will try that out shortly.

 

First, with regards to the PointMonitor, I simply lifted code from the Devblog, see link below

http://through-the-interface.typepad.com/through_the_interface/2009/07/providing-information-on-auto...

 

This approach looked cool, but would not actually let me select an item, nor did it drill down into the CorridorFeatureLines

 

 

In the meantime, I have successfully managed to pick out a CorridorFeaturelLine from a corridor model. I first allow the user to select a corridor item, then draw a pickbox in screen units using the PICKBOX system variable.

 

I them enumerate through all CorridorFeatureLines, checking each segment against the new pickbox entities. If there is an intersection, I store the CFL into a new list. 

This list is then shown in a new dialog, where the user selects the line they want.

 

I'm still looking into improving the intersection checking (something like line.IntersectsWith())? , but check out the code below and let me know what you think.

 

 

        [CommandMethod("FLSelect")]
        public void FLSelect()
        {
            // Have the user select a corridor.
            try
            {
                // Get the AutoCAD Editor
                acApp.Document doc = acApp.Application.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                Database acCurDb = doc.Database;

                string sPrompt = "Select corridor:";
                PromptEntityOptions entOpts = new PromptEntityOptions(sPrompt);
                entOpts.Message = sPrompt;
                PromptEntityResult entRes = null;
                
                try
                {
                    entRes = ed.GetEntity(entOpts);
                }
                catch (System.Exception)
                {
                    ed.WriteMessage("You did not select a valid entity\n");
                    throw;
                }

                if (entRes.Status == PromptStatus.OK)
                {
                    //Transaction acTrans = acCurDb.TransactionManager.StartTransaction();


                    FeatureLineInstanceRepository featureLineRepo = new FeatureLineInstanceRepository();
                    featureLineRepo.ExtractFeatureLines(entRes.ObjectId, acCurDb, ed);

                    
                    using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                    {
                        // First get the currently selected object
                        Point3d screenPt = entRes.PickedPoint;
                        ObjectId objId = entRes.ObjectId;

                        // Get pickbox's size. Note, the number obtained from
                        // system variable "PICKBOX" is actually the half of
                        // pickbox's width/height
                        object pBox = acApp.Application.GetSystemVariable("PICKBOX");
                        int pSize = Convert.ToInt32(pBox);

                        int viewPortNumber = Convert.ToInt32(Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("cvport").ToString());

                        // Define a Point3dCollection for CrossingWindow selecting
                        Point3dCollection points = new Point3dCollection();

                        System.Windows.Point pScreen;
                        System.Windows.Point p;
                        Point3d pt;

                        pScreen = ed.PointToScreen(screenPt, viewPortNumber);
                        
                        p = new System.Windows.Point(pScreen.X - pSize, pScreen.Y - pSize);
                        pt = ed.PointToWorld(p, viewPortNumber);
                        points.Add(pt);

                        p = new System.Windows.Point(pScreen.X + pSize, pScreen.Y - pSize);
                        pt = ed.PointToWorld(p, viewPortNumber);
                        points.Add(pt);

                        p = new System.Windows.Point(pScreen.X + pSize, pScreen.Y + pSize);
                        pt = ed.PointToWorld(p, viewPortNumber);
                        points.Add(pt);

                        p = new System.Windows.Point(pScreen.X - pSize, pScreen.Y + pSize);
                        pt = ed.PointToWorld(p, viewPortNumber);
                        points.Add(pt);

                        
                        // pickbox cross window lines
                        Line pickBoxLine1 = new Line(new Point3d(points[0].X, points[0].Y, 0.0), 
                            new Point3d(points[2].X, points[2].Y, 0.0));  
                        Line pickBoxLine2 = new Line(new Point3d(points[1].X, points[1].Y, 0.0), 
                            new Point3d(points[3].X, points[3].Y, 0.0));  

                        // Loop through each item in the feature line list
                        foreach (FeatureLineInstance item in featureLineRepo.FeatureLineRepository)
                        {
                            bool intFound = false;

                            // Loop through each segment of the featureline
                            for (int i = 0; i < item.Points.Count - 1; i++)
                            {
                                Point3d pt1 = new Point3d(item.Points[i].X, item.Points[i].Y, 0.0);
                                Point3d pt2 = new Point3d(item.Points[i + 1].X, item.Points[i + 1].Y, 0.0);
                                Line lineSegment = new Line(pt1, pt2);

                                PointXYZ ptInt = new PointXYZ();
                                intFound |= DoLinesIntersect(pickBoxLine1, lineSegment, ref ptInt);
                                intFound |= DoLinesIntersect(pickBoxLine2, lineSegment, ref ptInt);
                                if (intFound == true && item.Name != "None")
                                {
                                    // Add featureline to FeatureLineUnderPickbox
                                    featureLineRepo.FeatureLineUnderPickbox.Add(item);
                                    ed.WriteMessage($"Found String: {item.Name}\n");
                                    break;
                                }
                            }
                        }

                        // Add the values to a datagridview
                        if (featureLineRepo.FeatureLineUnderPickbox.Count == 1)
                        {
                            ed.WriteMessage("You have selected: " + featureLineRepo.FeatureLineUnderPickbox[0].Name + "\n");
                            ed.WriteMessage("   and it contains " + featureLineRepo.FeatureLineUnderPickbox[0].Points.Count.ToString() + " point\n");

                        }
                        else if (featureLineRepo.FeatureLineUnderPickbox.Count > 1)
                        {
                            // create a new form
                            frmSelectFeatureLine frmSFL = new frmSelectFeatureLine(featureLineRepo.FeatureLineUnderPickbox);
                            acApp.Application.ShowModalDialog(frmSFL);
                        }

                        


                        // You can also use GetPoint and use after Editor.SelectCrossingWindow with a 
                        // small window centered on the point to get the entity
                        // (but you are not sure to get a single entity).
                        // To set the size of the window, you can use the PICKBOX system variable. You need to make a conversion pixel->world units.

                        //The safe way is to use GetEntity to get the entity, then GetPoint to get the break point.


                        acTrans.Commit();
                    }


                }
              
            }
            catch (System.Exception ex)
            {

            }
        }



        /// <summary>
        /// This is based off an explanation and expanded math presented by Paul Bourke:
        /// 
        /// It takes two lines as inputs and returns true if they intersect, false if they 
        /// don't.
        /// If they do, ptIntersection returns the point where the two lines intersect.  
        /// </summary>
        /// <param name="L1">The first line</param>
        /// <param name="L2">The second line</param>
        /// <param name="ptIntersection">The point where both lines intersect (if they do).</param>
        /// <returns></returns>
        /// http://paulbourke.net/geometry/lineline2d/
        /// http://paulbourke.net/geometry/lineline2d/Helpers.cs
        /// <remarks>See http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/</remarks>
        public static bool DoLinesIntersect(Line L1, Line L2, ref PointXYZ ptIntersection)
        {
            
            // Denominator for ua and ub are the same, so store this calculation
            double d =
               (L2.EndPoint.Y - L2.StartPoint.Y) * (L1.EndPoint.X - L1.StartPoint.X)
               -
               (L2.EndPoint.X - L2.StartPoint.X) * (L1.EndPoint.Y - L1.StartPoint.Y);

            //n_a and n_b are calculated as seperate values for readability
            double n_a =
               (L2.EndPoint.X - L2.StartPoint.X) * (L1.StartPoint.Y - L2.StartPoint.Y)
               -
               (L2.EndPoint.Y - L2.StartPoint.Y) * (L1.StartPoint.X - L2.StartPoint.X);

            double n_b =
               (L1.EndPoint.X - L1.StartPoint.X) * (L1.StartPoint.Y - L2.StartPoint.Y)
               -
               (L1.EndPoint.Y - L1.StartPoint.Y ) * (L1.StartPoint.X - L2.StartPoint.X);

            // Make sure there is not a division by zero - this also indicates that
            // the lines are parallel.  
            // If n_a and n_b were both equal to zero the lines would be on top of each 
            // other (coincidental).  This check is not done because it is not 
            // necessary for this implementation (the parallel check accounts for this).
            if (d == 0)
                return false;

            // Calculate the intermediate fractional point that the lines potentially intersect.
            double ua = n_a / d;
            double ub = n_b / d;

            // The fractional point will be between 0 and 1 inclusive if the lines
            // intersect.  If the fractional calculation is larger than 1 or smaller
            // than 0 the lines would need to be longer to intersect.
            if (ua >= 0d && ua <= 1d && ub >= 0d && ub <= 1d)
            {
                
                ptIntersection.X = L1.StartPoint.X + (ua * (L1.EndPoint.X - L1.StartPoint.X));
                ptIntersection.Y = L1.StartPoint.Y + (ua * (L1.EndPoint.Y - L1.StartPoint.Y));
                return true;
            }
            return false;
        }
Regards

Andrew Milford
Sr. Product Manager
Autodesk Pty Ltd
100 Commercial St,
Manchester NH 03101

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


 

Autodesk Design & Make Report