» Circle Line Intersect Plugin
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

Circle Line Intersect Plugin

question resolved using-vvvv

lasal 02/06/11 - 03:59

Hi people,

i´m trying to implement this code in a dynamic plugin, but i don´t know really how it works...
http://www.openprocessing.org/visuals/?visualID=8009

If anybody has a moment to check it would be great, this is my first attempt to make a plugin.

Here there is a realted thread.
intersect-between-several-circles

Thanks in advance,

ari.

24 replies 0 new

Hi,
i think i´ve got it, but it returns 2 solutions even if one of the points is into the circle.

Any idea?

ari

It seems that all the people is on Hollydays ?¿

Haven't looked at your code, but i guess it creates the formula of the line based on the 2 points you pass to the algorithm.

And of course this line (almost) always has 2 intersections with the circle.

I guess if you only want the intersection that lies between these 2 points, take the solution(x,y) where solution(x) is between P1(x) and P2(x) and solution(y) is between P1(y) and P2(y).

Hi ft, thanks a lot for your response.
this is the code, i´ve just implemented the processing one.

Any help would be great.

Ari.

#region usings
using System;
using System.ComponentModel.Composition;
 
using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VColor;
using VVVV.Utils.VMath;
 
using VVVV.Core.Logging;
#endregion usings
 
namespace VVVV.Nodes
{
    #region PluginInfo
    [PluginInfo(Name = "CircleLineIntersect",
                Category = "Value",
                Help = "Basic template with one value in/out",
                Tags = "")]
    #endregion PluginInfo
    public class ValueCircleLineIntersectNode : IPluginEvaluate
    {
        #region fields & pins
        [Input("CircleCenter")]
        ISpread<Vector2D> center;
 
        [Input("CircleRadius", DefaultValue = 1.0)]
        ISpread<double> cr;
 
        [Input("Line1")]
        ISpread<Vector2D> L1;
 
        [Input("Line2")]
        ISpread<Vector2D> L2;
 
        [Output("Intersection 1 ")]
        ISpread<Vector2D> FIntersection1;
 
        [Output("Intersection 2 ")]
        ISpread<Vector2D> FIntersection2;
 
        [Output("Number of Solutions")]
        ISpread<int> FSolutionCount;
 
        [Import()]
        ILogger FLogger;
        #endregion fields & pins
 
        //called when data for any output pin is requested
        public void Evaluate(int SpreadMax)
        {
            FIntersection1.SliceCount = SpreadMax;
            FIntersection2.SliceCount = SpreadMax;
            FSolutionCount.SliceCount = SpreadMax;
 
            for (int i = 0; i < SpreadMax; i++)
                {
                Vector2D s1;
                Vector2D s2;
 
                FSolutionCount[i] = CircleLineIntersection(center[i], cr[i], L1[i], L2[i] , out s1, out s2);
                FIntersection1[i] = s1;
                FIntersection2[i] = s2;
            }
 
            //FLogger.Log(LogType.Debug, "Logging to Renderer (TTY)");
        }
        private int CircleLineIntersection (Vector2D center, double cr, Vector2D L1 , Vector2D L2,  out Vector2D p1, out Vector2D p2)
        {
            p1 = new Vector2D();
            p2 = new Vector2D();
 
        double dx = L2.x - L1.x;
        double dy = L2.y - L1.y;
        double a = dx * dx + dy * dy;
        double b = 2 * (dx * (L1.x - center.x) + dy * (L1.y - center.y));
        double c = L1.x * L1.x + L1.y * L1.y + center.x * center.x + center.y * center.y - 2 * (center.x * L1.x + center.y * L1.y)-(cr * cr);
        double bb4ac = b * b - 4 * a * c;
 
        double mu1 = (-b + Math.Sqrt(bb4ac)) / (2*a);
        double mu2 = (-b - Math.Sqrt(bb4ac)) / (2*a);
 
        double i1x = L1.x + mu1*(dx);
        double i1y = L1.y + mu1*(dy);
 
        double i2x = L1.x + mu2*(dx);
        double i2y = L1.y + mu2*(dy);
 
        double dist1 = Math.Sqrt((L1.x-center.x)*(L1.x-center.x)+(L1.y-center.y)*(L1.y-center.y));
        double dist2 = Math.Sqrt((L2.x-center.x)*(L2.x-center.x)+(L2.y-center.y)*(L2.y-center.y));
        double dist3 = Math.Sqrt((L2.x-L1.x)*(L2.x-L1.x)+(L2.y-L1.y)*(L2.y-L1.y));
        double dist4 = Math.Sqrt((p1.x-i1x)*(p1.x-i1x)+(p1.y-i1y)*(p1.y-i1y));
        double dist5 = Math.Sqrt((p1.x-i2x)*(p1.x-i2x)+(p1.y-i2y)*(p1.y-i2y));
 
 
       if (bb4ac < 0) {  // Not intersecting
    return 0;
  }
       if (bb4ac > 0) {  //2 solutions
 
            p1.x = i1x;
            p1.y = i1y;
            p2.x = i2x;
            p2.y = i2y;
            return 2;
   }
      if (bb4ac == 0) {  //1 solution tangent
 
            p1.x = i1x;
            p1.y = i1y;
            return 1;
   }
    // Figure out which point is closer to the circle
    if (dist1 < dist2 ) {  //&& cr >= dist2
 
      p1.x = L2.x;
      p1.y = L2.y;
      return 1;
 
    } if (dist1>dist2 ) {
 
 
      p1.x = L1.x;
      p1.y = L1.y;
      return 1;
    }
   if (dist4 < dist3 || dist5 < dist3) { //2 solutions 
 
            p1.x = i1x;
            p1.y = i1y;
            p2.x = i2x;
            p2.y = i2y;
 
      return 2;
    } else {
      return 0;
 
    }
}
}
}

Hi people,

i´ve made some changes and it works more or less, but when the points are outside the circle, the plugin shows 2 values instead of 0.

if anyone has time to look at it, it would be great.

Thanks,

Ari.

#region usings
using System;
using System.ComponentModel.Composition;
 
using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VColor;
using VVVV.Utils.VMath;
 
using VVVV.Core.Logging;
#endregion usings
 
namespace VVVV.Nodes
{
    #region PluginInfo
    [PluginInfo(Name = "CircleLineIntersect",
                Category = "Value",
                Help = "Basic template with one value in/out",
                Tags = "")]
    #endregion PluginInfo
    public class ValueCircleLineIntersectNode : IPluginEvaluate
    {
        #region fields & pins
        [Input("CircleCenter")]
        ISpread<Vector2D> center;
 
        [Input("CircleRadius", DefaultValue = 1.0)]
        ISpread<double> cr;
 
        [Input("Line1")]
        ISpread<Vector2D> L1;
 
        [Input("Line2")]
        ISpread<Vector2D> L2;
 
        [Output("Intersection 1 ")]
        ISpread<Vector2D> FIntersection1;
 
        [Output("Intersection 2 ")]
        ISpread<Vector2D> FIntersection2;
 
        [Output("Number of Solutions")]
        ISpread<int> FSolutionCount;
 
        [Import()]
        ILogger FLogger;
        #endregion fields & pins
 
        //called when data for any output pin is requested
        public void Evaluate(int SpreadMax)
        {
            FIntersection1.SliceCount = SpreadMax;
            FIntersection2.SliceCount = SpreadMax;
            FSolutionCount.SliceCount = SpreadMax;
 
            for (int i = 0; i < SpreadMax; i++)
                {
                Vector2D s1;
                Vector2D s2;
 
                FSolutionCount[i] = CircleLineIntersection(center[i], cr[i], L1[i], L2[i] , out s1, out s2);
                FIntersection1[i] = s1;
                FIntersection2[i] = s2;
            }
 
 
        }
        private int CircleLineIntersection (Vector2D center, double cr, Vector2D L1 , Vector2D L2,  out Vector2D p1, out Vector2D p2)
        {
            p1 = new Vector2D();
            p2 = new Vector2D();
 
        double dx = L2.x - L1.x;
        double dy = L2.y - L1.y;
        double a = dx * dx + dy * dy;
        double b = 2 * (dx * (L1.x - center.x) + dy * (L1.y - center.y));
        double c = L1.x * L1.x + L1.y * L1.y + center.x * center.x + center.y * center.y - 2 * (center.x * L1.x + center.y * L1.y)-(cr * cr);
        double bb4ac = b * b - 4 * a * c;
 
        double mu1 = (-b + Math.Sqrt(bb4ac)) / (2*a);
        double mu2 = (-b - Math.Sqrt(bb4ac)) / (2*a);
 
        double i1x = L1.x + mu1*(dx);
        double i1y = L1.y + mu1*(dy);
 
        double i2x = L1.x + mu2*(dx);
        double i2y = L1.y + mu2*(dy);
 
        double dist1 = Math.Sqrt((L1.x-center.x)*(L1.x-center.x)+(L1.y-center.y)*(L1.y-center.y));
        double dist2 = Math.Sqrt((L2.x-center.x)*(L2.x-center.x)+(L2.y-center.y)*(L2.y-center.y));
 
 
        if  (bb4ac < 0)    // Not intersecting  (bb4ac < 0) 
        {
            return 0;
            }
 
        if  (bb4ac==0 )  //1 solution tangent  (bb4ac == 0)
        { 
            p1.x = i1x;
            p1.y = i1y;
            return 1;
            }
 
        if  ( (dist1>=cr & dist2>=cr ))    //2 solutions  (dist1>=cr & dist2>=cr)
        {
            p1.x = i1x;
            p1.y = i1y;
            p2.x = i2x;
            p2.y = i2y;
            return 2;
            }
            //else {return 0;}
 
        if  ( (dist1>=cr & dist2<=cr))    //1 solution  
        {
            p1.x = i2x;
            p1.y = i2y;
              return 1;
            }
        if  ( (dist1<=cr & dist2>=cr))    //1 solution  
        {
            p1.x = i1x;
            p1.y = i1y;
            return 1;
            }
 
            {
            return 0;    
} 
}
}}
link | Flagged as solution by lasal. Remove solution flag. lasal 11/06/2011 - 10:55

Finally i found the solution for the 5 cases, in a "finite line - circle intersection".

Thanks ft for the hint.

Ari.

Is there any way to do this spreadable???

link | Flagged as solution by lasal. Remove solution flag. Hadasi 02/03/2012 - 00:21

Hi Ari,

Its been a while since you posed the question but I recently started looking for the answer too. Andy McW and I went over the plugin to try and figure out a spreadable method and we got a very workable if not perfect solution.

The patch explains why but it ain't bad.

Here's the code if you wanna peak:

using System;
using System.ComponentModel.Composition;
 
using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VColor;
using VVVV.Utils.VMath;
 
using VVVV.Core.Logging;
#endregion usings
 
namespace VVVV.Nodes
{
    #region PluginInfo
    [PluginInfo(Name = "IntersectCircles", Category = "2d", Help = "Basic template with one value in/out", Tags = "")]
    #endregion PluginInfo
    public class C2dIntersectCirclesNode : IPluginEvaluate
    {
        #region fields & pins
        [Input("Centers")]
        ISpread<Vector2D> FCenters;
 
        [Input("Radii", DefaultValue = 1.0)]
        ISpread<double> FRadii;
 
        [Output("Intersections")]
        ISpread<Vector2D> FIntersections;
 
        [Output("Number of Solutions")]
        ISpread<int> FSolutionCount;
 
        [Import()]
        ILogger FLogger;
        #endregion fields & pins
 
        //called when data for any output pin is requested
        public void Evaluate(int SpreadMax)
        {
            FIntersections.SliceCount = SpreadMax;
            FSolutionCount.SliceCount = SpreadMax;
 
            for(int i = 0; i < FIntersections.SliceCount; i++)
            {
                FIntersections.RemoveAt(i);
            }
 
            for (int i = 0; i < SpreadMax; i++)
            {
                for (int j = i + 1; j < SpreadMax; j++)
                {    
                    Vector2D s1;
                    Vector2D s2;
 
                    FSolutionCount[i] = CircleIntersection(FCenters[i], FRadii[i], FCenters[j], FRadii[j], out s1, out s2);
 
                    FIntersections.Add(s1);
                    FIntersections.Add(s2);    
                }
            }
        }
 
        private int CircleIntersection (Vector2D c1, double c1r, Vector2D c2, double c2r, out Vector2D p1, out Vector2D p2)
        {
            p1 = new Vector2D();
            p2 = new Vector2D();
 
            //Calculate distance between centres of circle
            double d = !(c1 - c2);
            double m = c1r + c2r;
            double n = c1r - c2r;
 
            if (n < 0)
                n = n * -1;
 
            //No solns
            if ( d > m )
                return 0;
 
            //Circle are contained within each other
            if ( d < n )
                return 0;
 
            //Circles are the same
            if ( d == 0 && c1r == c2r )
                return 0;
 
            //Solve for a
            double a = ( c1r * c1r - c2r * c2r + d * d ) / (2 * d);
 
            //Solve for h
            double h = Math.Sqrt( c1r * c1r - a * a );
 
            //Calculate point p, where the line through the circle intersection points crosses the line between the circle centers.
            Vector2D p;
 
            p.x = c1.x + ( a / d ) * ( c2.x -c1.x );
            p.y = c1.y + ( a / d ) * ( c2.y -c1.y );
 
            //1 soln , circles are touching
            if ( d == c1r + c2r ) 
            {
                p1 = p;
                return 1;
            }
 
            //2solns            
            p1.x = p.x + ( h / d ) * ( c2.y - c1.y );
            p1.y = p.y - ( h / d ) * ( c2.x - c1.x );
 
            p2.x = p.x - ( h / d ) * ( c2.y - c1.y );
            p2.y = p.y + ( h / d ) * ( c2.x - c1.x );
 
 
            return 2;
        }
 
    }
}

Hope its still helpful,

Hadasi

Grande Hadasi!

i´ll try to use the same method to Circle-Line and Line-Line intersections.
could i share it as a contribution?

2d-circle-line-intersections

Thanks a lot.

Ari.

Be our guest!

The idea came from Elias'sConnectAll">ConnectAll)) dynamic plug-in he did for his tutorial. In it he showed how multiple vectors can be made to analyse each other (the "for j = i+1" bit).

Most of the credit goes to Andy McWilliams and your good self, though, co-opted the ideas into a something usable and lovely.

Looking forward to the lines version!

Hayd

link | Flag this reply as a solution. Elias (devvvv) 02/03/2012 - 13:19

you should replace these lines

for(int i = 0; i < FIntersections.SliceCount; i++)
{
    FIntersections.RemoveAt(i);
}

with this

FIntersections.Clear();

it's easier to read and has a better run time, as removing them one by one will trigger a shift of all remaining slices each time you remove one slice.

Danke Elias.

Hi Elias,

.Clear method wasn't recognised.

'VVVV.PluginInterfaces.V2.ISpread<VVVV.Utils.VMath.Vector2D>' does not contain a definition for 'Clear' and no extension method 'Clear' accepting a first argument of type 'VVVV.PluginInterfaces.V2.ISpread<VVVV.Utils.VMath.Vector2D>' could be found (are you missing a using directive or an assembly reference?)

link | Flag this reply as a solution. Elias (devvvv) 02/03/2012 - 21:33

whaaat? :p
ok, then replace it with a

FIntersections.SliceCount = 0;

Hey guys,
i´m trying to make the multiple finite lines version,
but i don´t know how to feed the plugin with a spread of points instead of 4 points with individual inputs.

Any tip?

thanks.

#region usings
using System;
using System.ComponentModel.Composition;
 
using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VColor;
using VVVV.Utils.VMath;
 
using VVVV.Core.Logging;
#endregion usings
 
namespace VVVV.Nodes
{
    #region PluginInfo
    [PluginInfo(Name = "MultipleLinesIntersect", Category = "Value", Help = "2 lines intersect", Tags = "")]
    //Source:
    //http://paulbourke.net/geometry/lineline2d/
    //Credits:
    //Lasal 2011
 
    #endregion PluginInfo
    public class Value2LinesIntersectNode : IPluginEvaluate
    {
        #region fields & pins
 
                // Could it be possible to use a spread of points? 
 
                [Input("P1")]
        ISpread<Vector2D> P1;
 
        [Input("P2")]
        ISpread<Vector2D> P2;
 
            [Input("P3")]
        ISpread<Vector2D> P3;
 
        [Input("P4")]
        ISpread<Vector2D> P4;
 
        [Output("Intersection")]
        ISpread<Vector2D> FIntersection;
 
        [Output("Number of Solutions")]
        ISpread<int> FSolutionCount;
 
        [Import()]
        ILogger FLogger;
        #endregion fields & pins
 
        //called when data for any output pin is requested
        public void Evaluate(int SpreadMax)
        {
            FIntersection.SliceCount = SpreadMax;
            FSolutionCount.SliceCount = SpreadMax;
 
            for(int i = 0; i < FIntersection.SliceCount; i++)
            {
               FIntersection.RemoveAt(i);
            }
 
            for (int i = 0; i < SpreadMax; i++)
                {
                for (int j = i + 1; j < SpreadMax; j++)
                {    
                    Vector2D s1;
                    Vector2D s2;
 
                //How to use 10 variables? P1[j], P2[j], P3[j], P4[j]
 
                FSolutionCount[i] = LinesIntersection( P1[i], P2[i], P3[i], P4[i], out s1, out s2);
 
                FIntersection.Add(s1);
                FIntersection.Add(s2);
                }
 
            }
 
 
        }
        private int LinesIntersection ( Vector2D P1 , Vector2D P2, Vector2D P3 , Vector2D P4, out Vector2D so1, out Vector2D so2)
        {
            so1 = new Vector2D();
            so2 = new Vector2D();
 
        // Denominator for ua and ub are the same, so store this calculation
         double d = 
            (P4.y - P3.y) * (P2.x - P1.x)
            -
            (P4.x - P3.x) * (P2.y - P1.y);
 
         //n_a and n_b are calculated as seperate values for readability
         double n_a =
            (P4.x - P3.x) * (P1.y - P3.y)
            -
            (P4.y - P3.y) * (P1.x - P3.x);
 
         double n_b =
            (P2.x - P1.x) * (P1.y - P2.y)
            -
            (P2.y - P1.y) * (P1.x - P2.x);
 
         // Calculate the intermediate fractional point that the lines potentially intersect.
         double ua = n_a / d;
         double ub = n_b / d;
 
         double   SX = P1.x + (ua * (P2.x - P1.x));
         double   SY = P1.y + (ua * (P2.y - P1.y));
 
        if (d == 0)   // Parallel lines.
        {
            return 0;
            }
 
        if (SX < P1.x & SX < P2.x | 
            SY < P1.y & SY < P2.y | 
            SX > P1.x & SX > P2.x | 
            SY > P1.y & SY > P2.y )  
            // No finite lines intersecting, delete this for infinite lines Intersection.
            {
            return 0;
            }
 
 
          // than 0 the lines would need to be longer to intersect.
         if (ua >= 0d && ua <= 1d && ub >= 0d && ub <= 1d)
         {
            so1.x = SX;
            so1.y = SY;
            return 1;
            }
 
 
            {
            return 0;    
} 
}
}}

I think Input 1 could be "line start(vector2D)" and Input 2 "line end(vector2D)."

Then you can compare the spread of lines

j = i + 1; 
line1[i]; line2[j];

(Pardon my lack of correct formatting, and the fact I may be wrong)

Hayd

PS thanks Elias

Bam:

#region usings
using System;
using System.ComponentModel.Composition;
 
using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VColor;
using VVVV.Utils.VMath;
 
using VVVV.Core.Logging;
#endregion usings
 
namespace VVVV.Nodes
{
    #region PluginInfo
    [PluginInfo(Name = "MultipleLinesIntersect", Category = "Value", Help = "2 lines intersect", Tags = "")]
    //Source:
    //http://paulbourke.net/geometry/lineline2d/
    //Credits:
    //Lasal 2011
 
    #endregion PluginInfo
    public class Value2LinesIntersectNode : IPluginEvaluate
    {
        #region fields & pins
 
                // Could it be possible to use a spread of points? 
 
                [Input("Line Start")]
        ISpread<Vector2D> P1;
 
        [Input("Line End")]
        ISpread<Vector2D> P2;
 
 
        [Output("Intersection")]
        ISpread<Vector2D> FIntersection;
 
        [Output("Number of Solutions")]
        ISpread<int> FSolutionCount;
 
        [Import()]
        ILogger FLogger;
        #endregion fields & pins
 
        //called when data for any output pin is requested
        public void Evaluate(int SpreadMax)
        {
            FIntersection.SliceCount = SpreadMax;
            FSolutionCount.SliceCount = SpreadMax;
 
            for(int i = 0; i < FIntersection.SliceCount; i++)
            {
               FIntersection.SliceCount = 0;
            }
 
            for (int i = 0; i < SpreadMax; i++)
                {
                for (int j = i + 1; j < SpreadMax; j++)
                {    
                    Vector2D s1;
                    Vector2D s2;
 
                //How to use 10 variables? P1[j], P2[j], P3[j], P4[j]
 
                FSolutionCount[i] = LinesIntersection( P1[i], P2[i], P1[j], P2[j], out s1, out s2);
 
                FIntersection.Add(s1);
                FIntersection.Add(s2);
                }
 
            }
 
 
        }
        private int LinesIntersection ( Vector2D P1 , Vector2D P2, Vector2D P3 , Vector2D P4, out Vector2D so1, out Vector2D so2)
        {
            so1 = new Vector2D();
            so2 = new Vector2D();
 
        // Denominator for ua and ub are the same, so store this calculation
         double d = 
            (P4.y - P3.y) * (P2.x - P1.x)
            -
            (P4.x - P3.x) * (P2.y - P1.y);
 
         //n_a and n_b are calculated as seperate values for readability
         double n_a =
            (P4.x - P3.x) * (P1.y - P3.y)
            -
            (P4.y - P3.y) * (P1.x - P3.x);
 
         double n_b =
            (P2.x - P1.x) * (P1.y - P2.y)
            -
            (P2.y - P1.y) * (P1.x - P2.x);
 
         // Calculate the intermediate fractional point that the lines potentially intersect.
         double ua = n_a / d;
         double ub = n_b / d;
 
         double   SX = P1.x + (ua * (P2.x - P1.x));
         double   SY = P1.y + (ua * (P2.y - P1.y));
 
        if (d == 0)   // Parallel lines.
        {
            return 0;
            }
 
        if (SX < P1.x & SX < P2.x | 
            SY < P1.y & SY < P2.y | 
            SX > P1.x & SX > P2.x | 
            SY > P1.y & SY > P2.y )  
            // No finite lines intersecting, delete this for infinite lines Intersection.
            {
            return 0;
            }
 
 
          // than 0 the lines would need to be longer to intersect.
         if (ua >= 0d && ua <= 1d && ub >= 0d && ub <= 1d)
         {
            so1.x = SX;
            so1.y = SY;
            return 1;
            }
 
 
            {
            return 0;    
} 
}
}}

Gets a little upset if I try to setup a line one axis going along a zero co-ordinates, but seems okay otherwise. Any ideas how to avoid that?

Hayd

link | Flagged as solution by Hadasi. Remove solution flag. Elias (devvvv) 05/03/2012 - 13:11

you had an error in calculation of n_b, and parallel worked but your demo patch didn't display it properly.
i simplified code and patch a little, seems to work fine now.

nice one

Sweet as a nut. Cheers Elias.

wow,
i was missing only one day and look at this ;)

Thanks Hadasi and Elias

Taking advance of the situation...
I´m cleaning up the Multiple circle intersection plugin and, it shows variables even when there isn´t any solution.

Anyone knows how to return false (nil) when there isn´t any intersection?
It seems that the behaviour is different than the multiple lines intersect.

Thanks

#region usings
using System;
using System.ComponentModel.Composition;
 
using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VColor;
using VVVV.Utils.VMath;
 
using VVVV.Core.Logging;
#endregion usings
 
namespace VVVV.Nodes
{
    #region PluginInfo
    [PluginInfo(Name = "IntersectCircles", Category = "2d", Help = "Basic template with one value in/out", Tags = "")]
    #endregion PluginInfo
    public class C2dIntersectCirclesNode : IPluginEvaluate
    {
        #region fields & pins
        [Input("Centers")]
        ISpread<Vector2D> FCenters;
 
        [Input("Radius", DefaultValue = 1.0)]
        ISpread<double> FRadii;
 
        [Output("Intersection")]
        ISpread<Vector2D> FIntersections;
 
        [Output("Number of Solutions")]
        ISpread<int> FSolutionCount; 
 
       // [Import()]
       // ILogger FLogger;
        #endregion fields & pins
 
        //called when data for any output pin is requested
 
        public void Evaluate(int SpreadMax)
        {
            FIntersections.SliceCount = SpreadMax;
            FSolutionCount.SliceCount = SpreadMax;
            for(int i = 0; i < FSolutionCount.SliceCount; i++)
            {
               FIntersections.SliceCount = 0;
 
            }
            for (int i = 0; i < SpreadMax; i++)
            {
                for (int j = i + 1; j < SpreadMax; j++)
                {    
                    Vector2D s1;
                    Vector2D s2;
 
                    if ( CircleIntersection(FCenters[i], FRadii[i], FCenters[j], FRadii[j], out s1, out s2))
 
                    FIntersections.Add(s1);
                    FIntersections.Add(s2);    
                }
            }
        }
 
        private bool CircleIntersection (Vector2D c1, double c1r, Vector2D c2, double c2r, out Vector2D p1, out Vector2D p2)
        {
            p1 = new Vector2D();
            p2 = new Vector2D();
 
            //Calculate distance between centres of circle
            double d = !(c1 - c2);
            double m = c1r + c2r;
            double n = c1r - c2r;
 
            if (n < 0)
                n = n * -1;
 
 
 
            //Solve for a
            double a = ( c1r * c1r - c2r * c2r + d * d ) / (2 * d);
 
            //Solve for h
            double h = Math.Sqrt( c1r * c1r - a * a );
 
            //Calculate point p, where the line through the circle intersection points crosses the line between the circle centers.
            Vector2D p;
 
            p.x = c1.x + ( a / d ) * ( c2.x -c1.x );
            p.y = c1.y + ( a / d ) * ( c2.y -c1.y );
 
            //No solns  //Circle are contained within each other //Circles are the same
            if ( d > m || d < n || d == 0 && c1r == c2r)
                {
                return false;
            }
 
            //1 soln , circles are touching
            if ( d == c1r + c2r ) 
            {
                p1 = p;
                {
                return true;
 
                }
            }
 
            //2solns      
 
            p1.x = p.x + ( h / d ) * ( c2.y - c1.y );
            p1.y = p.y - ( h / d ) * ( c2.x - c1.x );
 
            p2.x = p.x - ( h / d ) * ( c2.y - c1.y );
            p2.y = p.y + ( h / d ) * ( c2.x - c1.x );
 
 
            return true;
             {
            return false;
 
             }
 
 
 
        }
 
 
        }
 
    }

anonymous user login

Shoutbox

~2d ago

joreg: @io: we have a new workshop format planned for that this year. to be announced with the rest of the workshops mid jannuary.

~2d ago

joreg: @mori better start a forum-thread describing your problem in more detail. because if you just ask: Can I? the answer is: Yes.

~2d ago

Mori: Can I connect the reverse pin of an LFO to something event triggered? I can't seem to find a way :(

~2d ago

Mori: Can I connect the reverse pin of an LFO to something event triggered? I can't seem to find a way :(

~2d ago

io: Yes, good patching style is the most difficult skill to learn when you are an isolated vvvv user as myself

~2d ago

Mori: Is there a workaround for the reset pin on LFO? Wave shaper doesn't do it

~2d ago

guest: @io Node13's Software Engineering Patterns workshop by Meso essentially fit the MVC pattern. It would be good if they run it again.

~2d ago

joreg: @io more than what?