本文整理汇总了Golang中github.com/runningwild/linear.Seg2类的典型用法代码示例。如果您正苦于以下问题:Golang Seg2类的具体用法?Golang Seg2怎么用?Golang Seg2使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Seg2类的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: TestSeg
// Returns the fraction of the segment that was visible
func (l *Los) TestSeg(seg linear.Seg2) float64 {
seg.P = seg.P.Sub(l.in.Pos)
seg.Q = seg.Q.Sub(l.in.Pos)
wrap := len(l.in.Buffer.ZBuffer)
a1 := math.Atan2(seg.P.Y, seg.P.X)
a2 := math.Atan2(seg.Q.Y, seg.Q.X)
if a1 > a2 {
a1, a2 = a2, a1
seg.P, seg.Q = seg.Q, seg.P
}
if a2-a1 > math.Pi {
a1, a2 = a2, a1
seg.P, seg.Q = seg.Q, seg.P
}
start := int(((a1 / (2 * math.Pi)) + 0.5) * float64(len(l.in.Buffer.ZBuffer)))
end := int(((a2 / (2 * math.Pi)) + 0.5) * float64(len(l.in.Buffer.ZBuffer)))
count := 0.0
visible := 0.0
for i := start % wrap; i != end%wrap; i = (i + 1) % wrap {
dist2 := float32(rays[i].Isect(seg).Mag2())
if dist2 < l.in.Buffer.ZBuffer[i] {
visible += 1.0
}
count += 1.0
}
return visible / count
}
示例2: DrawSeg
func (l *Los) DrawSeg(seg linear.Seg2, source string) {
seg.P = seg.P.Sub(l.in.Pos)
seg.Q = seg.Q.Sub(l.in.Pos)
wrap := len(l.in.Buffer.ZBuffer)
a1 := math.Atan2(seg.P.Y, seg.P.X)
a2 := math.Atan2(seg.Q.Y, seg.Q.X)
if a1 > a2 {
a1, a2 = a2, a1
seg.P, seg.Q = seg.Q, seg.P
}
if a2-a1 > math.Pi {
a1, a2 = a2, a1
seg.P, seg.Q = seg.Q, seg.P
}
start := int(((a1 / (2 * math.Pi)) + 0.5) * float64(len(l.in.Buffer.ZBuffer)))
end := int(((a2 / (2 * math.Pi)) + 0.5) * float64(len(l.in.Buffer.ZBuffer)))
for i := start % wrap; i != end%wrap; i = (i + 1) % wrap {
dist2 := float32(rays[i].Isect(seg).Mag2())
// dist = rays[i].Isect(seg).Mag2()
if dist2 < l.in.Buffer.ZBuffer[i] {
l.in.Buffer.ZBuffer[i] = dist2
l.in.Buffer.SBuffer[i] = source
}
}
}
示例3: Think
func (p *lightningBoltProc) Think(g *game.Game) {
p.NumThinks++
if p.NumThinks < p.BuildThinks {
return
}
perp := p.Seg.Ray().Cross().Norm().Scale(p.Width / 2)
for _, ent := range g.Ents {
entSeg := linear.Seg2{
ent.Pos().Sub(perp),
ent.Pos().Add(perp),
}
if entSeg.DoesIsect(p.Seg) {
ent.Stats().ApplyDamage(stats.Damage{stats.DamageFire, p.Dps * p.Power})
}
}
// for _, ent := range g.Ents {
// if ent.Pos().Sub(p.Pos).Mag2() <= p.CurrentRadius*p.CurrentRadius {
// ent.Stats().ApplyDamage(stats.Damage{stats.DamageFire, p.Dps})
// }
// }
}
示例4: fireDoLine
func fireDoLine(c *cmwc.Cmwc, pos linear.Vec2, angle, stored float64, speed int, level *game.Level) fireExplosion {
rng := rand.New(c)
ray := (linear.Vec2{1, 0})
// ray.Scale(math.Abs(rng.NormFloat64()/10) + 50)
scale := (stored/5 + 50) * (1 + rng.Float64()*(0.2+stored/2000))
ray = ray.Rotate(angle).Rotate(rng.NormFloat64() * (0.2 + stored/7500)).Scale(scale)
seg := linear.Seg2{pos, pos.Add(ray)}
base.DoOrdered(level.Room.Walls, func(a, b string) bool { return a < b }, func(_ string, poly linear.Poly) {
for i := range poly {
if seg.DoesIsect(poly.Seg(i)) {
isect := seg.Isect(poly.Seg(i))
seg.Q = isect
}
}
})
p1 := rng.Intn(speed)
p2 := rng.Intn(speed)
p3 := rng.Intn(speed)
return fireExplosion{
Pos: seg.Q,
Radius: rng.Float64()*40 + 30,
Timer: 0,
Start: 1*speed + p1,
Peak: 4*speed + p1 + p2,
End: 5*speed + p1 + p2 + p3,
}
}
示例5: Apply
func (e addRiftWalkFireEvent) Apply(_g interface{}) {
g := _g.(*game.Game)
player, ok := g.Ents[e.PlayerGid].(*game.PlayerEnt)
if !ok {
return
}
proc := player.Processes[100+e.ProcessId]
if proc == nil {
return
}
rwProc, ok := proc.(*riftWalkProcess)
if !ok {
return
}
if rwProc.Stored.Magnitude() <= rwProc.Threshold {
return
}
dist, radius := rwProc.GetVals()
rwProc.Stored = game.Mana{}
movement := (linear.Vec2{dist, 0}).Rotate(player.Angle)
dest := player.Pos().Add(movement)
inside := false
// Check if the player would end up inside a polygon
for _, poly := range g.Levels[player.Level()].Room.Walls {
if linear.VecInsideConvexPoly(dest, poly) {
inside = true
break
}
}
// If the player would end up inside a polygon then intersect the segment the
// player would move along with all line segements and move the player to the
// nearest intersection point.
if inside {
moveSeg := linear.Seg2{player.Pos(), dest}
closest := dest
var collisionSeg linear.Seg2
for _, poly := range g.Levels[player.Level()].Room.Walls {
for i := range poly {
seg := poly.Seg(i)
if seg.DoesIsect(moveSeg) {
isect := seg.Isect(moveSeg)
if isect.Sub(player.Pos()).Mag2() < closest.Sub(player.Pos()).Mag2() {
closest = isect
collisionSeg = seg
}
}
}
}
if collisionSeg.Ray().Mag2() == 0 {
dest = closest.Sub(movement.Norm().Scale(player.Stats().Size() * 2))
} else {
nudge := collisionSeg.Ray().Norm().Cross().Scale(player.Stats().Size())
dest = closest.Add(nudge)
}
}
for _, ent := range g.Ents {
if ent == player {
continue
}
doDamage := false
if ent.Pos().Sub(dest).Mag() <= radius+ent.Stats().Size() {
angle := dest.Sub(ent.Pos()).Angle()
ent.ApplyForce((linear.Vec2{-rwProc.Force, 0}).Rotate(angle))
doDamage = true
} else {
ray := dest.Sub(player.Pos())
perp := ray.Cross().Norm()
scaledPerp := perp.Scale(ent.Stats().Size() + player.Stats().Size())
sideRay0 := linear.Seg2{player.Pos().Add(scaledPerp), dest.Add(scaledPerp)}
sideRay1 := linear.Seg2{player.Pos().Sub(scaledPerp), dest.Sub(scaledPerp)}
if sideRay0.Left(ent.Pos()) != sideRay1.Left(ent.Pos()) {
// We know the ent lies between sideRays 0 and 1, now we need to make
// sure it lies between src and dst.
forward := ent.Pos().Sub(dest)
backward := ent.Pos().Sub(player.Pos())
if (forward.Dot(ray) < 0) != (backward.Dot(ray) < 0) {
if (linear.Seg2{player.Pos(), dest}).Left(ent.Pos()) {
ent.ApplyForce(perp.Scale(rwProc.Force))
} else {
ent.ApplyForce(perp.Scale(-rwProc.Force))
}
doDamage = true
}
}
}
if doDamage {
ent.Stats().ApplyDamage(stats.Damage{stats.DamageFire, 50})
}
}
player.SetPos(dest)
}
示例6: GenerateRoom
func GenerateRoom(dx, dy, radius float64, grid int, seed int64) Room {
var room Room
room.Walls = make(map[string]linear.Poly)
nextIdInt = 0
room.Dx = int(dx)
room.Dy = int(dy)
c := cmwc.MakeGoodCmwc()
if seed == 0 {
c.SeedWithDevRand()
n := c.Int63()
c = cmwc.MakeGoodCmwc()
base.Log().Printf("SEED: %v", n)
c.Seed(n)
} else {
c.Seed(seed)
}
sanity := int(math.Sqrt(dx * dy))
r := rand.New(c)
var poss []linear.Vec2
for sanity > 0 {
pos := linear.Vec2{r.Float64() * (dx - radius + 1), r.Float64() * (dy - radius + 1)}
good := true
for _, p := range poss {
if p.Sub(pos).Mag() < 2*(2*radius) {
good = false
break
}
}
if !good {
sanity--
continue
}
poss = append(poss, pos)
}
// Find the pair of points that maximizes distance
maxDist := 0.0
for i := range poss {
for j := range poss {
dist := poss[i].Sub(poss[j]).Mag()
if dist > maxDist {
maxDist = dist
}
}
}
var a, b int
minDist := maxDist * 3 / 4
hits := 1.0
for i := range poss {
for j := range poss {
if i == j {
continue
}
dist := poss[i].Sub(poss[j]).Mag()
if dist > minDist && r.Float64() < 1.0/hits {
a, b = i, j
hits = hits + 1
}
}
}
room.Starts = []linear.Vec2{poss[a], poss[b]}
for _, start := range room.Starts {
var data mobaRoomSideData
data.Base = start
room.Moba.SideData = append(room.Moba.SideData, data)
}
var data mobaRoomSideData
for i, pos := range poss {
if i == a || i == b {
continue
}
data.Towers = append(data.Towers, pos)
}
room.Moba.SideData = append(room.Moba.SideData, data)
sanity = int(math.Pow(dx*dy, 0.20))
var segs []linear.Seg2
for sanity > 0 {
a := linear.Vec2{r.Float64() * (dx), r.Float64() * (dy)}
length := gridify(r.Float64()*radius+(radius), grid)
angle := float64(r.Intn(4)) * 3.1415926535 / 2
ray := (linear.Vec2{1, 0}).Rotate(angle)
seg := linear.Seg2{a, a.Add(ray.Scale(length))}
seg.P.X = gridify(seg.P.X, grid)
seg.P.Y = gridify(seg.P.Y, grid)
seg.Q.X = gridify(seg.Q.X, grid)
seg.Q.Y = gridify(seg.Q.Y, grid)
good := true
if seg.P.X <= 0 || seg.P.X >= dx || seg.P.Y <= 0 || seg.P.Y >= dy {
good = false
}
if seg.Q.X <= 0 || seg.Q.X >= dx || seg.Q.Y <= 0 || seg.Q.Y >= dy {
good = false
}
if seg.P.X == seg.Q.X && seg.P.Y == seg.Q.Y {
good = false
}
// Can't get too close to a circle
for _, p := range poss {
//.........这里部分代码省略.........
示例7: distFromPointToSeg
func distFromPointToSeg(p linear.Vec2, s linear.Seg2) float64 {
s.P = s.P.Sub(p)
s.Q = s.Q.Sub(p)
cross := s.Ray().Cross()
crossSeg := linear.Seg2{Q: cross}
if crossSeg.Left(s.P) != crossSeg.Left(s.Q) {
return s.DistFromOrigin()
}
da := s.P.Mag()
db := s.Q.Mag()
if da < db {
return da
}
return db
}
示例8: Think
func (b *BaseEnt) Think(g *Game) {
// This will clear out old conditions
b.StatsInst.Think()
var dead []int
// Calling DoOrdered is too slow, so we just sort the Gids ourselves and go
// through them in order.
pids := make([]int, len(b.Processes))[0:0]
for pid := range b.Processes {
pids = append(pids, pid)
}
sort.Ints(pids)
for _, pid := range pids {
proc := b.Processes[pid]
proc.Think(g)
if proc.Dead() {
dead = append(dead, pid)
} else {
b.StatsInst.ApplyCondition(proc)
}
}
// Removed dead processes from the ent
for _, id := range dead {
delete(b.Processes, id)
}
if b.Delta.Speed < -1.0 {
b.Delta.Speed = -1.0
}
if b.Delta.Speed > 1.0 {
b.Delta.Speed = 1.0
}
// TODO: Speed is a complete misnomer now - fix it!
force := b.Delta.Speed * (linear.Vec2{1, 0}).Rotate(b.Target.Angle).Dot((linear.Vec2{1, 0}).Rotate(b.Angle_))
b.ApplyForce((linear.Vec2{1, 0}).Rotate(b.Angle_).Scale(force * b.Stats().MaxAcc()))
mangle := math.Atan2(b.Velocity.Y, b.Velocity.X)
friction := g.Friction
b.Velocity = b.Velocity.Scale(
math.Pow(friction, 1+3*math.Abs(math.Sin(b.Angle_-mangle))))
if b.Velocity.Mag2() < 0.01 {
b.Velocity = linear.Vec2{0, 0}
} else {
size := b.Stats().Size()
sizeSq := size * size
// We pretend that the player is started from a little behind wherever they
// actually are. This makes it a lot easier to get collisions to make sense
// from frame to frame.
epsilon := b.Velocity.Norm().Scale(size / 2)
move := linear.Seg2{b.Position.Sub(epsilon), b.Position.Add(b.Velocity)}
prev := b.Position
walls := g.local.temp.WallCache.GetWalls(int(b.Position.X), int(b.Position.Y))
for _, wall := range walls {
// Don't bother with back-facing segments
if wall.Right(b.Position) {
continue
}
// Check against the segment itself
if wall.Ray().Cross().Dot(move.Ray()) <= 0 {
shiftNorm := wall.Ray().Cross().Norm()
shift := shiftNorm.Scale(size)
col := linear.Seg2{shift.Add(wall.P), shift.Add(wall.Q)}
if move.DoesIsect(col) {
cross := col.Ray().Cross()
fix := linear.Seg2{move.Q, cross.Add(move.Q)}
isect := fix.Isect(col)
move.Q = isect
}
}
}
for _, wall := range walls {
// Check against the leading vertex
{
v := wall.P
originMove := linear.Seg2{move.P.Sub(v), move.Q.Sub(v)}
originPerp := linear.Seg2{linear.Vec2{}, move.Ray().Cross()}
dist := originMove.DistFromOrigin()
if originPerp.DoesIsect(originMove) && dist < size {
// Stop passthrough
isect := originMove.Isect(originPerp).Add(v)
diff := math.Sqrt(sizeSq - dist*dist)
finalLength := isect.Sub(move.P).Mag() - diff
move.Q = move.Ray().Norm().Scale(finalLength).Add(move.P)
} else if v.Sub(move.Q).Mag2() < sizeSq {
move.Q = move.Q.Sub(v).Norm().Scale(size).Add(v)
}
}
}
b.Position = move.Q
b.Velocity = b.Position.Sub(prev)
}
if math.Abs(b.Angle_+b.Target.Angle-math.Pi) < 0.01 {
b.Angle_ += 0.1
} else {
frac := 0.80
//.........这里部分代码省略.........
示例9: Think
func (p *Player) Think(g *Game) {
if p.Exile_frames > 0 {
p.Exile_frames--
return
}
// This will clear out old conditions
p.Stats.Think()
var dead []int
for i, process := range p.Processes {
process.Think(g)
if process.Phase() == PhaseComplete {
dead = append(dead, i)
}
}
for _, i := range dead {
delete(p.Processes, i)
}
// And here we add back in all processes that are still alive.
for _, process := range p.Processes {
p.Stats.ApplyCondition(process)
}
if p.Delta.Speed > p.Stats.MaxAcc() {
p.Delta.Speed = p.Stats.MaxAcc()
}
if p.Delta.Speed < -p.Stats.MaxAcc() {
p.Delta.Speed = -p.Stats.MaxAcc()
}
if p.Delta.Angle < -p.Stats.MaxTurn() {
p.Delta.Angle = -p.Stats.MaxTurn()
}
if p.Delta.Angle > p.Stats.MaxTurn() {
p.Delta.Angle = p.Stats.MaxTurn()
}
in_lava := false
for _, lava := range g.Room.Lava {
if vecInsideConvexPoly(p.Pos(), lava) {
in_lava = true
}
}
if in_lava {
p.Stats.ApplyDamage(stats.Damage{stats.DamageFire, 5})
}
p.Vx += p.Delta.Speed * math.Cos(p.Angle)
p.Vy += p.Delta.Speed * math.Sin(p.Angle)
mangle := math.Atan2(p.Vy, p.Vx)
friction := g.Friction
if in_lava {
friction = g.Friction_lava
}
p.Vx *= math.Pow(friction, 1+3*math.Abs(math.Sin(p.Angle-mangle)))
p.Vy *= math.Pow(friction, 1+3*math.Abs(math.Sin(p.Angle-mangle)))
move := linear.MakeSeg2(p.X, p.Y, p.X+p.Vx, p.Y+p.Vy)
size := 12.0
px := p.X
py := p.Y
p.X += p.Vx
p.Y += p.Vy
for _, poly := range g.Room.Walls {
for i := range poly {
// First check against the leading vertex
{
v := poly[i]
dist := v.DistToLine(move)
if v.Sub(move.Q).Mag() < size {
dist = v.Sub(move.Q).Mag()
// Add a little extra here otherwise a player can sneak into geometry
// through the corners
ray := move.Q.Sub(v).Norm().Scale(size + 0.1)
final := v.Add(ray)
move.Q.X = final.X
move.Q.Y = final.Y
} else if dist < size {
// TODO: This tries to prevent passthrough but has other problems
// cross := move.Ray().Cross()
// perp := linear.Seg2{v, cross.Sub(v)}
// if perp.Left(move.P) != perp.Left(move.Q) {
// shift := perp.Ray().Norm().Scale(size - dist)
// move.Q.X += shift.X
// move.Q.Y += shift.Y
// }
}
}
// Now check against the segment itself
w := poly.Seg(i)
if w.Ray().Cross().Dot(move.Ray()) <= 0 {
shift := w.Ray().Cross().Norm().Scale(size)
col := linear.Seg2{shift.Add(w.P), shift.Add(w.Q)}
if move.DoesIsect(col) {
cross := col.Ray().Cross()
fix := linear.Seg2{move.Q, cross.Add(move.Q)}
isect := fix.Isect(col)
move.Q.X = isect.X
move.Q.Y = isect.Y
}
//.........这里部分代码省略.........