/// <summary> /// Checking whether two rays intersect. Their intersection is center of a cirlcle.(circle event) /// Using projection it checks if the event is on the correct place. /// </summary> /// <param name="par"></param> private void checkCircle(Parabola par) { var leftSeg = par.GetLeftSegment(); var rightSeg = par.GetRightSegment(); if (leftSeg == null || rightSeg == null) { return; } var center = Segment.GetTwoLinesIntersection(leftSeg, rightSeg); if (!center.HasValue) { return; } var c = center.Value; Segment s = null; if (center == leftSeg.Start) { s = rightSeg; } else { s = leftSeg; } var u = s.Start.Value - c; if (u.Length() < NumericsUtils.Vector2Epsilon) { return; } var v = (u).Normalize() - s.Direction.Value.Normalize(); if (v.Length() < NumericsUtils.Vector2Epsilon /*&& center != sl.Start && center != sr.Start*/) { return; } var radius = (c - par.Site).Length(); if (c.Y - radius - directixY > NumericsUtils.Vector2Epsilon) { return; } if (par.CircleEvent != null) { par.CircleEvent.Invalidate();// when this happens the segment should be removed because it is invalid. maybe start = end => zero lenght } CircleEvent cev = new CircleEvent(c.X, c.Y, radius); cev.Parabola = par; par.CircleEvent = cev; queue.Insert(cev); }
/// <summary> /// Reaction to the cirle event. Removes the parabola associated to this event. /// It also rebuilds the tree. /// </summary> /// <param name="ce"></param> private void removeParabola(CircleEvent ce) { var p = ce.Parabola; var pl = p.GetLeftParent(); var pr = p.GetRightParent(); var l = p.GetLeafParabolaOnTheLeft(); var r = p.GetLeafParabolaOnTheRight(); var sl = pl.Segment; var sr = pr.Segment; if (l.CircleEvent != null) { l.CircleEvent.Invalidate(); } if (r.CircleEvent != null) { r.CircleEvent.Invalidate(); } if (sl != null) { sl.End = ce.Center; } if (sr != null) { sr.End = ce.Center; } var seg = new Segment(ce.Center.Value, r.Site, l.Site); segs.Add(seg); var pp = p.Parent; if (pp.GetRightNode() == p)//removed parabole is on the right so the left one is correct { if (pp.Parent.GetLeftNode() == pp) { pp.Parent.SetLeftParabola(pp.GetLeftNode()); } if (pp.Parent.GetRightNode() == pp) { pp.Parent.SetRightParabola(pp.GetLeftNode()); } pr.Segment = seg; } else { if (pp.Parent.GetLeftNode() == pp) { pp.Parent.SetLeftParabola(pp.GetRightNode()); } if (pp.Parent.GetRightNode() == pp) { pp.Parent.SetRightParabola(pp.GetRightNode()); } pl.Segment = seg; } checkCircle(l); checkCircle(r); }