private static double get_ted(double prev_r, double this_r, double tool_r) { double prev_wall_r = prev_r + tool_r; double this_wall_r = this_r + tool_r; if (this_r - prev_wall_r >= tool_r) { return(double.MaxValue); } if (prev_wall_r - this_r >= tool_r) { return(double.MinValue); } // get intersection of two cicles = cutter circle and prev wall Circle2F prev_wall = new Circle2F(new Point2F(0, 0), prev_wall_r); Circle2F tool_circle = new Circle2F(new Point2F(this_r, 0), tool_r); Line2F insects = prev_wall.CircleIntersect(tool_circle); if (insects.p1.IsUndefined || insects.p2.IsUndefined) { return(0); } double ted = this_wall_r - insects.p1.X; return(ted); }
private void calc_teds(double tool_r) { // expand both slices to form walls Circle2F parent_wall = new Circle2F(_parent.Center, _parent.Radius + tool_r); Circle2F this_wall = new Circle2F(this.Center, this.Radius + tool_r); // find the point of cut start (intersection of walls) Line2F wall_insects = parent_wall.CircleIntersect(this_wall); if (wall_insects.p1.IsUndefined || wall_insects.p2.IsUndefined) { Logger.err("no wall intersections #1"); return; } Vector2d v_move = new Vector2d(_parent.Center, this.Center); Vector2d v1 = new Vector2d(_parent.Center, wall_insects.p1); Point2F cut_tail = v_move.Det(v1) * (int)this.Dir < 0 ? wall_insects.p1 : wall_insects.p2; Vector2d v_tail = new Vector2d(this.Center, cut_tail); Point2F entry_tool_center = this.Center + (v_tail.Unit() * this.Radius).Point; _entry_ted = calc_ted(entry_tool_center, tool_r); Point2F mid_tool_center = this.Center + (v_move.Unit() * this.Radius).Point; _mid_ted = calc_ted(mid_tool_center, tool_r); }
private double calc_ted(Point2F tool_center, double tool_r) { Circle2F parent_wall = new Circle2F(_parent.Center, _parent.Radius + tool_r); // find the points tool touching parent wall Circle2F cut_circle = new Circle2F(tool_center, tool_r); Line2F insects = cut_circle.CircleIntersect(parent_wall); if (insects.p1.IsUndefined || insects.p2.IsUndefined) { Logger.err("no wall intersections #0"); return(0); } // we're interested in tool head point, so choose more advanced point in mill direction Vector2d v1 = new Vector2d(_parent.Center, insects.p1); Vector2d v_parent_to_tool_center = new Vector2d(_parent.Center, tool_center); Point2F cut_head = v_parent_to_tool_center.Det(v1) * (int)this.Dir > 0 ? insects.p1 : insects.p2; // project headpoint to the center find TED Vector2d v_me_to_tool_center = new Vector2d(this.Center, tool_center); Vector2d v_me_to_cut_head = new Vector2d(this.Center, cut_head); double ted = this.Radius + tool_r - v_me_to_cut_head * v_me_to_tool_center.Unit(); return(ted > 0 ? ted : 0); }
private bool is_biarc_inside_ball(Biarc2d biarc, Circle2F ball) { if (biarc.Pm.DistanceTo(ball.Center) > ball.Radius) { return(false); } Point2F start = biarc.P1; Point2F end = biarc.P2; Line2F insects; if (biarc.Seg1 is Line2F) { insects = ball.LineIntersect((Line2F)biarc.Seg1); } else { insects = ((Arc2F)biarc.Seg1).CircleIntersect(ball); } if ((!insects.p1.IsUndefined) && insects.p1.DistanceTo(start) < _general_tolerance) { insects.p1 = Point2F.Undefined; } if ((!insects.p2.IsUndefined) && insects.p2.DistanceTo(start) < _general_tolerance) { insects.p2 = Point2F.Undefined; } if (!(insects.p1.IsUndefined && insects.p2.IsUndefined)) { return(false); } if (biarc.Seg2 is Line2F) { insects = ball.LineIntersect((Line2F)biarc.Seg2); } else { insects = ((Arc2F)biarc.Seg2).CircleIntersect(ball); } if ((!insects.p1.IsUndefined) && insects.p1.DistanceTo(end) < _general_tolerance) { insects.p1 = Point2F.Undefined; } if ((!insects.p2.IsUndefined) && insects.p2.DistanceTo(end) < _general_tolerance) { insects.p2 = Point2F.Undefined; } if (!(insects.p1.IsUndefined && insects.p2.IsUndefined)) { return(false); } return(true); }
public void Add(Circle2F ball, object obj) { this.Add(ball.Center, ball.Radius, obj); }
public Slice(Point2F center, double radius, RotationDirection dir) { _ball = new Circle2F(center, radius); _placement = Slice_placement.NORMAL; create_arc_circle(new Point2F(center.X + radius, center.Y), dir); }
public Slice(Slice parent, Point2F center, double radius, RotationDirection dir, double tool_r, Point2F magnet) { _parent = parent; _ball = new Circle2F(center, radius); double dist = Point2F.Distance(center, parent.Center); double delta_r = this.Radius - parent.Radius; double coarse_ted = dist + delta_r; // 1) one ball is inside other, no intersections // 2) balls are spaced too far and do not intersect, TED is 0, distance is positive // 3) balls are intersect, TED is valid if (dist <= Math.Abs(delta_r)) { _placement = Slice_placement.INSIDE_ANOTHER; return; } if (dist >= this.Radius + parent.Radius) { _placement = Slice_placement.TOO_FAR; return; } // TED can't be more >= tool diameter, this check prevents fails during the calculation of real angle-based TED if (coarse_ted > tool_r * 1.999) { _placement = Slice_placement.TOO_FAR; return; } Line2F insects = _parent.Ball.CircleIntersect(this._ball); if (insects.p1.IsUndefined || insects.p2.IsUndefined) { // try to return meaningful result even if CB routine had failed (unlikely) Logger.err("no intersections found there intersections should be (_parent.Ball.CircleIntersect(_ball))"); _placement = (dist <= this.Radius || dist <= parent.Radius) ? Slice_placement.INSIDE_ANOTHER : Slice_placement.TOO_FAR; return; } _placement = Slice_placement.NORMAL; Vector2d v_move = new Vector2d(_parent.Center, this.Center); Vector2d v1 = new Vector2d(_parent.Center, insects.p1); RotationDirection default_dir = v_move.Det(v1) > 0 ? RotationDirection.CW : RotationDirection.CCW; if (dir == RotationDirection.Unknown) { if (magnet.IsUndefined) { dir = RotationDirection.CCW; // just something } else { if (insects.p1.DistanceTo(magnet) < insects.p2.DistanceTo(magnet)) // match, use existing dir { dir = default_dir; } else { dir = (default_dir == RotationDirection.CCW) ? RotationDirection.CW : RotationDirection.CCW; // flip } } } Arc2F arc; if (default_dir == dir) { arc = new Arc2F(this.Center, insects.p1, insects.p2, dir); } else { arc = new Arc2F(this.Center, insects.p2, insects.p1, dir); } _segments.Add(arc); calc_teds(tool_r); if (_mid_ted <= 0) { Logger.warn("forced to patch mid_ted"); _mid_ted = coarse_ted; // shouldn't be, but ok } _max_ted = Math.Max(_mid_ted, _entry_ted); }