feat: trying to fix the vertical lines collisions.

This commit is contained in:
Andrey Parhomenko 2024-01-22 10:23:47 +03:00
parent ca0e87b4d1
commit 88c1aa9577
16 changed files with 199 additions and 33 deletions

39
cmd/math/main.go Normal file
View file

@ -0,0 +1,39 @@
package main
import (
"vultras.su/core/gg"
"fmt"
"encoding/json"
)
type Float = gg.Float
func EdgesFromVals(vals ...Float) gg.Edges {
ret := gg.Edges{}
for i:=0 ; i<len(vals) ; i += 4 {
ret = append(
ret,
gg.Edge{
gg.Point{
vals[i], vals[i+1],
},
gg.Point{
vals[i+2], vals[i+3],
},
},
)
}
return ret
}
func main() {
e1 := EdgesFromVals(
0, 0, 5, 5,
)
e2 := EdgesFromVals(
0, 1, 5, 0,
0, 0, 5, 5,
)
val, ok := e1.CrossWithEdges(e2)
bts, _ := json.MarshalIndent(val, "", "\t")
fmt.Println(string(bts), ok)
}

View file

@ -9,6 +9,17 @@ import (
type Debug struct { type Debug struct {
gg.Object gg.Object
gg.Visibility
}
func (d *Debug) Update(c *Context) {
for _, e := range c.Events { switch ec := e.(type) {
case *gg.KeyDown :
switch ec.Key {
case gg.KeyF11 :
d.Visible = !d.Visible
}
}}
} }
func (d *Debug) Draw(c *Context) []gg.EVertex { func (d *Debug) Draw(c *Context) []gg.EVertex {
@ -87,4 +98,3 @@ func (d *Debug) Draw(c *Context) []gg.EVertex {
return nil return nil
} }
func (d *Debug) IsVisible() bool { return true }

View file

@ -50,6 +50,13 @@ func (p *Player) Draw(c *Context) []gg.EVertex {
} }
func (p *Player) Update(c *Context) { func (p *Player) Update(c *Context) {
/*r := gg.Rectangle{
Transform: gg.T(),
}
r.Width = 150
r.Height = 150
col, _ := gg.Collide(p, r)
fmt.Println(col.Crosses)*/
//p.SetPosition(p.Position().Sub(gg.Y(2))) //p.SetPosition(p.Position().Sub(gg.Y(2)))
p.Move(gg.Y(1)) p.Move(gg.Y(1))
if p.Spawned { if p.Spawned {
@ -71,7 +78,7 @@ func (p *Player) Update(c *Context) {
), ),
) )
case gg.KeyW: case gg.KeyW:
p.Move(gg.Y(-p.MoveSpeed * dt *10)) p.Move(gg.Y(-p.MoveSpeed * dt ))
walking = true walking = true
p.Animate(Walk) p.Animate(Walk)
case gg.KeyA: case gg.KeyA:
@ -80,7 +87,7 @@ func (p *Player) Update(c *Context) {
walking = true walking = true
p.Animate(Walk) p.Animate(Walk)
case gg.KeyS: case gg.KeyS:
p.Move(gg.X(-p.MoveSpeed * dt)) p.Move(gg.Y(p.MoveSpeed * dt))
//p.Position.Y -= p.MoveSpeed * dt //p.Position.Y -= p.MoveSpeed * dt
walking = true walking = true
p.Animate(Walk) p.Animate(Walk)
@ -160,8 +167,11 @@ func (p *Player) GetCollisionInterest() []gg.CollisionType {
func (p *Player) Resolve(c *Context) { func (p *Player) Resolve(c *Context) {
col := c.Collisions[0] col := c.Collisions[0]
if !p.Spawned { if !p.Spawned && false {
fmt.Printf("frame[%d]: the col[0] len(%d): %T, %T\n", c.Frame(), len(c.Collisions), col.What, col.With) fmt.Printf(
"frame[%d]: the col[0] len(%d): %T, %T, %d %d\n",
c.Frame(), len(c.Collisions), col.What, col.With, len(col.Crosses), len(col.Points),
)
} }
for _, col := range c.Collisions {switch col.Type{ for _, col := range c.Collisions {switch col.Type{
case gg.CollisionStaticPhysics : case gg.CollisionStaticPhysics :

View file

@ -8,7 +8,7 @@ type Rect struct {
func NewRect() *Rect { func NewRect() *Rect {
ret := &Rect{} ret := &Rect{}
ret.SetScale(gg.V(200, 400)) ret.SetScale(gg.V(5, 5))
ret.Color = gg.Color{ ret.Color = gg.Color{
gg.MaxColorV, gg.MaxColorV,
0, 0,

View file

@ -1,7 +1,7 @@
package main package main
import "vultras.su/core/gg" import "vultras.su/core/gg"
//import "fmt" import "fmt"
var ( var (
counter int counter int
@ -15,6 +15,7 @@ type Tri struct {
func NewTri() *Tri { func NewTri() *Tri {
ret := &Tri{} ret := &Tri{}
ret.Transform = gg.T() ret.Transform = gg.T()
ret.SetPosition(gg.V(-100, -100))
ret.Triangles = gg.Triangles{ ret.Triangles = gg.Triangles{
gg.Triangle{ gg.Triangle{
gg.V(0, 10), gg.V(0, 10),
@ -24,13 +25,27 @@ func NewTri() *Tri {
} }
ret.Color = gg.Rgba(1, 1, 0, 1) ret.Color = gg.Rgba(1, 1, 0, 1)
ret.Visible = true ret.Visible = true
ret.Collidable = true
ret.Type = gg.CollisionStaticPhysics
ret.Layer = TriangleL ret.Layer = TriangleL
ret.Connect(player) //ret.Connect(player)
return ret return ret
} }
func (t *Tri) Update(c *Context) { func (t *Tri) Update(c *Context) {
//redges := rect.Edges()
//tedges := t.Edges()
//crosses, ok := tedges.CrossWithEdges(redges)
//fmt.Println("shit:", crosses, ok)
if false {
//fmt.Println("edges:", tedges)
}
col, hasCol := gg.Collide(t, rect)
if hasCol{
fmt.Println("col:", col)
}
dt := c.Dt().Seconds() dt := c.Dt().Seconds()
if !t.ContainedPoints(gg.Points{c.AbsCursorPosition()}).Empty() { if !t.ContainedPoints(gg.Points{c.AbsCursorPosition()}).Empty() {
t.Color = gg.Rgba(0, 1, 0, 1) t.Color = gg.Rgba(0, 1, 0, 1)

View file

@ -83,7 +83,7 @@ func (r Resolvability) GetCollisionInterest() []CollisionType {
func Collide(c1, c2 Collider) (Collision, bool) { func Collide(c1, c2 Collider) (Collision, bool) {
vertices := c1.Vertices() vertices := c1.Vertices()
es1, es2 := c1.Edges(), c2.Edges() es1, es2 := c1.Edges(), c2.Edges()
crosses, doCross := es1.LineCrossWith(es2) crosses, doCross := es1.CrossWithEdges(es2)
pts := c2.ContainedPoints(vertices) pts := c2.ContainedPoints(vertices)
return Collision{ return Collision{
Type: c2.CollisionType(), Type: c2.CollisionType(),
@ -91,7 +91,7 @@ func Collide(c1, c2 Collider) (Collision, bool) {
With: c2, With: c2,
Points: pts, Points: pts,
Crosses: crosses, Crosses: crosses,
}, len(pts) != 0 || doCross }, len(pts) > 0 || doCross
} }
func GetCollisions(c Collider, cs []Collider) []Collision { func GetCollisions(c Collider, cs []Collider) []Collision {

29
edge.go
View file

@ -2,7 +2,7 @@ package gg
type Edges []Edge type Edges []Edge
// Get crosses of edges. // Get crosses of edges.
func (what Edges) LineCrossWith(with Edges) ([]LineCross, bool) { func (what Edges) CrossWithEdges(with Edges) ([]LineCross, bool) {
ret := []LineCross{} ret := []LineCross{}
for i := range what { for i := range what {
for j := range with { for j := range with {
@ -13,11 +13,7 @@ func (what Edges) LineCrossWith(with Edges) ([]LineCross, bool) {
} }
} }
if len(ret) == 0 { return ret, len(ret) > 0
return nil, false
}
return ret, true
} }
// The type represents a line segment. The name is for short. // The type represents a line segment. The name is for short.
@ -25,13 +21,22 @@ type Edge [2]Vector
// Returns corresponding to the segment Line. // Returns corresponding to the segment Line.
func (l Edge) Line() Line { func (l Edge) Line() Line {
var (
x Float
vertical bool
)
p0 := l[0] p0 := l[0]
p1 := l[1] p1 := l[1]
k := (p0.Y - p1.Y) / (p0.X - p1.X) k := (p0.Y - p1.Y) / (p0.X - p1.X)
c := p0.Y - p0.X*k c := p0.Y - p0.X*k
if p0.X == p1.X {
return Line{k, c} vertical = true
x = p0.X
}
return Line{k, c, x, vertical}
} }
func (l Edge) ContainedPoints(pts Points) (Points) { func (l Edge) ContainedPoints(pts Points) (Points) {
@ -51,11 +56,11 @@ func (l Edge) ContainsPoint(p Point) bool {
return false return false
} }
xMax := Max(l[0].X, l[1].X) xMax := Max(l[0].X, l[1].X)
xMin := Min(l[0].X, l[1].X) xMin := Min(l[0].X, l[1].X)
yMax := Max(l[0].Y, l[1].Y) yMax := Max(l[0].Y, l[1].Y)
yMin := Min(l[0].Y, l[1].Y) yMin := Min(l[0].Y, l[1].Y)
if !(xMin < p.X && p.X < xMax) || if !(xMin < p.X && p.X < xMax) ||
!(yMin < p.Y && p.Y < yMax) { !(yMin < p.Y && p.Y < yMax) {

13
fmt.go Normal file
View file

@ -0,0 +1,13 @@
package gg
import (
"fmt"
)
func Println(v ...any) {
fmt.Println(v...)
}
func Printf(format string, v ...any) {
fmt.Printf(format, v...)
}

25
line.go
View file

@ -1,8 +1,11 @@
package gg package gg
//import "fmt"
// The type represents mathematical equation of line and line itself. // The type represents mathematical equation of line and line itself.
type Line struct { type Line struct {
K, C Float K, C, X Float
Vertical bool
} }
// Returns the line itself. Made to implement the Liner interface. // Returns the line itself. Made to implement the Liner interface.
@ -11,22 +14,32 @@ func (l Line) Line() Line {
} }
func (l Line) ContainsPoint(p Point) bool { func (l Line) ContainsPoint(p Point) bool {
buf := Line{0, p.Y} buf := Line{0, p.Y, 0, false}
pc, ok := l.crossesLine(buf) pc, ok := l.crossesLine(buf)
if !ok { if !ok {
return false return false
} }
return pc == p return Neq(pc.X, p.X) && Neq(pc.Y, p.Y)
} }
func (l1 Line) crossesLine(l2 Line) (Point, bool) { func (l1 Line) crossesLine(l2 Line) (Point, bool) {
var x, y Float
if LinersParallel(l1, l2) { if LinersParallel(l1, l2) {
return Point{}, false return Point{}, false
} }
x := (l1.C - l2.C) / (l2.K - l1.K) if l1.Vertical {
y := l1.K*x + l1.C x = l1.X
y = l2.K*x + l2.C
} else if l2.Vertical {
x = l2.X
y = l1.K*x + l1.C
} else {
x = (l1.C - l2.C) / (l2.K - l1.K)
y = l1.K*x + l1.C
}
return Point{x, y}, true return Point{x, y}, true
} }

View file

@ -22,16 +22,15 @@ func LinersCross(lp1, lp2 LinerPointContainer) (LineCross, bool) {
l2 := lp2.Line() l2 := lp2.Line()
crossPt, doCross := l1.crossesLine(l2) crossPt, doCross := l1.crossesLine(l2)
if !doCross || if len(lp1.ContainedPoints([]Point{crossPt}))==0 ||
len(lp1.ContainedPoints([]Point{crossPt}))==0 ||
len(lp2.ContainedPoints([]Point{crossPt}))==0 { len(lp2.ContainedPoints([]Point{crossPt}))==0 {
return LineCross{}, false doCross = false
} }
return LineCross{ return LineCross{
Pair: [2]Line{l1, l2}, Pair: [2]Line{l1, l2},
Point: crossPt, Point: crossPt,
}, true }, doCross
} }
// Check whether the liner is parallel to the other liner. // Check whether the liner is parallel to the other liner.
@ -39,7 +38,7 @@ func LinersParallel(first, second Liner) bool {
l1 := first.Line() l1 := first.Line()
l2 := second.Line() l2 := second.Line()
return l1.K == l2.K return l1.K == l2.K || l1.Vertical && l2.Vertical
} }
// Returns angle between liners in radians. // Returns angle between liners in radians.

20
math.go
View file

@ -13,8 +13,17 @@ const (
Pi = math.Pi Pi = math.Pi
RadDegrees = 57.2958 RadDegrees = 57.2958
//PiRad = Pi * Rad //PiRad = Pi * Rad
EqualityThreshold = 1e-9
) )
func IsNan(v Float) bool {
return math.IsNaN(v)
}
func IsInf(f Float, sign int) bool {
return math.IsInf(f, sign)
}
func Degree(f Float) Float { func Degree(f Float) Float {
return (f/(2*Pi))*360 return (f/(2*Pi))*360
} }
@ -64,6 +73,13 @@ func Min(v1, v2 Float) Float {
return v2 return v2
} }
func Abs(v Float) Float {
if v >= 0 {
return v
}
return -v
}
func RadiansToDegrees(v Float) Float { func RadiansToDegrees(v Float) Float {
return v/Pi * 180 return v/Pi * 180
} }
@ -72,4 +88,8 @@ func DeegresToRadians(v Float) Float {
return v return v
} }
// Returns whether the two floats are nearly equal.
func Neq(a, b Float) bool {
return Abs(a-b) <= EqualityThreshold
}

View file

@ -28,6 +28,13 @@ func (p Polygon) MakeTriangles() Triangles {
return ret return ret
} }
func (p Polygon) Vertices() Vertices {
return p.MakeTriangles().Vertices()
}
func (p Polygon) Edges() Edges {
return p.MakeTriangles().Edges()
}
// Polygon that can be drawn. // Polygon that can be drawn.
type DrawablePolygon struct { type DrawablePolygon struct {
Polygon Polygon

View file

@ -6,7 +6,13 @@ type Size struct {
// The upper left corner position point. // The upper left corner position point.
Position Point Position Point
// Absolute width and height. // Absolute width and height.
// Both must be positive values.
Width, Height Float Width, Height Float
} }
func (size Size) ContainsPoint(pt Point) bool {
return (size.Position.X < pt.X && (size.Position.X + size.Width) > pt.X ) &&
(size.Position.Y < pt.Y && (size.Position.Y + size.Height) > pt.Y )
}
//type (s Size) ContainsPoint //type (s Size) ContainsPoint

View file

@ -3,3 +3,6 @@ tasks:
btest: btest:
cmds: cmds:
- go build ./cmd/test/ - go build ./cmd/test/
bmath:
cmds:
- go build ./cmd/math/

View file

@ -43,6 +43,7 @@ func T() Transform {
scale: Vector{1, 1}, scale: Vector{1, 1},
// Rotate around the center. // Rotate around the center.
around: V(.5, .5), around: V(.5, .5),
rotation: EqualityThreshold,
} }
return ret return ret
} }

View file

@ -86,6 +86,14 @@ func (t Triangle) Sgn() Float {
(t[1].X - t[2].X) * (t[0].Y - t[2].Y) (t[1].X - t[2].X) * (t[0].Y - t[2].Y)
} }
func (t Triangle) Edges() Edges {
return Edges{
Edge{t[0], t[1]},
Edge{t[1], t[2]},
Edge{t[2], t[0]},
}
}
func (t Triangle) Vertices() Vertices { func (t Triangle) Vertices() Vertices {
return Vertices{ return Vertices{
t[0], t[1], t[2], t[0], t[1], t[2],
@ -103,6 +111,22 @@ func (ts Triangles) ContainedPoints(pts Points) (Points) {
return ret return ret
} }
func (ts Triangles) Vertices() Vertices {
ret := make(Vertices, 0, len(ts)*3)
for _, t := range ts {
ret = append(ret, t.Vertices()...)
}
return ret
}
func (ts Triangles) Edges() Edges {
ret := make(Edges, 0, len(ts)*3)
for _, t := range ts {
ret = append(ret, t.Edges()...)
}
return ret
}
func (r *DrawableTriangles) MakeEVertices(c *Context) []EVertex { func (r *DrawableTriangles) MakeEVertices(c *Context) []EVertex {
m := c.Camera.RealMatrix() m := c.Camera.RealMatrix()
vs := make([]ebiten.Vertex, len(r.Triangles) * 3) vs := make([]ebiten.Vertex, len(r.Triangles) * 3)
@ -117,3 +141,4 @@ func (r *DrawableTriangles) MakeEVertices(c *Context) []EVertex {
return vs return vs
} }