Esempio n. 1
0
		/// <summary>
		/// 从edges开始检查, 获取将半径为radius的物体, 从from移动到to, 可达的最远位置. 
		/// </summary>
		Vector3 RaycastWithEdges(IEnumerable<HalfEdge> edges, Vector3 from, Vector3 to, float radius)
		{
			if (from.equals2(to))
			{
				return to;
			}

			Vector2 segCrossAnswer = Vector2.zero;
			foreach (HalfEdge edge in edges)
			{
				// 检查相交.
				CrossState crossState = MathUtility.SegmentCross(out segCrossAnswer, from, to, edge.Src.Position, edge.Dest.Position);

				Utility.Verify(crossState == CrossState.CrossOnSegment || crossState == CrossState.CrossOnExtLine);

				// 交点不在线段上.
				if (segCrossAnswer.x < 0 || segCrossAnswer.x > 1) { continue; }

				// 如果交点在线段上, 那么表示该交点为当前最远位置. 再继续从这条边开始检查.
				if (crossState == CrossState.CrossOnSegment)
				{
					Vector3 cross = from + segCrossAnswer.x * (to - from);
					to = RaycastFromEdge(edge, cross, to, radius);
					break;
				}
			}

			return to;
		}
Esempio n. 2
0
		/// <summary>
		/// 查找ray的环中, 与src->dest的边相交的边.
		/// </summary>
		bool FindCrossedEdge(out Tuple2<HalfEdge, CrossState> answer, HalfEdge ray, Vector3 src, Vector3 dest)
		{
			List<HalfEdge> cycle = ray.Cycle;
			answer = new Tuple2<HalfEdge, CrossState>();

			foreach (HalfEdge edge in cycle)
			{
				Vector3 point;
				CrossState crossState = MathUtility.GetLineCrossPoint(out point,
					edge.Src.Position, edge.Dest.Position,
					src, dest
				);

				if (crossState == CrossState.FullyOverlaps
					|| (crossState == CrossState.CrossOnSegment && !point.equals2(edge.Src.Position) && !point.equals2(edge.Dest.Position)))
				{
					answer.Second = crossState;
					answer.First = edge;
					if (crossState == CrossState.FullyOverlaps
						&& (dest.equals2(edge.Src.Position) || src.equals2(edge.Dest.Position)))
					{
						answer.First = answer.First.Pair;
					}

					return true;
				}
			}

			return false;
		}
Esempio n. 3
0
		/// <summary>
		/// from在edge上, 查找半径为radius的物体从from到to可达的最远位置.
		/// </summary>
		Vector3 RaycastFromEdge(HalfEdge edge, Vector3 from, Vector3 to, float radius)
		{
			// 起点==终点, 或者edge为约束边.
			if (from.equals2(to) || edge.Constrained || edge.Pair.Constrained)
			{
				return from;
			}

			// from位置无效.
			if (!IsValidPosition(from, radius))
			{
				return from;
			}

			// 根据from->to的方向, 确定下一个要访问的三角形是edge.Face还是edge.Pair.Face.
			if ((to - from).cross2(edge.Dest.Position - edge.Src.Position) > 0)
			{
				edge = edge.Pair;
			}

			// 不存在另一边的三角形.
			if (edge.Face == null)
			{
				return from;
			}

			// 检查另外两条边.
			return RaycastWithEdges(new HalfEdge[] { edge.Next, edge.Next.Next }, from, to, radius);
		}