Can I use a line object in a parallel.foreach loop?

Can I use a line object in a parallel.foreach loop?

Anonymous
Not applicable
1,189 Views
6 Replies
Message 1 of 7

Can I use a line object in a parallel.foreach loop?

Anonymous
Not applicable

I have a list of line objects stored in RAM and I want to see if any of them (one always will be) are parallel to a seperate line object which is also already on RAM so I don't have to read them from the database. I also have another line object that will cross the parallel line from the list but start at the beginning of the separate line and end at the opposite side of the line from the list as shown in the image below. List line is red and the two comparisons lines are green.

New Bitmap Image.jpg

 

it will add the line that is parallel but only when its partner intersects to a concurrentbag. The problem I get is that it either does not find a value or it finds a value and repeats that line 162 times (the amount of lines I have in the list). It is random if does or does not find a result. I tied using a regular loop and it has the same problem. Not sure where I am going wrong.

 

 

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections.Concurrent;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;

namespace placePillars.Place_Cables
{
    class CableIntersects
    {
        public static (Line, ObjectId) IntersectingCables(Document doc, Editor ed, Database db, List<Line> lineList, Line innerLine, Line outerLine)
        {
            //Assume the line is correct, ie y2-y
            bool innerbackwars = false;
            bool outerbackwars = false;
            bool linebackwards = false;
            Double mBoundary;
            Double bBoundary;
            Double mInner;
            Double mOuter;
            
            double tolerance = 0.01;

            ConcurrentBag<Line> newCable = new ConcurrentBag<Line>();
            ObjectId cableIntersect = new ObjectId();
            Line newcableResult = new Line();

            //Check where the start point is in regards to the end point
            if (innerLine.EndPoint.X - innerLine.StartPoint.X < 0)
            {
                //start point is after end point
                innerbackwars = true;
            }
            if (outerLine.EndPoint.X - outerLine.StartPoint.X < 0)
            {
                outerbackwars = true;
            }

            //Workout gradient of unchanging lines
            if (innerbackwars == false)
            {

                mInner = (innerLine.EndPoint.Y - innerLine.StartPoint.Y) / (innerLine.EndPoint.X - innerLine.StartPoint.X);
            }
            else
            {
                mInner = (innerLine.StartPoint.Y - innerLine.EndPoint.Y) / (innerLine.StartPoint.X - innerLine.EndPoint.X);;
            }

            if (outerbackwars == false)
            {

                mOuter = (outerLine.EndPoint.Y - outerLine.StartPoint.Y) / (outerLine.EndPoint.X - outerLine.StartPoint.X);
            }
            else
            {
                mOuter = (outerLine.StartPoint.Y - outerLine.EndPoint.Y) / (outerLine.StartPoint.X - outerLine.EndPoint.X);
            }


            //Workout y axis intersect (where x=0)
            Double bInner = innerLine.StartPoint.Y - mInner * innerLine.StartPoint.X;
            Double bOuter = outerLine.StartPoint.Y - mOuter * outerLine.StartPoint.X;

            try
            {
                //using (DocumentLock acLckDoc = doc.LockDocument())
                //{
                    //using (Transaction acTrans = db.TransactionManager.StartTransaction())
                    //{
                        //Check for parallel lines first
                        //Parallel.ForEach(lineList, (lineRecord) =>
                        foreach(Line lineRecord in lineList)
                        {
                            bool inner = false;
                            bool outer = false;

                            if (lineRecord.EndPoint.X - lineRecord.StartPoint.X < 0)

                            {
                                //start point is after end point
                                linebackwards = true;
                            }

                            //Workout gradients of the lines
                            if (linebackwards == false)
                            {

                                mBoundary = (lineRecord.EndPoint.Y - lineRecord.StartPoint.Y) / (lineRecord.EndPoint.X - lineRecord.StartPoint.X);
                            }
                            else
                            {
                                mBoundary = (lineRecord.StartPoint.Y - lineRecord.EndPoint.Y) / (lineRecord.StartPoint.X - lineRecord.EndPoint.X);
                            }
                            bBoundary = lineRecord.StartPoint.Y - mBoundary * lineRecord.StartPoint.X;

                            //test to see if  innter out outer intersect
                            //Check to see if they are parallel to reduce calculations
                            //y=xm+b ---> xm+b=y=xm+b ---> x=x (move x to LHS) ---> x+x(-1)
                            var x = mBoundary + mInner * -1;
                            var b = bBoundary * -1 + bInner;
                            if (x <= tolerance && x >= -tolerance) x = 0;
                            double x1 = (float)b / (float)x;

                            x = mBoundary + mOuter * -1;
                            b = bBoundary * -1 + bOuter;
                            if (x <= tolerance && x >= -tolerance) x = 0;
                            double x2 = (float)b / (float)x;

                            var _y = lineRecord.Handle.Value;
                            if (_y==67397683)
                            {
                                var _u = 1;
                            }

                            //If X1 is the intercept line then we want to look at ir whilst X2 = inf
                            if (!double.IsInfinity(x1) && double.IsInfinity(x2))
                            {
                                //Dont know if line start or end comes first on x axis so work it out based on line length from x=0
                                if (innerbackwars == true)
                                {
                                    if (x1 < innerLine.StartPoint.X && x1 > innerLine.EndPoint.X)
                                    {
                                        //if inner line intercepts then we want the outer as our cable
                                        outer = true;
                                    }
                                }
                                if (innerbackwars == false)
                                {
                                    if (x1 > innerLine.StartPoint.X && x1 < innerLine.EndPoint.X)
                                    {
                                        outer = true;
                                    }
                                }
                                //if (inner == true && outer == false) break;
                            }
                            //Now see if outer cable intersects
                            if (double.IsInfinity(x1) && !double.IsInfinity(x2))
                            {
                                //Dont know if line start or end comes first on x axis so work it out based on line length from x=0
                                if (outerbackwars == false)
                                {
                                    if (x2 < outerLine.StartPoint.X && x2 > outerLine.EndPoint.X)
                                    {
                                        inner = true;

                                    }
                                }
                                if (outerbackwars == true)
                                {
                                    if (x2 > outerLine.StartPoint.X && x2 < outerLine.EndPoint.X)
                                    {
                                        inner = true;
                                    }
                                }
                            }
                            if ((inner == true && outer == false) || (inner == false && outer == true))
                            {
                                if (inner == true)
                                {
                                    newCable.Add(innerLine);
                                    cableIntersect = outerLine.ObjectId;
                                    inner = false;
                                    outer = false;
                                }
                                else
                                {
                                    newCable.Add(outerLine);
                                    cableIntersect = innerLine.ObjectId;
                                    inner = false;
                                    outer = false;
                                }
                            }
                        }//);//End of loop
                    //}
                //}
                var newcacleCount = newCable.Count;
                if (newcacleCount == 0)
                {
                    var _a = 1;
                }
                //if (newcacleCount > 1) { }
                else 
                {
                    foreach(var item in newCable)
                    {
                        newcableResult = item;
                    }
                };
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.StackTrace);
                MessageBox.Show(ex.Source);

            }
            return (newcableResult, cableIntersect) ;
        }
    }
}

 

 

 

 

0 Likes
Accepted solutions (1)
1,190 Views
6 Replies
Replies (6)
Message 2 of 7

_gile
Consultant
Consultant
Accepted solution

Hi,

 

AFAIK, you cannot use parallel computing with DBObjects, but it may be possible with some non-database resident geometric objects (I know it is possible with Point3d, I did it here).

You could try with LineSegment3d objects instead of Lines



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 7

Anonymous
Not applicable

Thanks Gile, I will have to change the Line object out. I assume i can just copy the x,y coordinates to a float if the 3Dpoint doesn't workout

0 Likes
Message 4 of 7

ActivistInvestor
Mentor
Mentor

Regarding this snippet from your code:

 

if ((inner == true && outer == false) || (inner == false && outer == true))

 

Is equivalent to:

 

if (inner ^ outer) 

 

 

the ^ (exclusive or) operator returns true if one of its operands is true and the other is false. 

Message 5 of 7

Anonymous
Not applicable

Thank you, I will change that. Would reduce processing needed at all?

0 Likes
Message 6 of 7

ActivistInvestor
Mentor
Mentor

Yes reducing it to a single simple operation would be more efficient.

 

Also, comparing a Boolean value to True is redundant.

 

if(x == true) 

 

Is equivalent to 

 

if(x) 

 

And

 

if(x == false) 

 

Is equivalent to 

 

if(!x) 
0 Likes
Message 7 of 7

Anonymous
Not applicable

Thanks, I didnt even think about this but when you mentioned it I thought that might be referring to efficiency. I guess I have to treat higher languages like a microcontroller

0 Likes