Хакан обнови решението на 18.11.2018 14:50 (преди 9 месеца)
+package main
+
+import (
+ "github.com/fmi/go-homework/geom"
+ "math"
+)
+
+const epsilon float64 = 0.0000001
+
+type Triangle struct {
+ a, b, c geom.Vector
+}
+
+func NewTriangle(a, b, c geom.Vector) Triangle {
+ return Triangle{a, b, c}
+}
+
+func (my Triangle) Intersect(ray geom.Ray) bool {
+ edge1 := subVectors(my.b, my.a)
+ edge2 := subVectors(my.c, my.a)
+ h := cross(ray.Direction, edge2)
+ a := dot(edge1, h)
+ if a > -epsilon && a < epsilon {
+ return false // parallel
+ }
+ f := 1.0 / a
+ s := subVectors(ray.Origin, my.a)
+ u := f * (dot(s, h))
+ if u < 0.0 || u > 1.0 {
+ return false
+ }
+ q := cross(s, edge1)
+ v := f * dot(ray.Direction, q)
+ if v < 0.0 || v > 1.0 {
+ return false
+ }
+ return true
+}
+
+type Quad struct {
+ a, b, c, d geom.Vector
+}
+
+func NewQuad(a, b, c, d geom.Vector) Quad {
+ return Quad{a, b, c, d}
+}
+
+func (my Quad) Intersect(ray geom.Ray) bool {
+ firstTriangle, secondTriangle := separateRect(my)
+ return firstTriangle.Intersect(ray) || secondTriangle.Intersect(ray)
+}
+
+func separateRect(rect Quad) (Triangle, Triangle) {
+ return Triangle{rect.a, rect.b, rect.c}, Triangle{rect.a, rect.d, rect.c}
+}
+
+type Sphere struct {
+ origin geom.Vector
+ r float64
+}
+
+func NewSphere(origin geom.Vector, r float64) Sphere {
+ return Sphere{origin, r}
+}
+
+func (my Sphere) Intersect(ray geom.Ray) bool {
+ vecL := subVectors(ray.Origin, my.origin)
+ a := dot(ray.Direction, ray.Direction)
+ b := 2 * dot(ray.Direction, vecL)
+ c := dot(vecL, vecL) - (my.r * my.r)
+ return solveQuadratic(a, b, c)
+}
+
+func dot(first, second geom.Vector) float64 {
+ return first.X*second.X + first.Y*second.Y + first.Z*second.Z
+}
+
+func cross(first, second geom.Vector) geom.Vector {
+ return geom.NewVector(first.Y*second.Z-first.Z*second.Y,
+ first.Z*second.X-first.X*second.Z,
+ first.X*second.Y-first.Y*second.X)
+}
+
+func subVectors(first, second geom.Vector) geom.Vector {
+ return geom.NewVector(first.X-second.X,
+ first.Y-second.Y,
+ first.Z-second.Z)
+}
+
+func solveQuadratic(a, b, c float64) bool {
+ discriminant := b*b - 4*a*c
+ x1 := (math.Sqrt(discriminant) - b) / (2 * a)
+ x2 := (-b - math.Sqrt(discriminant)) / (2 * a)
+ if discriminant < 0 || (x1 < 0 && x2 < 0) {
+ return false
+ }
+ return true
+}
Помисли малко повече за това какво представлява един лъч. С какво се различава от права?