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 {
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 {
@ -87,4 +98,3 @@ func (d *Debug) Draw(c *Context) []gg.EVertex {
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) {
/*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.Move(gg.Y(1))
if p.Spawned {
@ -71,7 +78,7 @@ func (p *Player) Update(c *Context) {
),
)
case gg.KeyW:
p.Move(gg.Y(-p.MoveSpeed * dt *10))
p.Move(gg.Y(-p.MoveSpeed * dt ))
walking = true
p.Animate(Walk)
case gg.KeyA:
@ -80,7 +87,7 @@ func (p *Player) Update(c *Context) {
walking = true
p.Animate(Walk)
case gg.KeyS:
p.Move(gg.X(-p.MoveSpeed * dt))
p.Move(gg.Y(p.MoveSpeed * dt))
//p.Position.Y -= p.MoveSpeed * dt
walking = true
p.Animate(Walk)
@ -160,8 +167,11 @@ func (p *Player) GetCollisionInterest() []gg.CollisionType {
func (p *Player) Resolve(c *Context) {
col := c.Collisions[0]
if !p.Spawned {
fmt.Printf("frame[%d]: the col[0] len(%d): %T, %T\n", c.Frame(), len(c.Collisions), col.What, col.With)
if !p.Spawned && false {
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{
case gg.CollisionStaticPhysics :

View file

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

View file

@ -1,7 +1,7 @@
package main
import "vultras.su/core/gg"
//import "fmt"
import "fmt"
var (
counter int
@ -15,6 +15,7 @@ type Tri struct {
func NewTri() *Tri {
ret := &Tri{}
ret.Transform = gg.T()
ret.SetPosition(gg.V(-100, -100))
ret.Triangles = gg.Triangles{
gg.Triangle{
gg.V(0, 10),
@ -24,13 +25,27 @@ func NewTri() *Tri {
}
ret.Color = gg.Rgba(1, 1, 0, 1)
ret.Visible = true
ret.Collidable = true
ret.Type = gg.CollisionStaticPhysics
ret.Layer = TriangleL
ret.Connect(player)
//ret.Connect(player)
return ret
}
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()
if !t.ContainedPoints(gg.Points{c.AbsCursorPosition()}).Empty() {
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) {
vertices := c1.Vertices()
es1, es2 := c1.Edges(), c2.Edges()
crosses, doCross := es1.LineCrossWith(es2)
crosses, doCross := es1.CrossWithEdges(es2)
pts := c2.ContainedPoints(vertices)
return Collision{
Type: c2.CollisionType(),
@ -91,7 +91,7 @@ func Collide(c1, c2 Collider) (Collision, bool) {
With: c2,
Points: pts,
Crosses: crosses,
}, len(pts) != 0 || doCross
}, len(pts) > 0 || doCross
}
func GetCollisions(c Collider, cs []Collider) []Collision {

29
edge.go
View file

@ -2,7 +2,7 @@ package gg
type Edges []Edge
// Get crosses of edges.
func (what Edges) LineCrossWith(with Edges) ([]LineCross, bool) {
func (what Edges) CrossWithEdges(with Edges) ([]LineCross, bool) {
ret := []LineCross{}
for i := range what {
for j := range with {
@ -13,11 +13,7 @@ func (what Edges) LineCrossWith(with Edges) ([]LineCross, bool) {
}
}
if len(ret) == 0 {
return nil, false
}
return ret, true
return ret, len(ret) > 0
}
// 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.
func (l Edge) Line() Line {
var (
x Float
vertical bool
)
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}
if p0.X == p1.X {
vertical = true
x = p0.X
}
return Line{k, c, x, vertical}
}
func (l Edge) ContainedPoints(pts Points) (Points) {
@ -51,11 +56,11 @@ func (l Edge) ContainsPoint(p Point) bool {
return false
}
xMax := Max(l[0].X, l[1].X)
xMin := Min(l[0].X, l[1].X)
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)
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) {

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
//import "fmt"
// The type represents mathematical equation of line and line itself.
type Line struct {
K, C Float
K, C, X Float
Vertical bool
}
// 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 {
buf := Line{0, p.Y}
buf := Line{0, p.Y, 0, false}
pc, ok := l.crossesLine(buf)
if !ok {
return false
}
return pc == p
return Neq(pc.X, p.X) && Neq(pc.Y, p.Y)
}
func (l1 Line) crossesLine(l2 Line) (Point, bool) {
var x, y Float
if LinersParallel(l1, l2) {
return Point{}, false
}
x := (l1.C - l2.C) / (l2.K - l1.K)
y := l1.K*x + l1.C
if l1.Vertical {
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
}

View file

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

20
math.go
View file

@ -13,8 +13,17 @@ const (
Pi = math.Pi
RadDegrees = 57.2958
//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 {
return (f/(2*Pi))*360
}
@ -64,6 +73,13 @@ func Min(v1, v2 Float) Float {
return v2
}
func Abs(v Float) Float {
if v >= 0 {
return v
}
return -v
}
func RadiansToDegrees(v Float) Float {
return v/Pi * 180
}
@ -72,4 +88,8 @@ func DeegresToRadians(v Float) Float {
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
}
func (p Polygon) Vertices() Vertices {
return p.MakeTriangles().Vertices()
}
func (p Polygon) Edges() Edges {
return p.MakeTriangles().Edges()
}
// Polygon that can be drawn.
type DrawablePolygon struct {
Polygon

View file

@ -6,7 +6,13 @@ type Size struct {
// The upper left corner position point.
Position Point
// Absolute width and height.
// Both must be positive values.
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

View file

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

View file

@ -43,6 +43,7 @@ func T() Transform {
scale: Vector{1, 1},
// Rotate around the center.
around: V(.5, .5),
rotation: EqualityThreshold,
}
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)
}
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 {
return Vertices{
t[0], t[1], t[2],
@ -103,6 +111,22 @@ func (ts Triangles) ContainedPoints(pts Points) (Points) {
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 {
m := c.Camera.RealMatrix()
vs := make([]ebiten.Vertex, len(r.Triangles) * 3)
@ -117,3 +141,4 @@ func (r *DrawableTriangles) MakeEVertices(c *Context) []EVertex {
return vs
}