Кристиан обнови решението на 19.11.2018 20:40 (преди 9 месеца)
+package main
+
+import (
+ "math"
+
+ "github.com/fmi/go-homework/geom"
+)
+
+type Triangle struct {
+ A, B, C geom.Vector
+}
+
+type Quad struct {
+ A, B, C, D geom.Vector
+}
+
+type Sphere struct {
+ origin geom.Vector
+ R float64
+}
+
+func NewTriangle(a, b, c geom.Vector) Triangle {
+ return Triangle{
+ A: a,
+ B: b,
+ C: c,
+ }
+}
+
+func NewQuad(a, b, c, d geom.Vector) Quad {
+ return Quad{
+ A: a,
+ B: b,
+ C: c,
+ D: d,
+ }
+}
+
+func NewSphere(origin geom.Vector, r float64) Sphere {
+ return Sphere{
+ origin: origin,
+ R: r,
+ }
+}
+
+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.Vector{
+ 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 Abs(vektor geom.Vector) geom.Vector {
+ return geom.Vector{math.Abs(vektor.X), math.Abs(vektor.Y), math.Abs(vektor.Z)}
+}
+
+func Add(first, second geom.Vector) geom.Vector {
+ return geom.Vector{first.X + second.X, first.Y + second.Y, first.Z + second.Z}
+}
+
+func Sub(first, second geom.Vector) geom.Vector {
+ return geom.Vector{first.X - second.X, first.Y - second.Y, first.Z - second.Z}
+}
+
+func Mul(vektor geom.Vector, number float64) geom.Vector {
+ return geom.Vector{number * vektor.X, number * vektor.Y, number * vektor.Z}
+}
+
+func (triangle Triangle) Intersect(ray geom.Ray) bool {
+ epsiolon := 0.0000001
+
+ var edge1, edge2 geom.Vector
+ edge1 = Sub(triangle.B, triangle.A) // u
+ edge2 = Sub(triangle.C, triangle.A) // v
+ crossProduct := Cross(edge1, edge2) // n
+ if crossProduct.X == 0.0 && crossProduct.Y == 0.0 && crossProduct.Z == 0.0 {
+ return false
+ }
+
+ rayDirectrion := Sub(ray.Direction, ray.Origin)
+ diff := Sub(ray.Origin, triangle.A)
+ a := -Dot(crossProduct, diff)
+ b := Dot(crossProduct, rayDirectrion)
+
+ if math.Abs(b) < epsiolon {
+ if a == 0 {
+ return true
+ } else {
+ return false
+ }
+ }
+
+ if a/b < 0.0 {
+ return false
+ }
+
+ intersectPoint := Add(ray.Origin, Mul(rayDirectrion, a/b))
+ aa := Dot(edge1, edge1)
+ ab := Dot(edge1, edge2)
+ bb := Dot(edge2, edge2)
+ w := Sub(intersectPoint, triangle.A)
+ wa := Dot(w, edge1)
+ wb := Dot(w, edge2)
+ quadraticDiff := ab*ab - aa*bb
+ intersectedSide := (ab*wa - aa*wb) / quadraticDiff
+
+ if intersectedSide < 0.0 || intersectedSide > 1.0 {
+ return false
+ }
+
+ intersectedArea := (ab*wa - aa*wb) / quadraticDiff
+
+ if intersectedArea < 0.0 || (intersectedSide+intersectedArea) > 1.0 {
+ return false
+ }
+
+ return true
+}
+
+func (quad Quad) Intersect(ray geom.Ray) bool {
+ firstTriangle := NewTriangle(quad.A, quad.B, quad.C)
+ secondTriangle := NewTriangle(quad.C, quad.D, quad.A)
+ return firstTriangle.Intersect(ray) || secondTriangle.Intersect(ray)
+}
+
+func (sphere Sphere) Intersect(ray geom.Ray) bool {
+ L := Sub(sphere.origin, ray.Origin)
+ tca := Dot(L, ray.Direction)
+
+ if tca < 0 {
+ return false
+ }
+
+ d2 := Dot(L, L) - tca*tca
+ if d2 > sphere.R {
+ return false
+ }
+ thc := math.Sqrt(sphere.R - d2)
+ t0 := tca - thc
+ t1 := tca + thc
+ if t0 > t1 {
+ t0, t1 = t1, t0
+ }
+
+ if t0 < 0 {
+ t0 = t1
+ if t0 < 0 {
+ return false
+ }
+ }
+
+ return true
+}
+
+func main() {
+ //EMPTY BODY
+}