feat: starting implementing collisions.
This commit is contained in:
parent
7dcf0eeca8
commit
f910d4f99b
17 changed files with 349 additions and 195 deletions
|
@ -33,7 +33,7 @@ func NewTri() *Tri {
|
|||
|
||||
func (t *Tri) Update(c *Context) {
|
||||
dt := c.Dt().Seconds()
|
||||
if t.ContainsPoint(c.AbsCursorPosition()) {
|
||||
if !t.ContainedPoints(gg.Points{c.AbsCursorPosition()}).Empty() {
|
||||
t.Color = gg.Rgba(0, 1, 0, 1)
|
||||
} else {
|
||||
t.Color = gg.Rgba(1, 0, 1, 1)
|
||||
|
|
80
collider.go
80
collider.go
|
@ -6,19 +6,25 @@ package gg
|
|||
// if the the bigger collider that
|
||||
// contains more complicated (accurate) structure
|
||||
// do collide.
|
||||
type ColliderSimplifier interface {
|
||||
ColliderSimplify() Triangle
|
||||
}
|
||||
//type ColliderSimplifier interface {
|
||||
//ColliderSimplify() Triangle
|
||||
//}
|
||||
|
||||
// The structure represents all
|
||||
// information on collisions.
|
||||
type CollisionType int
|
||||
const (
|
||||
CollisionTypePhys CollisionType = iota
|
||||
CollisionTypeTrigger
|
||||
)
|
||||
|
||||
// The structure contains collision information.
|
||||
type Collision struct {
|
||||
Current, With any
|
||||
Type CollisionType
|
||||
What, With Objecter
|
||||
// Points of Self contained in
|
||||
Points Points
|
||||
Crosses []LineCross
|
||||
}
|
||||
|
||||
type PointContainer interface {
|
||||
ContainsPoint(Point) bool
|
||||
}
|
||||
|
||||
// Implementing the interface lets the engine
|
||||
// to determine if the object collides with anything.
|
||||
|
@ -26,8 +32,60 @@ type PointContainer interface {
|
|||
// inner structure field as first argument.
|
||||
// The Collide method will be called on collisions.
|
||||
type Collider interface {
|
||||
Collides(Collider) *Collision
|
||||
Collide(*Collision)
|
||||
// Checks whether the object is collidable
|
||||
IsCollidable() bool
|
||||
Verticer
|
||||
Edger
|
||||
PointContainer
|
||||
}
|
||||
type Collidability struct {
|
||||
Collidable bool
|
||||
}
|
||||
func (c Collidability) IsCollidable() bool {
|
||||
return c.Collidable
|
||||
}
|
||||
type PointContainer interface {
|
||||
ContainedPoints(Points) Points
|
||||
}
|
||||
type Verticer interface {
|
||||
Vertices() Vertices
|
||||
}
|
||||
type Edger interface {
|
||||
Edges() Edges
|
||||
}
|
||||
|
||||
// Implementing the type provides way
|
||||
// to resolve collisions and other problems.
|
||||
// The Resolve() is called right after the Update() of Updater.
|
||||
type Resolver interface {
|
||||
IsResolvable() bool
|
||||
Resolve(c *Context)
|
||||
Collider
|
||||
}
|
||||
type Resolvability struct {
|
||||
Resolvable bool
|
||||
}
|
||||
func (r Resolvability) IsResolvable() bool {
|
||||
return r.Resolvable
|
||||
}
|
||||
|
||||
func Collide(c1, c2 Collider) (Collision, bool) {
|
||||
vertices := c1.Vertices()
|
||||
es1, es2 := c1.Edges(), c2.Edges()
|
||||
crosses, doCross := es1.LineCrossWith(es2)
|
||||
pts := c2.ContainedPoints(vertices)
|
||||
return Collision{
|
||||
Points: pts,
|
||||
Crosses: crosses,
|
||||
}, len(pts) != 0 || doCross
|
||||
}
|
||||
|
||||
func GetCollisions(c Collider, cs []Collider) []Collision {
|
||||
ret := []Collision{}
|
||||
for _, ic := range cs {
|
||||
if !ic.IsCollidable() || ic == c {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ type contextType int
|
|||
const (
|
||||
startContext contextType = iota
|
||||
updateContext
|
||||
resolveContext
|
||||
eventContext
|
||||
drawContext
|
||||
deleteContext
|
||||
|
@ -12,6 +13,7 @@ const (
|
|||
type Context struct {
|
||||
typ contextType
|
||||
Events []any
|
||||
Collisions []Collision
|
||||
*Engine
|
||||
*Image
|
||||
}
|
||||
|
|
78
edge.go
Normal file
78
edge.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
package gg
|
||||
|
||||
type Edges []Edge
|
||||
// Get crosses of edges.
|
||||
func (what Edges) LineCrossWith(with Edges) ([]LineCross, bool) {
|
||||
ret := []LineCross{}
|
||||
for i := range what {
|
||||
for j := range with {
|
||||
cross, doCross := LinersCross(what[i], with[j])
|
||||
if doCross {
|
||||
ret = append(ret, cross)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(ret) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return ret, true
|
||||
}
|
||||
|
||||
// The type represents a line segment. The name is for short.
|
||||
type Edge [2]Vector
|
||||
|
||||
// Returns corresponding to the segment Line.
|
||||
func (l Edge) Line() Line {
|
||||
p0 := l[0]
|
||||
p1 := l[1]
|
||||
|
||||
k := (p0.Y - p1.Y) / (p0.X - p1.X)
|
||||
c := p0.Y - p0.X*k
|
||||
|
||||
return Line{k, c}
|
||||
}
|
||||
|
||||
func (l Edge) ContainedPoints(pts Points) (Points) {
|
||||
ret := Points{}
|
||||
for i := range pts {
|
||||
if l.ContainsPoint(pts[i]) {
|
||||
ret = append(ret, pts[i])
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Check if the edge contains the specified point.
|
||||
func (l Edge) ContainsPoint(p Point) bool {
|
||||
line := l.Line()
|
||||
if !line.ContainsPoint(p) {
|
||||
return false
|
||||
}
|
||||
|
||||
xMax := Max(l[0].X, l[1].X)
|
||||
xMin := Min(l[0].X, l[1].X)
|
||||
|
||||
yMax := Max(l[0].Y, l[1].Y)
|
||||
yMin := Min(l[0].Y, l[1].Y)
|
||||
|
||||
if !(xMin < p.X && p.X < xMax) ||
|
||||
!(yMin < p.Y && p.Y < yMax) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Get square of length of line segment (for performance sometimes).
|
||||
func (ls Edge) LenSqr() Float {
|
||||
return Sqr(ls[0].X - ls[1].X) +
|
||||
Sqr(ls[0].Y - ls[1].Y)
|
||||
}
|
||||
|
||||
// Get length of the line segment.
|
||||
func (ls Edge) Len() Float {
|
||||
return Sqrt(ls.LenSqr())
|
||||
}
|
||||
|
50
engine.go
50
engine.go
|
@ -232,14 +232,9 @@ func (e *Engine) Runes() []rune {
|
|||
return e.runes
|
||||
}
|
||||
|
||||
func (e *engine) Update() error {
|
||||
func (e *engine) UpdateEvents() []any {
|
||||
|
||||
eng := (*Engine)(e)
|
||||
e.dt = time.Since(e.lastTime)
|
||||
|
||||
e.runes = ebiten.AppendInputChars(e.runes[:0])
|
||||
fmt.Println("runes:", e.runes)
|
||||
// Buffering the context for faster.
|
||||
|
||||
e.prevKeys = e.keys
|
||||
e.keys = inpututil.
|
||||
AppendPressedKeys(e.keys[:0])
|
||||
|
@ -261,10 +256,10 @@ func (e *engine) Update() error {
|
|||
}
|
||||
|
||||
x, y := ebiten.Wheel()
|
||||
eng.wheel = V(x, y)
|
||||
if !(eng.wheel.Eq(ZV)) {
|
||||
e.wheel = V(x, y)
|
||||
if !(e.wheel.Eq(ZV)) {
|
||||
events = append(events, &WheelChange{
|
||||
Offset: eng.wheel,
|
||||
Offset: e.wheel,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -284,22 +279,34 @@ func (e *engine) Update() error {
|
|||
}
|
||||
|
||||
realPos := eng.cursorPosition()
|
||||
if !realPos.Eq(eng.cursorPos) {
|
||||
if !realPos.Eq(e.cursorPos) {
|
||||
absM := eng.Camera.AbsMatrix()
|
||||
|
||||
absPrevPos :=eng.cursorPos.Apply(absM)
|
||||
absPrevPos := e.cursorPos.Apply(absM)
|
||||
absPos := realPos.Apply(absM)
|
||||
|
||||
events = append(events, &MouseMove{
|
||||
Real: realPos.Sub(eng.cursorPos),
|
||||
Real: realPos.Sub(e.cursorPos),
|
||||
Abs: absPos.Sub(absPrevPos),
|
||||
})
|
||||
eng.cursorPos = realPos
|
||||
e.cursorPos = realPos
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
func (e *engine) Update() error {
|
||||
|
||||
eng := (*Engine)(e)
|
||||
e.dt = time.Since(e.lastTime)
|
||||
|
||||
e.runes = ebiten.AppendInputChars(e.runes[:0])
|
||||
fmt.Println("runes:", e.runes)
|
||||
// Buffering the context for faster.
|
||||
// Providing the events to the objects.
|
||||
// Maybe should think of the better way,
|
||||
// but for it is simple enough.
|
||||
|
||||
events := e.UpdateEvents()
|
||||
c := &Context{
|
||||
Engine: eng,
|
||||
typ: updateContext,
|
||||
|
@ -310,11 +317,26 @@ func (e *engine) Update() error {
|
|||
object.Input() <- c
|
||||
}
|
||||
e.wg.Wait()
|
||||
e.Resolve()
|
||||
|
||||
e.lastTime = time.Now()
|
||||
e.frame++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *engine) Resolve() {
|
||||
colliders := []Collider{}
|
||||
resolvers := []Resolver{}
|
||||
for _, object := range e.Objects.store {
|
||||
if object.IsCollidable() {
|
||||
colliders = append(colliders, object)
|
||||
}
|
||||
if object.IsResolvable() {
|
||||
resolvers = append(resolvers, object)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
fullPageIndexes = func() [MaxVertices]uint16 {
|
||||
ret := [MaxVertices]uint16{}
|
||||
|
|
120
line.go
120
line.go
|
@ -1,88 +1,15 @@
|
|||
package gg
|
||||
|
||||
import (
|
||||
"math"
|
||||
//"fmt"
|
||||
)
|
||||
|
||||
// The type represents mathematical equation of line and line itself.
|
||||
type Line struct {
|
||||
K, C Float
|
||||
}
|
||||
|
||||
type Liner interface {
|
||||
Line() Line
|
||||
}
|
||||
|
||||
type LinerPointContainer interface {
|
||||
Liner
|
||||
PointContainer
|
||||
}
|
||||
|
||||
// The type represents a line segment.
|
||||
type LineSegment [2]Point
|
||||
|
||||
// The type represents multiple line segments.
|
||||
type LineSegments []LineSegment
|
||||
|
||||
type Edge = LineSegment
|
||||
type Edges = LineSegments
|
||||
|
||||
|
||||
|
||||
// Check if two LinerPointContainers do cross and return the
|
||||
// crossing point.
|
||||
func LinersCross(lp1, lp2 LinerPointContainer) (Point, bool) {
|
||||
l1 := lp1.Line()
|
||||
l2 := lp2.Line()
|
||||
|
||||
p, crosses := l1.crossesLine(l2)
|
||||
if !crosses ||
|
||||
!lp1.ContainsPoint(p) ||
|
||||
!lp2.ContainsPoint(p) {
|
||||
return Point{}, false
|
||||
}
|
||||
|
||||
return p, true
|
||||
}
|
||||
|
||||
// Check whether the liner is parallel to the other liner.
|
||||
func LinersParallel(first, second Liner) bool {
|
||||
l1 := first.Line()
|
||||
l2 := second.Line()
|
||||
|
||||
return l1.K == l2.K
|
||||
}
|
||||
|
||||
// Returns angle between liners in radians.
|
||||
// The value fits the -Pi < Value < Pi condition.
|
||||
func LinersAngle(first, second Liner) Float {
|
||||
l1 := first.Line()
|
||||
l2 := second.Line()
|
||||
|
||||
if l1.K == l2.K {
|
||||
return 0
|
||||
}
|
||||
|
||||
return math.Atan(l1.K/l2.K)
|
||||
}
|
||||
|
||||
// Returns the line itself. Made to implement the Liner interface.
|
||||
func (l Line) Line() Line {
|
||||
return l
|
||||
}
|
||||
|
||||
// Returns corresponding to the segment line line.
|
||||
func (l LineSegment) Line() Line {
|
||||
p0 := l[0]
|
||||
p1 := l[1]
|
||||
|
||||
k := (p0.Y - p1.Y) / (p0.X - p1.X)
|
||||
c := p0.Y - p0.X*k
|
||||
|
||||
return Line{k, c}
|
||||
}
|
||||
|
||||
func (l Line) ContainsPoint(p Point) bool {
|
||||
buf := Line{0, p.Y}
|
||||
pc, ok := l.crossesLine(buf)
|
||||
|
@ -93,26 +20,6 @@ func (l Line) ContainsPoint(p Point) bool {
|
|||
return pc == p
|
||||
}
|
||||
|
||||
func (l LineSegment) ContainsPoint(p Point) bool {
|
||||
line := l.Line()
|
||||
if !line.ContainsPoint(p) {
|
||||
return false
|
||||
}
|
||||
|
||||
xMax := Max(l[0].X, l[1].X)
|
||||
xMin := Min(l[0].X, l[1].X)
|
||||
|
||||
yMax := Max(l[0].Y, l[1].Y)
|
||||
yMin := Min(l[0].Y, l[1].Y)
|
||||
|
||||
if !(xMin < p.X && p.X < xMax) ||
|
||||
!(yMin < p.Y && p.Y < yMax) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (l1 Line) crossesLine(l2 Line) (Point, bool) {
|
||||
if LinersParallel(l1, l2) {
|
||||
return Point{}, false
|
||||
|
@ -124,30 +31,3 @@ func (l1 Line) crossesLine(l2 Line) (Point, bool) {
|
|||
}
|
||||
|
||||
|
||||
// Get square of length of line segment.
|
||||
func (ls LineSegment) LenSqr() Float {
|
||||
return Sqr(ls[0].X - ls[1].X) +
|
||||
Sqr(ls[0].Y - ls[1].Y)
|
||||
}
|
||||
|
||||
// Get length of the line segment.
|
||||
func (ls LineSegment) Len() Float {
|
||||
return math.Sqrt(ls.LenSqr())
|
||||
}
|
||||
|
||||
func (what LineSegments) Cross(with LineSegments) ([][2]int, Points) {
|
||||
indexes := [][2]int{}
|
||||
points := Points{}
|
||||
for i := range what {
|
||||
for j := range with {
|
||||
p, cross := LinersCross(what[i], with[j])
|
||||
if cross {
|
||||
points = append(points, p)
|
||||
indexes = append(indexes, [2]int{i, j})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return indexes, points
|
||||
}
|
||||
|
||||
|
|
56
liner.go
Normal file
56
liner.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package gg
|
||||
|
||||
type Liner interface {
|
||||
Line() Line
|
||||
}
|
||||
|
||||
type LinerPointContainer interface {
|
||||
Liner
|
||||
PointContainer
|
||||
}
|
||||
|
||||
// The type represents the cross of 2 Liners.
|
||||
type LineCross struct {
|
||||
Pair [2]Line
|
||||
Point Point
|
||||
}
|
||||
|
||||
// Check if two LinerPointContainers do cross and return the
|
||||
// crossing point.
|
||||
func LinersCross(lp1, lp2 LinerPointContainer) (LineCross, bool) {
|
||||
l1 := lp1.Line()
|
||||
l2 := lp2.Line()
|
||||
|
||||
crossPt, doCross := l1.crossesLine(l2)
|
||||
if !doCross ||
|
||||
len(lp1.ContainedPoints([]Point{crossPt}))==0 ||
|
||||
len(lp2.ContainedPoints([]Point{crossPt}))==0 {
|
||||
return LineCross{}, false
|
||||
}
|
||||
|
||||
return LineCross{
|
||||
Pair: [2]Line{l1, l2},
|
||||
Point: crossPt,
|
||||
}, true
|
||||
}
|
||||
|
||||
// Check whether the liner is parallel to the other liner.
|
||||
func LinersParallel(first, second Liner) bool {
|
||||
l1 := first.Line()
|
||||
l2 := second.Line()
|
||||
|
||||
return l1.K == l2.K
|
||||
}
|
||||
|
||||
// Returns angle between liners in radians.
|
||||
// The value fits the -Pi < Value < Pi condition.
|
||||
func LinersAngle(first, second Liner) Float {
|
||||
l1 := first.Line()
|
||||
l2 := second.Line()
|
||||
|
||||
if l1.K == l2.K {
|
||||
return 0
|
||||
}
|
||||
|
||||
return Atan(l1.K/l2.K)
|
||||
}
|
4
math.go
4
math.go
|
@ -24,6 +24,10 @@ func Sqr(v Float) Float {
|
|||
return v * v
|
||||
}
|
||||
|
||||
func Sqrt(v Float) Float {
|
||||
return math.Sqrt(v)
|
||||
}
|
||||
|
||||
func Asin(v Float) Float {
|
||||
return math.Asin(v)
|
||||
}
|
||||
|
|
13
object.go
13
object.go
|
@ -54,14 +54,19 @@ type Objecter interface {
|
|||
Input() chan *Context
|
||||
Starter
|
||||
Updater
|
||||
Collider
|
||||
Resolver
|
||||
Drawer
|
||||
Deleter
|
||||
}
|
||||
|
||||
// The type for embedding into engine-in types.
|
||||
type Object struct {
|
||||
Collidability
|
||||
Resolvability
|
||||
Layer
|
||||
Visibility
|
||||
|
||||
input chan *Context
|
||||
}
|
||||
|
||||
|
@ -69,7 +74,15 @@ func (o *Object) GetObject() *Object { return o }
|
|||
func (o *Object) Input() chan *Context { return o.input }
|
||||
|
||||
func (o *Object) Start(c *Context) {}
|
||||
|
||||
func (o *Object) Update(c *Context) {}
|
||||
|
||||
func (o *Object) ContainedPoints(Points) Points {return Points{}}
|
||||
func (o *Object) Vertices() Vertices {return Vertices{}}
|
||||
func (o *Object) Edges() Edges {return Edges{}}
|
||||
|
||||
func (o *Object) Resolve(c *Context) {}
|
||||
|
||||
func (o *Object) Draw(c *Context) []EVertex { return nil}
|
||||
func (o *Object) Delete(c *Context) {}
|
||||
|
||||
|
|
8
point.go
Normal file
8
point.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package gg
|
||||
|
||||
type Point = Vector
|
||||
type Points []Point
|
||||
|
||||
func (pts Points) Empty() bool {
|
||||
return len(pts) == 0
|
||||
}
|
21
polygon.go
21
polygon.go
|
@ -10,17 +10,8 @@ type Polygon struct {
|
|||
Triangles
|
||||
}
|
||||
|
||||
func (p Polygon) ContainsPoint(pnt Point) bool {
|
||||
return p.MakeTriangles().ContainsPoint(pnt)
|
||||
}
|
||||
|
||||
// Polygon that can be drawn.
|
||||
type DrawablePolygon struct {
|
||||
Polygon
|
||||
|
||||
ShaderOptions
|
||||
Visibility
|
||||
Colority
|
||||
func (p Polygon) ContainedPoints(pts Points) (Points) {
|
||||
return p.MakeTriangles().ContainedPoints(pts)
|
||||
}
|
||||
|
||||
func (p Polygon) MakeTriangles() Triangles {
|
||||
|
@ -37,6 +28,14 @@ func (p Polygon) MakeTriangles() Triangles {
|
|||
return ret
|
||||
}
|
||||
|
||||
// Polygon that can be drawn.
|
||||
type DrawablePolygon struct {
|
||||
Polygon
|
||||
ShaderOptions
|
||||
Visibility
|
||||
Colority
|
||||
}
|
||||
|
||||
func (p *DrawablePolygon) Draw(c *Context) []EVertex {
|
||||
return (&DrawableTriangles{
|
||||
Colority: p.Colority,
|
||||
|
|
49
rect.go
49
rect.go
|
@ -7,28 +7,16 @@ import (
|
|||
//"image"
|
||||
)
|
||||
|
||||
// The type describes rectangle geometry.
|
||||
// The type describes rectangle geometry with
|
||||
// way to move, rotate and scale it.
|
||||
type Rectangle struct {
|
||||
Object
|
||||
Transform
|
||||
}
|
||||
|
||||
// The type describes rectangle that can be drawn.
|
||||
type DrawableRectangle struct {
|
||||
Rectangle
|
||||
ShaderOptions
|
||||
|
||||
// Solid color of the rectangle.
|
||||
// Will be ignored if the Shader
|
||||
// field is not nil.
|
||||
Colority
|
||||
|
||||
// Should be draw or not.
|
||||
Visibility
|
||||
Width, Height Float
|
||||
}
|
||||
|
||||
// Return points of vertices of the rectangle.
|
||||
func (r Rectangle) Vertices() Points {
|
||||
func (r Rectangle) Vertices() Vertices {
|
||||
m := r.Matrix()
|
||||
p1 := V(0, 0).Apply(m)
|
||||
p2 := V(1, 0).Apply(m)
|
||||
|
@ -39,11 +27,11 @@ func (r Rectangle) Vertices() Points {
|
|||
|
||||
func (r Rectangle) Edges() Edges {
|
||||
vs := r.Vertices()
|
||||
return LineSegments{
|
||||
LineSegment{vs[0], vs[1]},
|
||||
LineSegment{vs[1], vs[2]},
|
||||
LineSegment{vs[2], vs[3]},
|
||||
LineSegment{vs[3], vs[0]},
|
||||
return Edges{
|
||||
Edge{vs[0], vs[1]},
|
||||
Edge{vs[1], vs[2]},
|
||||
Edge{vs[2], vs[3]},
|
||||
Edge{vs[3], vs[0]},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,8 +50,23 @@ func (r Rectangle) MakeTriangles() Triangles {
|
|||
}
|
||||
|
||||
// Check whether the rectangle contains the point.
|
||||
func (r Rectangle) ContainsPoint(p Point) bool {
|
||||
return r.MakeTriangles().ContainsPoint(p)
|
||||
func (r Rectangle) ContainedPoints(pts Points) (Points) {
|
||||
return r.MakeTriangles().ContainedPoints(pts)
|
||||
}
|
||||
|
||||
// The type describes rectangle that can be drawn.
|
||||
type DrawableRectangle struct {
|
||||
Rectangle
|
||||
ShaderOptions
|
||||
|
||||
// Solid color of the rectangle.
|
||||
// Will be ignored if the Shader
|
||||
// field is not nil.
|
||||
Colority
|
||||
|
||||
// Should be draw or not.
|
||||
Visibility
|
||||
Collidability
|
||||
}
|
||||
|
||||
// Check whether the drawable rectangle should be drawn.
|
||||
|
|
12
size.go
Normal file
12
size.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package gg
|
||||
|
||||
// The type describes a simple
|
||||
// rectangle without transformations.
|
||||
type Size struct {
|
||||
// The upper left corner position point.
|
||||
Position Point
|
||||
// Absolute width and height.
|
||||
Width, Height Float
|
||||
}
|
||||
|
||||
//type (s Size) ContainsPoint
|
|
@ -11,6 +11,8 @@ type Sprite struct {
|
|||
ShaderOptions
|
||||
Floating bool
|
||||
Visibility
|
||||
Collidability
|
||||
Resolvability
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
34
triangle.go
34
triangle.go
|
@ -15,7 +15,6 @@ type Vertex struct {
|
|||
}
|
||||
|
||||
type Triangle [3]Vector
|
||||
type Triangles []Triangle
|
||||
type DrawableTriangles struct {
|
||||
Triangles
|
||||
Colority
|
||||
|
@ -53,9 +52,9 @@ func sqr(v Float) Float {
|
|||
// Return squares of lengths of sides of the triangle.
|
||||
func (t Triangle) SideLengthSquares() ([3]Float) {
|
||||
|
||||
l1 := LineSegment{t[0], t[1]}.LenSqr()
|
||||
l2 := LineSegment{t[1], t[2]}.LenSqr()
|
||||
l3 := LineSegment{t[2], t[0]}.LenSqr()
|
||||
l1 := Edge{t[0], t[1]}.LenSqr()
|
||||
l2 := Edge{t[1], t[2]}.LenSqr()
|
||||
l3 := Edge{t[2], t[0]}.LenSqr()
|
||||
|
||||
return [3]Float{l1, l2, l3}
|
||||
}
|
||||
|
@ -72,19 +71,36 @@ func (t Triangle) ContainsPoint(p Point) bool {
|
|||
return !(neg && pos)
|
||||
}
|
||||
|
||||
func (t Triangle) ContainedPoints(pts Points) []Point {
|
||||
ret := []Point{}
|
||||
for i := range pts {
|
||||
if t.ContainsPoint(pts[i]) {
|
||||
ret = append(ret, pts[i])
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t Triangle) Sgn() Float {
|
||||
return (t[0].X - t[2].X) * (t[1].Y - t[2].Y) -
|
||||
(t[1].X - t[2].X) * (t[0].Y - t[2].Y)
|
||||
}
|
||||
|
||||
func (ts Triangles) ContainsPoint(p Point) bool {
|
||||
func (t Triangle) Vertices() Vertices {
|
||||
return Vertices{
|
||||
t[0], t[1], t[2],
|
||||
}
|
||||
}
|
||||
type Triangles []Triangle
|
||||
|
||||
func (ts Triangles) ContainedPoints(pts Points) (Points) {
|
||||
ret := []Point{}
|
||||
for _, t := range ts {
|
||||
if t.ContainsPoint(p) {
|
||||
return true
|
||||
}
|
||||
ps := t.ContainedPoints(pts)
|
||||
ret = append(ret, ps...)
|
||||
}
|
||||
|
||||
return false
|
||||
return ret
|
||||
}
|
||||
|
||||
func (r *DrawableTriangles) MakeEVertices(c *Context) []EVertex {
|
||||
|
|
|
@ -15,11 +15,7 @@ type Vector struct {
|
|||
func (v Vector) XY() (Float, Float) {
|
||||
return v.X, v.Y
|
||||
}
|
||||
type Point = Vector
|
||||
//type Vertex = Vector
|
||||
|
||||
type Vectors []Vector
|
||||
type Points []Point
|
||||
|
||||
func V(x, y Float) Vector {
|
||||
return Vector{x, y}
|
||||
|
@ -94,11 +90,11 @@ func (v Vector) Norm() Vector {
|
|||
return V(v.X / l, v.Y / l)
|
||||
}
|
||||
|
||||
func (pts Points) Contained(c PointContainer) Points {
|
||||
func (pts Points) ContainedIn(c PointContainer) Points {
|
||||
ret := make([]Point, 0, len(pts))
|
||||
|
||||
for _, pt := range pts {
|
||||
if c.ContainsPoint(pt) {
|
||||
if !c.ContainedPoints(Points{pt}).Empty() {
|
||||
ret = append(ret, pt)
|
||||
}
|
||||
}
|
||||
|
|
5
vertice.go
Normal file
5
vertice.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package gg
|
||||
|
||||
type Vertice = Point
|
||||
type Vertices = []Vertice
|
||||
|
Loading…
Reference in a new issue