Sign in TopomorphRSS Feed

A while ago Yu-Chung Chen commented on my post The fillet pseudo code. He reminded me of a small issue that remained unsolved: the point inside. Though the algorithm worked fine finding which of the four possible fillets was the right one should still be decided. I imagined that the intersection of the connection lines between start en end point of the two main lines would be a nice indicator. I decided to make a small Silverlight demonstration to show my point (pun intended).
A good point I did so: Immediately became clear that such a solution worked in a limited number of cases:

 

Only after I added a line between the the midpoints of both lines it became clear that the midpoint of this line was the most suitable candidate for the point inside. And indeed:


The FilletArc I’ve made into a control, to use binding on the endpoints of the mainlines (In Silverlight element binding is possible but you do need some extra objects to intermediate)

The fillet arc is drawn (adjusted) in the invalidate method, that  will be called from DependencyPropertyChanged callback:

private void Invalidate()
        {
            Point L11 = Line1Start;
            Point L12 = Line1End;
            Point L21 = Line2Start;
            Point L22 = Line2End;
            double radius = Radius;
            Point mid = new Point((L11.X + L12.X + L21.X + L22.X)/4,(L11.Y + L12.Y + L21.Y + L22.Y)/4);
            ArcSeg arcseg = LineUtilities.FilletArc(new LineSeg(L11, L12), new LineSeg(L21, L22), Radius, mid);
            double sA = arcseg.StartAngle * 180 / Math.PI; 
            double eA = arcseg.EndAngle * 180 / Math.PI; 
            
            //We only want the inner arcs
            if (eA - sA > 180) sA += 360;
            if (sA - eA > 180) eA += 360;
            
            FilletArcSegment.IsLargeArc = Math.Abs(eA - sA) > 180;
            FilletArcSegment.SweepDirection = eA > sA ? SweepDirection.Clockwise : SweepDirection.Counterclockwise;
            FilletArcSegment.Size = new Size(radius, radius);
            FilletArcSegment.Point = FromPolarPoint(eA, radius, arcseg.Center);
            ArcPathFigure.StartPoint = FromPolarPoint(sA, radius, arcseg.Center);
        }

The utility arcseg holds the data of the fillet. In the helper class LineUtilities it shows the (pseudo) code I posted before:

 

public static ArcSeg FilletArc(LineSeg Line1, LineSeg Line2, double Radius, Point pointOnInside)
       {
           Point center = (Point)Line1.Offset(Radius, pointOnInside).Intersect(Line2.Offset(Radius, pointOnInside));
           return new ArcSeg()
                  {
                      Center = center,
                      // P2 is the intersection point of the returned linesegment
                      StartPoint = Line1.PerpendicularLine(center).P2,
                      EndPoint = Line2.PerpendicularLine(center).P2,
                  };
       }

 

Both the fillet arc and the line segment utilities you can find in