当前位置: 首页>>代码示例>>Golang>>正文


Golang Seg2.Ray方法代码示例

本文整理汇总了Golang中github.com/runningwild/linear.Seg2.Ray方法的典型用法代码示例。如果您正苦于以下问题:Golang Seg2.Ray方法的具体用法?Golang Seg2.Ray怎么用?Golang Seg2.Ray使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在github.com/runningwild/linear.Seg2的用法示例。


在下文中一共展示了Seg2.Ray方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。

示例1: 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
}
开发者ID:runningwild,项目名称:magnus,代码行数:15,代码来源:generator.go

示例2: 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)
}
开发者ID:runningwild,项目名称:magnus,代码行数:94,代码来源:rift_walk.go

示例3: GenerateRoom


//.........这里部分代码省略.........
	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 {
			if distFromPointToSeg(p, seg) < radius/2 {
				good = false
				break
			}
		}

		// Check to make sure this segment isn't coincident with any othe segment.
		// To avoid annoying degeneracies we'll rotate the segment slightly.
		rot := linear.Seg2{seg.P, seg.Ray().Rotate(0.01).Add(seg.P)}
		for _, cur := range segs {
			if rot.DoesIsect(cur) {
				good = false
				break
			}
		}

		if !good {
			sanity--
			continue
		}
		segs = append(segs, seg)
	}

	for _, s := range segs {
		right := s.Ray().Cross().Norm().Scale(-float64(grid))
		s2 := linear.Seg2{s.Q.Add(right), s.P.Add(right)}
		room.Walls[nextId()] = linear.Poly{s.P, s.Q, s2.P, s2.Q}
	}
	room.Walls[nextId()] = linear.Poly{
		linear.Vec2{0, 0},
		linear.Vec2{dx, 0},
		linear.Vec2{dx, dy},
		linear.Vec2{0, dy},
	}
	room.NextId = nextIdInt
	return room
}
开发者ID:runningwild,项目名称:magnus,代码行数:101,代码来源:generator.go

示例4: 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
//.........这里部分代码省略.........
开发者ID:runningwild,项目名称:jota,代码行数:101,代码来源:base_ent.go

示例5: 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
				}
//.........这里部分代码省略.........
开发者ID:dgthunder,项目名称:magnus,代码行数:101,代码来源:game.go


注:本文中的github.com/runningwild/linear.Seg2.Ray方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。