Тодор обнови решението на 21.11.2018 03:56 (преди 9 месеца)
+package main
+
+import (
+ "math"
+
+ "github.com/fmi/go-homework/geom"
+)
+
+type Plane struct {
+ a float64
+ b float64
+ c float64
+ d float64
+}
+
+type Triangle struct {
+ a geom.Vector
+ b geom.Vector
+ c geom.Vector
+}
+
+func NewTriangle(a, b, c geom.Vector) Triangle {
+ return Triangle{
+ a: a,
+ b: b,
+ c: c,
+ }
+}
+
+func (t Triangle) Intersect(ray geom.Ray) bool {
+ intersectionPoint := findIntersectionPoint(t.a, t.b, t.c, ray)
+ area := findAreaByVectors(t.a, t.b, t.c)
+ combinedIntersection := findAreaByVectors(t.a, t.b, intersectionPoint) + findAreaByVectors(t.b, t.c, intersectionPoint) + findAreaByVectors(t.a, t.c, intersectionPoint)
+ return (math.Abs(area-combinedIntersection) < math.Pow(10, -10)) && ((intersectionPoint.X-ray.Origin.X)/ray.Direction.X > 0)
+}
+
+type Quad struct {
+ a geom.Vector
+ b geom.Vector
+ c geom.Vector
+ d geom.Vector
+}
+
+func NewQuad(a, b, c, d geom.Vector) Quad {
+ return Quad{
+ a: a,
+ b: b,
+ c: c,
+ d: d,
+ }
+}
+
+func (q Quad) Intersect(ray geom.Ray) bool {
+ intersectionPoint := findIntersectionPoint(q.a, q.b, q.c, ray)
+ area := findAreaByVectors(q.a, q.b, q.c) + findAreaByVectors(q.b, q.c, q.d)
+ combinedIntersection := findAreaByVectors(q.a, q.b, intersectionPoint) + findAreaByVectors(q.b, q.c, intersectionPoint) + findAreaByVectors(q.c, q.d, intersectionPoint) + findAreaByVectors(q.d, q.a, intersectionPoint)
+ return (math.Abs(area-combinedIntersection) < math.Pow(10, -10)) && ((intersectionPoint.X-ray.Origin.X)/ray.Direction.X > 0)
+}
+
+type Sphere struct {
+ o geom.Vector
+ radius float64
+}
+
+func NewSphere(origin geom.Vector, r float64) Sphere {
+ return Sphere{
+ o: origin,
+ radius: r,
+ }
+}
+
+func (s Sphere) Intersect(ray geom.Ray) bool {
+ originToCenterRay := geom.Ray{Origin: ray.Origin, Direction: geom.Vector{X: s.o.X, Y: s.o.Y, Z: s.o.Z}}
+ tc := (ray.Direction.X-ray.Origin.X)*(originToCenterRay.Direction.X-originToCenterRay.Direction.X) + (ray.Direction.Y-ray.Origin.Y)*(originToCenterRay.Direction.Y-originToCenterRay.Direction.Y) + (ray.Direction.Z-ray.Origin.Z)*(originToCenterRay.Direction.Z-originToCenterRay.Direction.Z)
+ if tc < 0 {
+ return false
+ }
+ l := math.Sqrt(math.Pow((originToCenterRay.Direction.X-originToCenterRay.Direction.X), 2) + math.Pow((originToCenterRay.Direction.Y-originToCenterRay.Direction.Y), 2) + math.Pow((originToCenterRay.Direction.Z-originToCenterRay.Direction.Z), 2))
+ d := math.Sqrt(math.Pow(tc, 2) + math.Pow(l, 2))
+ if d > s.radius {
+ return false
+ }
+ return true
+}
+
+func findAreaByVectors(a, b, c geom.Vector) float64 {
+ abRay := geom.Ray{Origin: a, Direction: geom.Vector{X: b.X - a.X, Y: b.Y - a.Y, Z: b.Z - a.Z}}
+ acRay := geom.Ray{Origin: a, Direction: geom.Vector{X: c.X - a.X, Y: c.Y - a.Y, Z: c.Z - a.Z}}
+ planeA := abRay.Direction.Y*acRay.Direction.Z - abRay.Direction.Z*acRay.Direction.Y
+ planeB := -(abRay.Direction.X*acRay.Direction.Z - abRay.Direction.Z*acRay.Direction.X)
+ planeC := abRay.Direction.X*acRay.Direction.Y - abRay.Direction.Y*acRay.Direction.X
+ return 0.5 * math.Sqrt(math.Pow(planeA, 2)+math.Pow(planeB, 2)+math.Pow(planeC, 2))
+}
+
+func findIntersectionPoint(a, b, c geom.Vector, ray geom.Ray) geom.Vector {
+ abRay := geom.Ray{Origin: a, Direction: geom.Vector{X: b.X - a.X, Y: b.Y - a.Y, Z: b.Z - a.Z}}
+ acRay := geom.Ray{Origin: a, Direction: geom.Vector{X: c.X - a.X, Y: c.Y - a.Y, Z: c.Z - a.Z}}
+ planeA := abRay.Direction.Y*acRay.Direction.Z - abRay.Direction.Z*acRay.Direction.Y
+ planeB := -(abRay.Direction.X*acRay.Direction.Z - abRay.Direction.Z*acRay.Direction.X)
+ planeC := abRay.Direction.X*acRay.Direction.Y - abRay.Direction.Y*acRay.Direction.X
+ planeD := planeA*abRay.Origin.X + planeB*abRay.Origin.Y + planeC*abRay.Origin.Z
+ t := (planeD - planeA*ray.Origin.X - planeB*ray.Origin.Y - planeC*ray.Origin.Z) / (planeA*ray.Direction.X + planeB*ray.Direction.Y + planeC*ray.Direction.Z)
+ intersectionPoint := geom.Vector{X: ray.Origin.X + t*ray.Direction.X, Y: ray.Origin.Y + t*ray.Direction.Y, Z: ray.Origin.Z + t*ray.Direction.Z}
+ return intersectionPoint
+}
+
+func main() {
+}
Малко помощни функции за работа с вектори ще са полезни на решението ти. Също така, бих ти препоръчал да го тестваш малко.