-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
04c8eab
commit 84ef317
Showing
2 changed files
with
127 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/fmi/go-homework/geom" | ||
) | ||
|
||
const Episilon = 1e-7 | ||
|
||
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 (triangle Triangle) Intersect(ray geom.Ray) bool { | ||
// Find vectors for two edges sharing vertex 0 | ||
edge1 := geom.Sub(triangle.b, triangle.a) | ||
edge2 := geom.Sub(triangle.c, triangle.a) | ||
|
||
// Begin calculating determinant | ||
h := geom.Cross(ray.Direction, edge2) | ||
|
||
det := geom.Dot(edge1, h) | ||
if det > -Episilon && det < Episilon { | ||
return false // The ray is parallel to triangle plane, impossible that they intersect | ||
} | ||
|
||
f := 1 / det | ||
|
||
// Calculate vector from vertex to the ray origin | ||
s := geom.Sub(ray.Origin, triangle.a) | ||
|
||
// Calculating U parameter | ||
u := f * geom.Dot(s, h) | ||
if u < 0 || u > 1 { | ||
return false | ||
} | ||
|
||
// Prepare to test V parameter | ||
q := geom.Cross(s, edge1) | ||
|
||
v := f * geom.Dot(ray.Direction, q) | ||
if v < 0 || u+v > 1 { | ||
return false | ||
} | ||
|
||
// Calculating t - final check to see if ray intersects triangle | ||
t := f * geom.Dot(edge2, q) | ||
if t > Episilon { | ||
return true | ||
} | ||
|
||
return false | ||
} | ||
|
||
func (quad Quad) Intersect(ray geom.Ray) bool { | ||
return true | ||
} | ||
|
||
func (sphere Sphere) Intersect(ray geom.Ray) bool { | ||
return true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package main | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/fmi/go-homework/geom" | ||
) | ||
|
||
func TestSampleSimpleOperations(t *testing.T) { | ||
var prim geom.Intersectable | ||
|
||
a, b, c := geom.NewVector(-1, -1, 0), geom.NewVector(1, -1, 0), geom.NewVector(0, 1, 0) | ||
prim = NewTriangle(a, b, c) | ||
ray := geom.NewRay(geom.NewVector(0, 0, -1), geom.NewVector(0, 0, 1)) | ||
|
||
if !prim.Intersect(ray) { | ||
t.Errorf("Expected ray %#v to intersect triangle %#v but it did not.", ray, prim) | ||
} | ||
} | ||
|
||
func TestSampleIntersectableImplementations(t *testing.T) { | ||
var prim geom.Intersectable | ||
|
||
a, b, c, d := geom.NewVector(-1, -1, 0), | ||
geom.NewVector(1, -1, 0), | ||
geom.NewVector(0, 1, 0), | ||
geom.NewVector(-1, 1, 0) | ||
|
||
prim = NewTriangle(a, b, c) | ||
prim = NewQuad(a, b, c, d) | ||
prim = NewSphere(a, 5) | ||
|
||
_ = prim | ||
} |