public seg2d(xy _a, xy _b) { a = _a; b = _b; Debug.Assert(!fp.eq_inches(a, b)); }
public static TriangleIntersection3d CalcTriangleIntersection3d(Triangle3d t1, Triangle3d t2) { if (ut.AllVerticesPlanar(t1, t2)) { TriangleIntersection3d ti = new TriangleIntersection3d(); xyz n = t1.n; xyz i = t1.iv; xyz j = t1.jv; xy a1 = ut.ConvertPointTo2d(t1.a, t1.a, i, j); xy b1 = ut.ConvertPointTo2d(t1.b, t1.a, i, j); xy c1 = ut.ConvertPointTo2d(t1.c, t1.a, i, j); xy a2 = ut.ConvertPointTo2d(t2.a, t1.a, i, j); xy b2 = ut.ConvertPointTo2d(t2.b, t1.a, i, j); xy c2 = ut.ConvertPointTo2d(t2.c, t1.a, i, j); TriangleIntersection2d ti2d = TriangleIntersection2d.CalcTriangleIntersection2d(a1, b1, c1, a2, b2, c2); if (ti2d.Count > 0) { foreach (xy p in ti2d) { xyz q = ut.Convert2dPointTo3d(p, t1.a, i, j); ti.Add(q); } } return(ti); } else { return(CalcTriangleIntersection3d_NotCoplanar(t1, t2)); } }
internal bool PointInside(xyz p) { #if false Triangle2d t2d = this.ConvertTo2d(a, iv, jv); xy pt2d = ut.ConvertPointTo2d(p, a, iv, jv); return(t2d.PointInside(pt2d)); #else if (fp.lt_unknowndata(xyz.dot(xyz.cross_subs(p, a, b), n), 0)) { return(false); } else if (fp.lt_unknowndata(xyz.dot(xyz.cross_subs(p, b, c), n), 0)) { return(false); } else if (fp.lt_unknowndata(xyz.dot(xyz.cross_subs(p, c, a), n), 0)) { return(false); } else { return(true); } #endif }
public void Add(xy p) { Debug.Assert( (q1 == null) || fp.eq_inches(q1, p) || (q2 == null) || fp.eq_inches(q2, p) ); if (q1 == null) { q1 = p; return; } if (fp.eq_inches(q1, p)) { return; } if (q2 == null) { q2 = p; return; } if (fp.eq_inches(q2, p)) { return; } }
internal Triangle2d ConvertTo2d(xyz origin, xyz i, xyz j) { xy a2d = ut.ConvertPointTo2d(a, origin, i, j); xy b2d = ut.ConvertPointTo2d(b, origin, i, j); xy c2d = ut.ConvertPointTo2d(c, origin, i, j); return(new Triangle2d(a2d, b2d, c2d)); }
public bool PointInside(xy p) { // this assumes that the triangle (a,b,c) is ccw return( (ut.PointSideOfLine(p, a, b) <= 0) && (ut.PointSideOfLine(p, b, c) <= 0) && (ut.PointSideOfLine(p, c, a) <= 0) ); }
public static bool eq_inches(xy a, xy b) { if (object.ReferenceEquals(a, b)) { return(true); } return(fp.eq_inches(a.x, b.x) && fp.eq_inches(a.y, b.y)); }
private static Solid CreateCutter_Box(string name, HalfEdge he, xy pos, xyz size, string[] fnames) { Face f = he.face; xyz vx = (he.to - he.from).normalize_in_place(); xyz nrml = f.UnitNormal(); xyz vy = xyz.cross(nrml, vx).normalize_in_place(); xyz origin = (vx * pos.x).add_in_place(he.from).add_in_place(vy * pos.y); return(CreateCutter_Box(name, origin, vx, nrml, size, fnames)); }
private static void CreateCutter_Drill(Solid s, HalfEdge he, xy pos, double diameter, double depth, string id) { Face f = he.face; xyz vx = (he.to - he.from).normalize_in_place(); xyz nrml = f.UnitNormal(); xyz vy = xyz.cross(nrml, vx).normalize_in_place(); xyz center = (vx * pos.x).add_in_place(he.from).add_in_place(vy * pos.y); CreateCutter_Drill(s, center, vx, nrml, diameter, depth, id); }
public void test_point_distancetoline() { xy v1 = new xy(0, 0); xy v2 = new xy(8, 0); xy p = new xy(3, -0.001); xy diff = (v2 - v1).normalize(); xy other = p - v1; double d = xy.kross(other, diff); Console.WriteLine(d); }
public xy copy() { xy p = new xy(x, y); // TODO is the following correct? if (orig != null) { p.orig = orig.copy(); } return(p); }
public static void add_seg(List <seg2d> segs, xy a, xy b) { seg2d already = find_seg(segs, a, b); if (already != null) { return; } segs.Add(new seg2d(a, b)); }
public void test_xy_copy() { xy p1 = new xy(5, 5); xy p2 = p1.copy(); Assert.AreEqual(5, p2.x); Assert.IsTrue(fp.eq_unitvec(p1, p2)); Assert.IsFalse(p1.GetHashCode() == p2.GetHashCode()); p1.x = 9; Assert.IsFalse(fp.eq_unitvec(p1, p2)); }
public static bool eq_unitvec(xy a, xy b) { if (object.ReferenceEquals(a, b)) { return(true); } const double eps = 0.0001; // TODO return(fp.eq_tol(a.x, b.x, eps) && fp.eq_tol(a.y, b.y, eps)); }
public Triangle2d(xy _a, xy _b, xy _c) { a = _a; b = _b; c = _c; Debug.Assert(ut.PointSideOfLine(c, a, b) < 0); #if false if (ut.PointSideOfLine(c, a, b) >= 0) { throw new GeomCheckException("Triangle must be counterclockwise, not collinear"); } #endif }
public static seg2d find_seg_a(List <seg2d> segs, xy p, out xy next) { next = null; seg2d result = null; foreach (seg2d s in segs) { if (fp.eq_inches(s.a, p)) { next = s.b; result = s; break; } } return(result); }
public void Add(xy p) { if (pts == null) { pts = new List <xy>(); } foreach (xy q in pts) { if (fp.eq_inches(p, q)) { return; } } pts.Add(p); }
public static bool SplitsVEP(xyz n1, xyz n2a, xyz n2b, xyz fn2a, xyz fn2b) { if (fp.eq_unitvec(n2a, -n2b)) { if (fp.eq_unitvec(n1, fn2a)) { return(true); } else { return(false); } } xyz n = xyz.cross(n2a, n2b); xyz iv = n2a; xyz jv = xyz.cross(n, iv).normalize_in_place(); xy p2a = ut.ConvertPointTo2d(n2a, iv, jv); xy p2b = ut.ConvertPointTo2d(n2b, iv, jv); xy p = ut.ConvertPointTo2d(n1, iv, jv); double d = xyz.dot(fn2a, n2b); Debug.Assert(!fp.eq_dot_unit(d, 0), "If d were zero, the case above should have caught it."); if (d > 0) { bool b = ut.SegmentInCone(new xy(0, 0), p, p2a, p2b); #if BOOL_DEBUG Console.Out.WriteLine("SplitsVEP: n1={0} n2a={1} n2b={2} p={3} p2a={4} p2b={5} result={6}", n1, n2a, n2b, p, p2a, p2b, b); #endif return(b); } else { bool b = ut.SegmentInCone(new xy(0, 0), p, p2b, p2a); #if BOOL_DEBUG Console.Out.WriteLine("SplitsVEP: n1={0} n2a={1} n2b={2} p={3} p2a={4} p2b={5} result={6}", n1, n2a, n2b, p, p2a, p2b, b); #endif return(b); } }
public static CompoundSolid Mortise(CompoundSolid sol, HalfEdge he, xy pos, xyz size, int count, Inches dx, Inches dy, string id) { Solid cutter; if (count == 1) { string[] fnames = new string[] { "NA", "right", "left", "bottom", "front", "back", }; cutter = CreateCutter_Box(id, he, pos, size, fnames); } else { cutter = new Solid(id, BoardMaterial.Find(BoardMaterial.NONE)); Inches x = pos.x; Inches y = pos.y; for (int i = 0; i < count; i++) { string[] fnames = new string[] { string.Format("NA_{0}", i + 1), string.Format("right_{0}", i + 1), string.Format("left_{0}", i + 1), string.Format("bottom_{0}", i + 1), string.Format("front_{0}", i + 1), string.Format("back_{0}", i + 1), }; CreateCutter_Box(cutter, he, new xy(x, y), size, fnames); x += dx; y += dy; } cutter.RecalcFacePlanes(); } return(bool3d.Subtract(sol, cutter)); }
public bool PointOutside(xy p) { if (fp.lt_inches(p.x, xmin)) { return(true); } if (fp.gt_inches(p.x, xmax)) { return(true); } if (fp.lt_inches(p.y, ymin)) { return(true); } if (fp.gt_inches(p.y, ymax)) { return(true); } return(false); }
public static void FindTheLoops(List <List <xy> > loops, List <seg2d> segs) { #if not bool bTricky = need_to_find_loop_starting_point(segs); #endif while (segs.Count > 0) { List <xy> pts = new List <xy>(); seg2d cur; #if not if (bTricky) { cur = find_loop_starting_point(segs); } else #endif { cur = segs[0]; } pts.Add(cur.a); pts.Add(cur.b); segs.Remove(cur); xy p0 = cur.a; xy plast = cur.b; while (true) { xy next; cur = seg2d.find_seg_a(segs, plast, out next); Debug.Assert(cur != null); segs.Remove(cur); if (fp.eq_inches(next, p0)) { // loop closed break; } pts.Add(next); plast = next; } loops.Add(pts); } }
public static void find_seg(List <seg2d> segs, xy p, out xy nextpt, out seg2d seg) { seg = null; nextpt = null; foreach (seg2d s in segs) { if (fp.eq_inches(s.a, p)) { seg = s; nextpt = s.b; break; } if (fp.eq_inches(s.b, p)) { seg = s; nextpt = s.a; break; } } Debug.Assert(seg != null); }
public static seg2d find_seg(List <seg2d> segs, xy a, xy b) { foreach (seg2d s in segs) { if ( (fp.eq_inches(s.a, a)) && (fp.eq_inches(s.b, b)) ) { return(s); } if ( (fp.eq_inches(s.a, b)) && (fp.eq_inches(s.b, a)) ) { return(s); } } return(null); }
public static CompoundSolid Tenon(CompoundSolid sol, HalfEdge he, xy pos, xyz size, string id) { Face f = he.face; EdgeLoop el = he.face.GetEdgeLoopFor(he); int ndx = el.IndexOf(he); ndx--; if (ndx < 0) { ndx += el.Count; } HalfEdge prevHe = el[ndx]; if (!fp.eq_inches(pos.y, 0)) { Solid cut = CreateCutter_Box(id, he, new xy(0, 0), new xyz(he.Length(), pos.y, size.z), new string[] { "NA_1", "NA_2", "NA_3", "frontshoulder", "NA_4", "front" }); sol = bool3d.Subtract(sol, cut); } if (!fp.eq_inches(pos.x, 0)) { Solid cut = CreateCutter_Box(id, he, new xy(0, pos.y), new xyz(pos.x, size.y, size.z), new string[] { "NA_1", "left", "NA_2", "leftshoulder", "NA_3", "NA_4" }); sol = bool3d.Subtract(sol, cut); } if ((pos.y + size.y) < prevHe.Length()) { Solid cut = CreateCutter_Box(id, he, new xy(0, pos.y + size.y), new xyz(he.Length(), prevHe.Length() - (pos.y + size.y), size.z), new string[] { "NA_1", "NA_2", "NA_3", "backshoulder", "back", "NA_4" }); sol = bool3d.Subtract(sol, cut); } if ((pos.x + size.x) < he.Length()) { Solid cut = CreateCutter_Box(id, he, new xy((pos.x + size.x), pos.y), new xyz(he.Length() - (pos.x + size.x), size.y, size.z), new string[] { "NA_1", "NA_2", "right", "rightshoulder", "NA_3", "NA_4" }); sol = bool3d.Subtract(sol, cut); } return(sol); }
internal bool PointInside(xy p) { if (bb.PointOutside(p)) { return(false); } if (!ut.PointInsidePoly(loops[0], p)) { return(false); } for (int i = 1; i < loops.Count; i++) { if (ut.PointInsidePoly(loops[i], p)) { return(false); } } return(true); }
public static double kross(xy a, xy b) { return(a.x * b.y - a.y * b.x); }
public static xy operator -(xy a, xy b) { xy n = new xy(a.x - b.x, a.y - b.y); return(n); }
public static xy operator +(xy a, xy b) { xy n = new xy(a.x + b.x, a.y + b.y); return(n); }
internal bool SegmentIntersection(xy p, xy q, out xy pt1, out xy pt2) { TriSegIntersect ti = new TriSegIntersect(); if (this.PointInside(p)) { ti.Add(p); } if (this.PointInside(q)) { ti.Add(q); } xy z1, z2; SegIntersection si = ut.GetSegIntersection(a, b, p, q, out z1, out z2); if (si == SegIntersection.Overlap) { pt1 = z1; pt2 = z2; return(true); } if (si == SegIntersection.Point) { ti.Add(z1); } si = ut.GetSegIntersection(b, c, p, q, out z1, out z2); if (si == SegIntersection.Overlap) { pt1 = z1; pt2 = z2; return(true); } if (si == SegIntersection.Point) { ti.Add(z1); } si = ut.GetSegIntersection(c, a, p, q, out z1, out z2); if (si == SegIntersection.Overlap) { pt1 = z1; pt2 = z2; return(true); } if (si == SegIntersection.Point) { ti.Add(z1); } if (ti.q1 == null) { pt1 = null; pt2 = null; return(false); } pt1 = ti.q1; if (ti.q2 != null) { pt2 = ti.q2; } else { pt2 = null; } return(true); }
public static double dot(xy a, xy b) { // x1*x2 + y1*y2 return(a.x * b.x + a.y * b.y); }