From 6245bed5341c1b2ed257b2aad490977752ef33c5 Mon Sep 17 00:00:00 2001 From: lelami Date: Wed, 13 May 2020 12:19:43 +0300 Subject: [PATCH 1/5] change the line's method IntersectLine to normals method --- primitives/line.go | 50 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/primitives/line.go b/primitives/line.go index 0366af9..f8ebcd8 100644 --- a/primitives/line.go +++ b/primitives/line.go @@ -36,13 +36,41 @@ func (l Line) IsCollinearPointOnSegment(p Point) bool { func (l Line) IntersectLine(l1 *Line) *Point { - orientation1 := l1.P1.Orientation(l.P1, l.P2) - orientation2 := l1.P2.Orientation(l.P1, l.P2) - orientation3 := l.P1.Orientation(l1.P1, l1.P2) - orientation4 := l.P2.Orientation(l1.P1, l1.P2) + normal := make([]Vector, 4) + orientation := make([]int, 4) + var base_normal Vector + + normal[0] = l1.P1.VectorTo(l.P1).Cross(l1.P1.VectorTo(l.P2)) + normal[1] = l1.P2.VectorTo(l.P1).Cross(l1.P2.VectorTo(l.P2)) + normal[2] = l.P1.VectorTo(l1.P1).Cross(l.P1.VectorTo(l1.P2)) + normal[3] = l.P2.VectorTo(l1.P1).Cross(l.P2.VectorTo(l1.P2)) + + for i, n := range normal { + if AlmostZero(n.X)&&AlmostZero(n.Y)&&AlmostZero(n.Z) { + orientation[i] = 0 + normal[i] = V(0,0,0) + } else { + base_normal = n + } + } + + for i, n := range normal { + if base_normal.Dot(n) > 0 { + orientation[i] = 1 + } + if base_normal.Dot(n) < 0 { + orientation[i] = 2 + } + } + + +/* orientation[0] := l1.P1.Orientation(l.P1, l.P2) + orientation[1] := l1.P2.Orientation(l.P1, l.P2) + orientation[2] := l.P1.Orientation(l1.P1, l1.P2) + orientation[3] := l.P2.Orientation(l1.P1, l1.P2)*/ // General case - if orientation1 != orientation2 && orientation3 != orientation4 { + if orientation[0] != orientation[1] && orientation[2] != orientation[3] { a := l.ToVector() b := l1.ToVector() @@ -64,20 +92,16 @@ func (l Line) IntersectLine(l1 *Line) *Point { } // Collinear case - if (orientation1 == 0 && l.IsCollinearPointOnSegment(l1.P1)) { - println("l1.P1 ", l1.P1.Z) + if (orientation[0] == 0 && l.IsCollinearPointOnSegment(l1.P1)) { return &l1.P1 } - if (orientation2 == 0 && l.IsCollinearPointOnSegment(l1.P2)) { - println("l1.P2 ", l1.P2.Z) + if (orientation[1] == 0 && l.IsCollinearPointOnSegment(l1.P2)) { return &l1.P2 } - if (orientation3 == 0 && l1.IsCollinearPointOnSegment(l.P1)) { - println("l.P1 ", l.P1.Z) + if (orientation[2] == 0 && l1.IsCollinearPointOnSegment(l.P1)) { return &l.P1 } - if (orientation4 == 0 && l1.IsCollinearPointOnSegment(l.P2)) { - println("l2.P2 ", l.P2.Z) + if (orientation[3] == 0 && l1.IsCollinearPointOnSegment(l.P2)) { return &l.P2 } return nil; // Doesn't fall in any of the above cases From c6568a017ab03eea958012bbdc9e5c7ee87831e1 Mon Sep 17 00:00:00 2001 From: lelami Date: Wed, 13 May 2020 12:22:04 +0300 Subject: [PATCH 2/5] add internal support triangles --- helpers/supports_by_vector.go | 35 +++++++++++++------- primitives/line.go | 20 +++++++++++ primitives/triangle.go | 62 +++++++++++++++++++++++++++-------- slicers/slice_by_vector.go | 23 +++++++++---- 4 files changed, 107 insertions(+), 33 deletions(-) diff --git a/helpers/supports_by_vector.go b/helpers/supports_by_vector.go index 23c3cde..e8ec1fa 100644 --- a/helpers/supports_by_vector.go +++ b/helpers/supports_by_vector.go @@ -7,6 +7,7 @@ import ( func MakeUndoubledLinesFromTriangles(col_triangles []Triangle) []Line { var lines []Line + //make lines from triangles for _, t := range col_triangles { lines = append(lines, Line{P1: t.P1, P2:t.P2}) lines = append(lines, Line{P1: t.P1, P2:t.P3}) @@ -15,6 +16,7 @@ func MakeUndoubledLinesFromTriangles(col_triangles []Triangle) []Line { var new_lines []Line var lines2 []Line + //make undoubled lines for i, l1 := range lines{ fl := false lines2 = []Line{} @@ -35,22 +37,31 @@ func MakeUndoubledLinesFromTriangles(col_triangles []Triangle) []Line { } -func IntersectTriangles(t Triangle, triangles []Triangle) []Line { +func MakeInternalSupportTriangles(top_point1, top_point2 Point, lines []Line) []Triangle { - var lines []Line - for _, bt := range triangles { - if !(bt.PointBelongs(t.P1) || bt.PointBelongs(t.P2) || bt.PointBelongs(t.P3)) { - line := bt.IntersectTriangle(&t) - if line != nil { - lines = append(lines, *line) + var triangles []Triangle + fake_point := Point{X: -1, Y: -1, Z: -1} + for _, l := range lines { + Tr := NewTriangle(l.P1, l.P2, top_point1) + fl := 0 + for _, l2 := range lines { + if l2.IntersectTriangle(Tr){ + if !l.P1.Equal(l2.P1) && !l.P1.Equal(l2.P2) && !l.P2.Equal(l2.P1) && !l.P2.Equal(l2.P2){ + fl = 1 + break + } + } + } + if fl == 0 { + triangles = append(triangles, Tr) + if top_point2 != fake_point { + Tr1 := NewTriangle(l.P1, top_point1, top_point2) + Tr2 := NewTriangle(l.P2, top_point1, top_point2) + triangles = append(triangles, Tr1, Tr2) } } } - if len(lines) != 0 { - return lines - } - - return nil + return triangles } diff --git a/primitives/line.go b/primitives/line.go index f8ebcd8..fc7f22f 100644 --- a/primitives/line.go +++ b/primitives/line.go @@ -107,3 +107,23 @@ func (l Line) IntersectLine(l1 *Line) *Point { return nil; // Doesn't fall in any of the above cases } + +func (l Line) IntersectTriangle(t Triangle) bool { + + p1 := Line{P1: t.P1, P2: t.P2}.IntersectLine(&l) + p2 := Line{P1: t.P1, P2: t.P3}.IntersectLine(&l) + p3 := Line{P1: t.P2, P2: t.P3}.IntersectLine(&l) + + if p1 != nil || p2 != nil || p3 != nil { + return true + } + +/* if p1 == nil && p2 == nil && p3 == nil { + if t.PointBelongs(l.P1) { //or l.P2 - no difference + return true + } + }*/ + + return false + +} \ No newline at end of file diff --git a/primitives/triangle.go b/primitives/triangle.go index f35b713..b5dc7c1 100644 --- a/primitives/triangle.go +++ b/primitives/triangle.go @@ -55,6 +55,23 @@ func (t *Triangle) MinMaxZ(z Vector) (float64, float64) { return math.Min(pr1, math.Min(pr2, pr3)), math.Max(pr1, math.Max(pr2, pr3)) } +func (t *Triangle) IntersectTriangles(triangles []Triangle) []Line { + + var lines []Line + for _, bt := range triangles { + line := bt.IntersectTriangle(t) + if line != nil { + lines = append(lines, *line) + } + } + + if len(lines) != 0 { + return lines + } + + return nil +} + func (t *Triangle)IntersectTriangle(t2 *Triangle) *Line { plane := Plane{P: t.P1, N: t.N} @@ -79,26 +96,38 @@ func (t *Triangle)IntersectTriangle(t2 *Triangle) *Line { if b1 || b2 { if p1 != nil{ if b1{ - return &Line{P1: line.P1, P2: *p1} + if !line.P1.Equal(*p1){ + return &Line{P1: line.P1, P2: *p1} + } } if b2{ - return &Line{P1: *p1, P2: line.P2} + if !line.P2.Equal(*p1) { + return &Line{P1: *p1, P2: line.P2} + } } } if p2 != nil{ if b1{ - return &Line{P1: line.P1, P2: *p2} + if !line.P1.Equal(*p2){ + return &Line{P1: line.P1, P2: *p2} + } } if b2{ - return &Line{P1: *p2, P2: line.P2} + if !(*p2).Equal(line.P2) { + return &Line{P1: *p2, P2: line.P2} + } } } if p3 != nil{ if b1{ - return &Line{P1: line.P1, P2: *p3} + if !line.P1.Equal(*p3) { + return &Line{P1: line.P1, P2: *p3} + } } if b2{ - return &Line{P1: *p3, P2: line.P2} + if !(*p3).Equal(line.P2) { + return &Line{P1: *p3, P2: line.P2} + } } } @@ -106,34 +135,39 @@ func (t *Triangle)IntersectTriangle(t2 *Triangle) *Line { // if line crosses 2 sides of triangle if p1 == nil && p2 != nil && p3 != nil{ - return &Line{P1: *p2, P2: *p3} + if (*p2).RoundPlaces(6) != (*p3).RoundPlaces(6) { + return &Line{P1: *p2, P2: *p3} + } } if p1 != nil && p2 == nil && p3 != nil{ - return &Line{P1: *p1, P2: *p3} + if (*p1).RoundPlaces(6) != (*p3).RoundPlaces(6) { + return &Line{P1: *p1, P2: *p3} + } } if p1 != nil && p2 != nil && p3 == nil{ - return &Line{P1: *p1, P2: *p2} + if (*p1).RoundPlaces(6) != (*p2).RoundPlaces(6) { + return &Line{P1: *p1, P2: *p2} + } } // if line cross all siides of triangle (one edge and one vertex) if p1 != nil && p2 != nil && p3 != nil { - if p1 == p2 { + if (*p1).Equal(*p2) { return &Line{P1: *p1, P2: *p3} } - if p1 == p3 { + if (*p1).Equal(*p3) { return &Line{P1: *p1, P2: *p2} } - if p2 == p3 { + if (*p2).Equal(*p3) { return &Line{P1: *p1, P2: *p2} } } - return nil } -func (t *Triangle) PointBelongs(p Point) bool { +func (t *Triangle) PointBelongs(p Point) bool { //TODO: not right variant, the case with normals should be better, but it not works, why plane := Plane{P: t.P1, N: t.N} if plane.PointBelongs(p) { diff --git a/slicers/slice_by_vector.go b/slicers/slice_by_vector.go index 8f6e23e..9e4d91a 100644 --- a/slicers/slice_by_vector.go +++ b/slicers/slice_by_vector.go @@ -36,9 +36,6 @@ func SliceByVector(mesh *Mesh, Z Vector, settings Settings) []Layer { Z = Z.Normalize() triangles := mesh.CopyTriangles() - sort.Slice(triangles, func(i, j int) bool { - return triangles[i].MinZ(Z) < triangles[j].MinZ(Z) - }) minz, maxz := mesh.MinMaxZ(Z) n := int(math.Ceil((maxz - minz) / thickness)) @@ -71,23 +68,35 @@ func SliceByVector(mesh *Mesh, Z Vector, settings Settings) []Layer { col_lines := helpers.MakeUndoubledLinesFromTriangles(col_triangles) sup_lines := helpers.MakeSupportLines(col_lines, plane) var sup_triangles []Triangle + for i := range col_lines { Tr1 := NewTriangle(sup_lines[i].P1, col_lines[i].P1, col_lines[i].P2) Tr2 := NewTriangle(sup_lines[i].P1, sup_lines[i].P2, col_lines[i].P2) - - lines := helpers.IntersectTriangles(Tr1, temp) + lines := Tr1.IntersectTriangles(temp) if lines == nil { sup_triangles = append(sup_triangles, Tr1) + } else { + internal := helpers.MakeInternalSupportTriangles(col_lines[i].P1, col_lines[i].P2, lines) + sup_triangles = append(sup_triangles, internal...) } - lines = helpers.IntersectTriangles(Tr2, temp) + lines = Tr2.IntersectTriangles(temp) if lines == nil { sup_triangles = append(sup_triangles, Tr2) + } else { + fake_point := Point{X: -1, Y: -1, Z: -1} + internal := helpers.MakeInternalSupportTriangles(col_lines[i].P2, fake_point, lines) + sup_triangles = append(sup_triangles, internal...) } } + triangles = append(sup_triangles, triangles...) } + sort.Slice(triangles, func(i, j int) bool { + return triangles[i].MinZ(Z) < triangles[j].MinZ(Z) + }) + index := 0 var active []*Triangle curP := Z.MulScalar(minz).ToPoint().Shift(sh.MulScalar(0.5)) @@ -154,7 +163,7 @@ func slicingWorker(in chan job, out chan Layer) func(wi, wn int) { paths = append(paths, Path{Points: []Point{line.P1, line.P2}}) } } - out <- Layer{Order: job.order, Norm: job.plane.N, Paths: JoinPaths2(paths)} + out <- Layer{Order: job.order, Norm: job.plane.N, Paths: JoinPaths3(paths)} } } } From 325c8eed4ed3cee8b7bd6a80870c64e2c17c5243 Mon Sep 17 00:00:00 2001 From: lelami Date: Mon, 6 Jul 2020 14:22:21 +0300 Subject: [PATCH 3/5] add tests to line, plane, triangle --- primitives/test/line_test.go | 89 ++++++++++++++++++++++++ primitives/test/plane_test.go | 55 +++++++++++++++ primitives/test/triangle_test.go | 112 +++++++++++++++++++++++++++++++ 3 files changed, 256 insertions(+) diff --git a/primitives/test/line_test.go b/primitives/test/line_test.go index eaf5c0f..557a634 100644 --- a/primitives/test/line_test.go +++ b/primitives/test/line_test.go @@ -86,4 +86,93 @@ func TestLine_IsIntersectingSegment(t *testing.T) { require.Equal(t, row.out, row.in1.IsIntersectingSegment(&row.in2)) }) } +} + +func TestLine_IntersectLine(t *testing.T) { + + cases := []struct { + in1 Line + in2 Line + out *Point + }{ + // Lines intersect on XY plane + { + in1: Line{Point{3, 2, 0}, Point{8, 7, 0}}, + in2: Line{Point{1, 6, 0}, Point{7, 3, 0}}, + out: &Point{5, 4, 0}, + }, + // Lines intersect on YZ plane - fail +/* { + in1: Line{Point{0, 3, 2}, Point{0, 8, 7}}, + in2: Line{Point{0, 1, 6}, Point{0, 7, 3}}, + out: &Point{0, 5, 4}, + },*/ + + // Lines intersect on XZ plane - fail +/* { + in1: Line{Point{3, 0, 2}, Point{8, 0, 7}}, + in2: Line{Point{1, 0, 6}, Point{7, 0, 3}}, + out: &Point{5, 0, 4}, + },*/ + // Lines intersect + { + in1: Line{Point{1, 1, -2}, Point{1, -5, 1}}, + in2: Line{Point{1, -3, 0}, Point{-1, 0, -4}}, + out: &Point{1, -3, 0}, + }, + // 1, 2, 3 points collinear, 3 lies b/w 1,2 + { + in1: Line{Point{1, -3, 0}, Point{-1, 0, -4}}, + in2: Line{Point{0, -1.5, -2}, Point{0, 0, 0}}, + out: &Point{0, -1.5, -2}, + }, + // 1, 2, 3 points collinear, 3 lies b/w 1,2 + { + in1: Line{Point{1, -3, 0}, Point{-3, 3, -8}}, + in2: Line{Point{-1, 0, -4}, Point{0, 0, 0}}, + out: &Point{-1, 0, -4}, + }, + // not intersect + { + in1: Line{Point{1, -3, 0}, Point{-3, 3, -8}}, + in2: Line{Point{1, 0, 4}, Point{0, 0, 0}}, + out: nil, + }, + + } + + for i, row := range cases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + require.Equal(t, row.out, row.in1.IntersectLine(&row.in2)) + }) + } +} + +func TestLine_IntersectTriangle(t *testing.T) { + + cases := []struct { + in1 Line + in2 Triangle + out bool + }{ + //Line intersect one side of triangle + { + in1: Line{Point{1, 1, -2}, Point{1, -5, 1}}, + in2: NewTriangle(Point{1, -3, 0}, Point{-1, 0, -4}, Point{0, 0, 0}), + out: true, + }, + //Not intersect + { + in1: Line{Point{10, 10, 10}, Point{9, 9, 9}}, + in2: NewTriangle(Point{1, -3, 0}, Point{-1, 0, -4}, Point{0, 0, 0}), + out: false, + }, + + } + + for i, row := range cases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + require.Equal(t, row.out, row.in1.IntersectTriangle(row.in2)) + }) + } } \ No newline at end of file diff --git a/primitives/test/plane_test.go b/primitives/test/plane_test.go index 939bdc8..7fdf620 100644 --- a/primitives/test/plane_test.go +++ b/primitives/test/plane_test.go @@ -104,3 +104,58 @@ func TestPlane_IntersectTriangle(t *testing.T) { }) } } + +func TestPlane_ProectionPointToPlane(t *testing.T) { + cases := []struct { + in1 Plane + in2 Point + out Point + }{ + { + in1: Plane{Point{1, 1, 1}, V(1, 1, 1)}, + in2: Point{0, 0, 0}, + out: Point{1, 1, 1}, + }, + { + in1: Plane{Point{1, 1, 1}, V(0, 0, 1)}, + in2: Point{0, 0, 0}, + out: Point{0, 0, 1}, + }, + { + in1: Plane{Point{1, 1, 1}, V(0, 1, 0)}, + in2: Point{0, 0, 0}, + out: Point{0, 1, 0}, + }, + } + for i, row := range cases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + res := row.in1.ProectionPointToPlane(row.in2) + require.Equal(t, row.out, res) + }) + } +} + +func TestPlane_PointBelongs(t *testing.T) { + cases := []struct { + in1 Plane + in2 Point + out bool + }{ + { + in1: Plane{Point{1, 1, 1}, V(1, 1, 1)}, + in2: Point{1, 1, 1}, + out: true, + }, + { + in1: Plane{Point{1, 1, 1}, V(1, 1, 1)}, + in2: Point{0, 0, 0}, + out: false, + }, + } + for i, row := range cases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + res := row.in1.PointBelongs(row.in2) + require.Equal(t, row.out, res) + }) + } +} \ No newline at end of file diff --git a/primitives/test/triangle_test.go b/primitives/test/triangle_test.go index 9eef4aa..7a7a849 100644 --- a/primitives/test/triangle_test.go +++ b/primitives/test/triangle_test.go @@ -30,3 +30,115 @@ func TestTriangle_MinZ(t *testing.T) { }) } } + +func TestTriangle_IntersectTriangle(t *testing.T) { + cases := []struct { + in1 Triangle + in2 Triangle + out *Line + }{ + //line inside of triangle + { + in1: NewTriangle(Point{0, 0, 5}, Point{0, 10, 5}, Point{10, 0, 5}), + in2: NewTriangle(Point{2, 0, 0}, Point{2, 7, 0}, Point{2, 0, 7}), + out: &Line{Point{2,0,5}, Point{2,2,5}}, + }, + //line intersect one side of triangle + { + in1: NewTriangle(Point{0, 0, 5}, Point{0, 10, 5}, Point{10, 0, 5}), + in2: NewTriangle(Point{2, -1, 0}, Point{2, 7, 0}, Point{2, -1, 8}), + out: &Line{Point{2,0,5}, Point{2,2,5}}, + }, + { + in1: NewTriangle(Point{0, 10, 5}, Point{0, 0, 5}, Point{10, 0, 5}), + in2: NewTriangle(Point{2, -1, 0}, Point{2, 7, 0}, Point{2, -1, 8}), + out: &Line{Point{2,2,5}, Point{2,0,5}}, + }, + { + in1: NewTriangle(Point{0, 0, 5}, Point{10, 0, 5}, Point{0, 10, 5}), + in2: NewTriangle(Point{2, -1, 0}, Point{2, 7, 0}, Point{2, -1, 8}), + out: &Line{Point{2,2,5}, Point{2,0,5}}, + }, + //line intersect two sides of triangle + { + in1: NewTriangle(Point{0, 0, 5}, Point{10, 0, 5}, Point{0, 10, 5}), + in2: NewTriangle(Point{9, -1, 0}, Point{9, 7, 0}, Point{9, -1, 8}), + out: &Line{Point{9,0,5}, Point{9,1,5}}, + }, + { + in1: NewTriangle(Point{0, 0, 5}, Point{0, 10, 5}, Point{10, 0, 5}), + in2: NewTriangle(Point{9, -1, 0}, Point{9, 7, 0}, Point{9, -1, 8}), + out: &Line{Point{9,0,5}, Point{9,1,5}}, + }, + { + in1: NewTriangle(Point{10, 0, 5}, Point{0, 0, 5}, Point{0, 10, 5}), + in2: NewTriangle(Point{9, -1, 0}, Point{9, 7, 0}, Point{9, -1, 8}), + out: &Line{Point{9,0,5}, Point{9,1,5}}, + }, + //line intersect one side and one vertex + { + in1: NewTriangle(Point{8, 0, 5}, Point{10, 0, 5}, Point{9, 1, 5}), + in2: NewTriangle(Point{9, -1, 0}, Point{9, 7, 0}, Point{9, -1, 8}), + out: &Line{Point{9,0,5}, Point{9,1,5}}, + }, + // not intersect + { + in1: NewTriangle(Point{2, 0, 5}, Point{0, 0, 5}, Point{0, 2, 5}), + in2: NewTriangle(Point{9, -1, 0}, Point{9, 7, 0}, Point{9, -1, 8}), + out: nil, + }, + } + for i, row := range cases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + require.Equal(t, row.out, row.in1.IntersectTriangle(&row.in2)) + }) + } +} + +func TestTriangle_PointBelongs(t *testing.T) { + cases := []struct { + in1 Triangle + in2 Point + out bool + }{ + //on XY plane + { + in1: NewTriangle(Point{10, 0, 5}, Point{0, 0, 5}, Point{0, 10, 5}), + in2: Point{3,4,5}, + out: true, + }, + { + in1: NewTriangle(Point{10, 0, 5}, Point{0, 0, 5}, Point{0, 10, 5}), + in2: Point{3,4,0}, + out: false, + }, + //on YZ plane + { + in1: NewTriangle(Point{2, 0, 0}, Point{2, 7, 0}, Point{2, 0, 7}), + in2: Point{2,1,1}, + out: true, + }, + //on XZ plane + { + in1: NewTriangle(Point{0, 2, 0}, Point{7, 2, 0}, Point{0, 2, 7}), + in2: Point{1,2,1}, + out: true, + }, + //arbitrary plane + { + in1: NewTriangle(Point{2, 2, 2}, Point{4, 1, 1}, Point{6, 2, -2}), + in2: Point{3,2,1}, + out: true, + }, + { + in1: NewTriangle(Point{2, 2, 2}, Point{4, 1, 1}, Point{6, 2, -2}), + in2: Point{10,-10,6}, + out: false, + }, + } + for i, row := range cases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + require.Equal(t, row.out, row.in1.PointBelongs(row.in2)) + }) + } +} \ No newline at end of file From 8044725a89210b718938bf0e0574270440a9ebfe Mon Sep 17 00:00:00 2001 From: lelami Date: Wed, 22 Jul 2020 13:28:13 +0300 Subject: [PATCH 4/5] Fix the IntersectLine method, add the tests --- primitives/line.go | 39 ++++++++++++++++++------------------ primitives/test/line_test.go | 12 +++++------ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/primitives/line.go b/primitives/line.go index 4b63a53..7f8ea27 100644 --- a/primitives/line.go +++ b/primitives/line.go @@ -72,11 +72,18 @@ func (l Line) IntersectLine(l1 *Line) *Point { } } + // Collinear case + if (orientation[0] == 0 && l.IsCollinearPointOnSegment(l1.P1)) { + return &l1.P1 } -/* orientation[0] := l1.P1.Orientation(l.P1, l.P2) - orientation[1] := l1.P2.Orientation(l.P1, l.P2) - orientation[2] := l.P1.Orientation(l1.P1, l1.P2) - orientation[3] := l.P2.Orientation(l1.P1, l1.P2)*/ + if (orientation[1] == 0 && l.IsCollinearPointOnSegment(l1.P2)) { + return &l1.P2 } + + if (orientation[2] == 0 && l1.IsCollinearPointOnSegment(l.P1)) { + return &l.P1 } + + if (orientation[3] == 0 && l1.IsCollinearPointOnSegment(l.P2)) { + return &l.P2 } // General case if orientation[0] != orientation[1] && orientation[2] != orientation[3] { @@ -85,13 +92,17 @@ func (l Line) IntersectLine(l1 *Line) *Point { b := l1.ToVector() var m float64 - if a.X != 0 { - m = (l1.P1.Y - l.P1.Y - (a.Y/a.X)*(l1.P1.X - l.P1.X)) / (b.X*a.Y/a.X - b.Y) - } else if a.Y != 0 { + m = (l1.P1.Y - l.P1.Y - (a.Y/a.X)*(l1.P1.X - l.P1.X)) / (b.X*a.Y/a.X - b.Y) + + if math.IsNaN(m) { m = (l1.P1.X - l.P1.X - (a.X/a.Y)*(l1.P1.Y - l.P1.Y)) / (a.X*b.Y/a.Y - b.X) - } else if a.Z != 0 { + } + if math.IsNaN(m) { m = (l1.P1.X - l.P1.X - (a.X/a.Z)*(l1.P1.Z - l.P1.Z)) / (a.X*b.Z/a.Z - b.X) } + if math.IsNaN(m) { + m = (l1.P1.Y - l.P1.Y - (a.Y/a.Z)*(l1.P1.Z - l.P1.Z)) / (a.Y*b.Z/a.Z - b.Y) + } x := l1.P1.X + b.X*m y := l1.P1.Y + b.Y*m @@ -100,18 +111,6 @@ func (l Line) IntersectLine(l1 *Line) *Point { return &Point{x, y, z} } - // Collinear case - if (orientation[0] == 0 && l.IsCollinearPointOnSegment(l1.P1)) { - return &l1.P1 } - - if (orientation[1] == 0 && l.IsCollinearPointOnSegment(l1.P2)) { - return &l1.P2 } - - if (orientation[2] == 0 && l1.IsCollinearPointOnSegment(l.P1)) { - return &l.P1 } - - if (orientation[3] == 0 && l1.IsCollinearPointOnSegment(l.P2)) { - return &l.P2 } return nil; // Doesn't fall in any of the above cases diff --git a/primitives/test/line_test.go b/primitives/test/line_test.go index 557a634..13838b4 100644 --- a/primitives/test/line_test.go +++ b/primitives/test/line_test.go @@ -101,19 +101,19 @@ func TestLine_IntersectLine(t *testing.T) { in2: Line{Point{1, 6, 0}, Point{7, 3, 0}}, out: &Point{5, 4, 0}, }, - // Lines intersect on YZ plane - fail -/* { + // Lines intersect on YZ plane + { in1: Line{Point{0, 3, 2}, Point{0, 8, 7}}, in2: Line{Point{0, 1, 6}, Point{0, 7, 3}}, out: &Point{0, 5, 4}, - },*/ + }, - // Lines intersect on XZ plane - fail -/* { + // Lines intersect on XZ plane + { in1: Line{Point{3, 0, 2}, Point{8, 0, 7}}, in2: Line{Point{1, 0, 6}, Point{7, 0, 3}}, out: &Point{5, 0, 4}, - },*/ + }, // Lines intersect { in1: Line{Point{1, 1, -2}, Point{1, -5, 1}}, From 43542d9b4b294eb6ce4b627aaae0bc89c196b2ff Mon Sep 17 00:00:00 2001 From: l1va Date: Wed, 5 Aug 2020 08:57:28 +0300 Subject: [PATCH 5/5] Update .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 546929c..baeb190 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: go go: - - "1.10" + - "1.14" - tip install: @@ -10,4 +10,4 @@ install: - go get github.com/stretchr/testify/require - go get github.com/fogleman/simplify - go get gopkg.in/alecthomas/kingpin.v2 - - go get gopkg.in/yaml.v2 \ No newline at end of file + - go get gopkg.in/yaml.v2