/// <summary> /// 頂点の設定。始点と終点が結ばれていること /// </summary> public void SetVertices(List <Vector2> vertices, Color color) { //包括矩形から原点からのオフセットを求め適用する Rect rect = GeomUtil.CalculateRect(vertices); for (int i = 0; i < vertices.Count; ++i) { vertices[i] -= rect.center; } this.vertices = vertices; //座標をずらす transform.localPosition = rect.center; //改めて包括矩形を求める inclusionRect = GeomUtil.CalculateRect(vertices); //ポリゴンの生成 //末尾を削除(一時的) vertices.RemoveAt(vertices.Count - 1); polygon = new ConcavePolygon(vertices); //末尾に先頭を追加 vertices.Add(vertices[0]); //簡易メッシュの確保 drawEMesh = polygon.ToEasyMesh(color); subEMesh = polygon.ToEasyMesh(color); //描画用メッシュの領域確保 drawEMeshes = new EasyMesh[2]; //色 SetPolygonColor(color); draw = true; }
internal void SetupDrawCall(Camera cam) { if (UseFrustumCulling) { GeomUtil.CalculateFrustumPlanes(s_planes, Camera.current.projectionMatrix * Camera.current.worldToCameraMatrix); isVisible |= GeometryUtility.TestPlanesAABB(s_planes, Bounds); } if (!SystemComp.enabled || SystemComp.ParticleCount == 0) { return; } //Setup proper size mult depending on camera ortho size if (isPixelSize) { var pixelMult = Mathf.Max(1.0f / Screen.width, 1.0f / Screen.height); if (cam.orthographic) { pixelMult *= cam.orthographicSize * 2.0f; } m_cacheMaterial.SetVector(SID._PixelMult, new Vector4(pixelMult, cam.orthographic ? 0.0f : 1.0f)); } else { m_cacheMaterial.SetVector(SID._PixelMult, new Vector4(1.0f, 0.0f)); } //Setup DrawM Bounds bounds = UseFrustumCulling ? _bounds : new Bounds(Vector3.zero, Vector3.one * 10000); var layer = SystemComp.gameObject.layer; Graphics.DrawMeshInstancedIndirect(m_particleMesh, 0, m_cacheMaterial, bounds, m_argsBuffer, 0, null, CastShadows, ReceiveShadows, layer, cam); }
public int Overlap(ICollection <Collider> results, int layerMask, QueryTriggerInteraction query) { if (results == null) { throw new System.ArgumentNullException("results"); } using (var set = TempCollection.GetSet <Collider>()) { foreach (var c in _colliders) { GeomUtil.GetGeom(c).Overlap(set, layerMask, query); } if (set.Count > 0) { var e = set.GetEnumerator(); while (e.MoveNext()) { results.Add(e.Current); } return(set.Count); } } return(0); }
/// <summary> /// Transforms local rect to global /// </summary> public Rect LocalToGlobal(Rect rect) { Rect result; GeomUtil.GetBounds(ref rect, ref compositeMatrix, out result); return(result); }
/// <summary> /// 頂点の設定 /// </summary> public void SetVertices(List <Vector2> vertices) { //包括矩形から原点からのオフセットを求め適用する Rect rect = GeomUtil.CalculateRect(vertices); for (int i = 0; i < vertices.Count; ++i) { vertices[i] -= rect.center; } this.vertices = vertices; //座標をずらす transform.localPosition = rect.center; //改めて包括矩形を求める inclusionRect = GeomUtil.CalculateRect(vertices); //ポリゴンの生成 vertices.RemoveAt(vertices.Count - 1); //末尾を一時的に削除 polygon = new ConcavePolygon(vertices); vertices.Add(vertices[0]); //末尾に始点を追加 //簡易メッシュの確保 drawEMesh = polygon.ToEasyMesh(polygonColor); targetColorEMesh = polygon.ToEasyMesh(polygonColor); //描画用簡易メッシュ領域の確保 eMeshes = new EasyMesh[2]; //コールバック onVertexChanged.Invoke(this); draw = true; }
// Update is called once per frame void Update() { if (null != OrgTran && null != TargetTran) { InFront = GeomUtil.Match_InFront(OrgTran.position, TargetTran.position); } }
public override bool Snap(Vector2 input, out Vector2 output) { float angle = GeomUtil.TwoPointAngle(point, input); //最も近い放射角度を求める float nearAngle = 0f; float halfDelta = deltaAngle * 0.5f; for (int i = 0; i < angles.Length; ++i) { if ((angles[i] - halfDelta) < angle && angle < (angles[i] + halfDelta)) { nearAngle = angles[i]; break; } } //線上の射影からスナップ座標を求める Vector2 p, q; p = GeomUtil.DegToVector2(nearAngle); q = input - point; float dot = GeomUtil.Dot(p, q); float projection = dot / p.magnitude; //射影距離 output = p.normalized * projection + point; //スナップ座標との距離を測る if ((output - input).magnitude <= snapForce) { return(true); } else { return(false); } }
public Rect GetChildrenBounds() { var resultBounds = new Rect(); var firstChild = true; foreach (var child in _children) { if (!child.visible) { continue; } var childBounds = child.GetLocalBounds(); if (firstChild) { firstChild = false; resultBounds = childBounds; } else { GeomUtil.UnionRect(ref resultBounds, ref childBounds, out resultBounds); } } return(resultBounds); }
///判断一个点是不是在一个多边形内,可以支持非凸多边形 ///已知点P,和参考点O,点O在多边形之外,如果OP与多边行的每个边有奇数个交点,那么P在多边形内部,否则,P在多边形外部 public static bool PointInsidePolygon(Vector2[] polyPoints, Vector2 point) { float xMin = 0; for (int i = 0; i < polyPoints.Length; i++) { xMin = Mathf.Min(xMin, polyPoints[i].x); } Vector2 origin = new Vector2(xMin - 0.1f, point.y); int intersections = 0; for (int i = 0; i < polyPoints.Length; i++) { Vector2 pA = polyPoints[i]; Vector2 pB = polyPoints[(i + 1) % polyPoints.Length]; if (GeomUtil.SegmentsCross(origin, point, pA, pB)) { intersections++; } } return((intersections & 1) == 1); }
public int CastAll(Vector3 direction, ICollection <RaycastHit> results, float distance, int layerMask, QueryTriggerInteraction query) { if (results == null) { throw new System.ArgumentNullException("results"); } using (var set = TempCollection.GetSet <RaycastHit>()) { foreach (var c in _colliders) { GeomUtil.GetGeom(c).CastAll(direction, set, distance, layerMask, query); } if (set.Count > 0) { var e = set.GetEnumerator(); while (e.MoveNext()) { results.Add(e.Current); } return(set.Count); } } return(0); }
/// <summary> /// 擬似半平面の作成 /// </summary> public ConvexPolygon Execute(Line line, Vector2 exsample) { //lineと各境界線の交差を調べる Vector2 p1 = Vector2.zero; bool i1 = border1.GetIntersectionPoint(line, ref p1); Vector2 p2 = Vector2.zero; bool i2 = border2.GetIntersectionPoint(line, ref p2); Vector2 p3 = Vector2.zero; bool i3 = border3.GetIntersectionPoint(line, ref p3); List <Vector2> vertices = new List <Vector2>(); //lineが境界線1及び2と交差する場合 if (i1 && i2 && Vector2.Distance(p1, p2) >= distanceThreshold) { //lineが境界線1及び2と交差する場合 if (GeomUtil.CCW(p1, boundary2, p2) * GeomUtil.CCW(p1, exsample, p2) > 0f) { //境界線2とexsampleがlineから見て同じ側にあるなら //境界点2を含む方の切断後頂点リストを生成 AddVertices(vertices, p1, boundary2, p2); } else { //境界点2を含まない方の切断後頂点リストを生成 AddVertices(vertices, p1, p2, boundary3, boundary1); } } else if (i2 && i3 && Vector2.Distance(p2, p3) >= distanceThreshold) { //lineが境界線2及び3と交差する場合 if (GeomUtil.CCW(p2, boundary3, p3) * GeomUtil.CCW(p2, exsample, p3) > 0f) { AddVertices(vertices, p2, boundary3, p3); } else { AddVertices(vertices, p2, p3, boundary1, boundary2); } } else if (i3 && i1 && Vector2.Distance(p3, p1) >= distanceThreshold) { //lineが境界線3及び1と交差する場合 if (GeomUtil.CCW(p3, boundary1, p1) * GeomUtil.CCW(p3, exsample, p1) > 0f) { AddVertices(vertices, p3, boundary1, p1); } else { AddVertices(vertices, p3, p1, boundary2, boundary3); } } else { throw new ArgumentException(); } //頂点リストから凸多角形を生成して返す return(new ConvexPolygon(vertices)); }
/// <summary> /// スプライトの更新 /// </summary> private void UpdateSprite() { if (!circle.Processing) { return; } if (!lerpSprite) { return; } //座標の調整 float centerAngle = (circle.NowEnd - circle.NowStart) * 0.5f + circle.NowStart; float radiusRange = (circle.NowOuter - circle.NowInner); float centerRadius = radiusRange * 0.5f + circle.NowInner; Vector3 pos = GeomUtil.DegToVector2(centerAngle) * centerRadius; pos.z = transform.localPosition.z - 1f; //lerpSpriteは自身のローカルにいること? lerpSprite.transform.localPosition = pos; //大きさの調整 if (adjustSpriteScale) { Vector2 size = lerpSprite.Target.sprite.bounds.size; float scale = radiusRange / size.magnitude; lerpSprite.transform.localScale = Vector2.one * (scale * adjustScale); } }
public override void DrawArc(double x1, double y1, double x2, double y2, double bulge) { if (thinlinemode != ThinLineModeFlag.OwnThinLines) { base.DrawArc(x1, y1, x2, y2, bulge); return; } stipplebit = 0x8000; int clipres = Clipper.ClipArc(x1, y1, x2, y2, bulge, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY); for (int idx = 0; idx < clipres; idx += 5) { int cx = GFXUtil.FloatToInt(clipbuffer[idx]), cy = GFXUtil.FloatToInt(clipbuffer[idx + 1]), nx, ny; GeomUtil.FlattenArc(clipbuffer[idx], clipbuffer[idx + 1], clipbuffer[idx + 2], clipbuffer[idx + 3], clipbuffer[idx + 4], false, flattentol, (x, y, moveto) => { nx = GFXUtil.FloatToInt(x); ny = GFXUtil.FloatToInt(y); Line_Internal(cx, cy, nx, ny, x2 == x && y2 == y); //set last point if last segment cx = nx; cy = ny; }); } }
/// <summary> /// Returns global bounds of this object /// </summary> public virtual Rect GetGlobalBounds() { Rect result; var bounds = GetInternalBounds(); GeomUtil.GetBounds(ref bounds, ref compositeMatrix, out result); return(result); }
public static bool CheckValueInSystem2Hidden(List <double> values, List <double> inputs) { if (GeomUtil.IsEqual(inputs[0] * values[0] + inputs[1] * values[1] + inputs[2], 0)) { return(true); } return(false); }
/// <summary> /// Transforms global rect to local /// </summary> public Rect GlobalToLocal(Rect rect) { Rect result; Matrix4x4 invMatrix; MatrixUtil.Inverse(ref compositeMatrix, out invMatrix); GeomUtil.GetBounds(ref rect, ref invMatrix, out result); return(result); }
private void Update() { Vector2 direction = lineEnd.position - lineStart.position; //GeomUtil.Ray2DIntersectCircle(lineStart.position, direction, circleCenter.position, radius, out m_intersection1, out m_intersection2); int intersectionCount = GeomUtil.LineSegmentIntersectCircle(lineStart.position, lineEnd.position, circleCenter.position, radius, out m_intersection1, out m_intersection2); Debug.Log("线段与圆交点的数量:" + intersectionCount); }
/// <summary> /// Returns bounds of this object in the parent container /// </summary> public virtual Rect GetLocalBounds() { Rect result; Matrix4x4 localMatrix; var bounds = GetInternalBounds(); MatrixUtil.Create2D(ref _scale, _rotation, ref _position, out localMatrix); GeomUtil.GetBounds(ref bounds, ref localMatrix, out result); return(result); }
public PosOri GetInterpPoint(float t) { var point = GetPoint(multiplier, length, t); var dir = GetTangent(multiplier, length, t); var upVector = -Vector3.Cross(dir, Vector3.forward); upVector = Vector3.up; var quat = GeomUtil.GetQuatFromDir(dir, upVector); return(new PosOri(point, quat)); }
public bool TestOverlap(int layerMask, QueryTriggerInteraction query) { foreach (var c in _colliders) { if (GeomUtil.GetGeom(c).TestOverlap(layerMask, query)) { return(true); } } return(false); }
public bool Cast(Vector3 direction, out RaycastHit hitinfo, float distance, int layerMask, QueryTriggerInteraction query) { foreach (var c in _colliders) { if (GeomUtil.GetGeom(c).Cast(direction, out hitinfo, distance, layerMask, query)) { return(true); } } hitinfo = default(RaycastHit); return(false); }
public PosOri GetInterpPoint(float t) { var point = GetPoint(rx, ry, t); var dir = GetTangent(rx, ry, t); var upVector = -Vector3.Cross(dir, Vector3.forward); var quat = GeomUtil.GetQuatFromDir(dir, upVector); //Quaternion.LookRotation(dir, Vector3.up); //if (t < 0.5f) // quat = Quaternion.LookRotation(dir, Vector3.down); return(new PosOri(point, quat)); }
public Autodesk.Revit.DB.Line drivingLine(Element wall) { LocationCurve lc = wall.Location as LocationCurve; Curve c = lc.Curve; Autodesk.Revit.DB.Parameter boP = wall.LookupParameter("Base Offset"); c = GeomUtil.OffsetCurve(c, XYZ.BasisZ, boP.AsDouble()); List <XYZ> ps = new List <XYZ> { c.GetEndPoint(0), c.GetEndPoint(1) }; ps.Sort(new ZYXComparer()); return(Autodesk.Revit.DB.Line.CreateBound(ps[0], ps[1])); }
/// <summary> 获取最近点的索引,如果点列表长度为0时,则返回-1。 </summary> private int GetClosestPointIndex() { int closestIndex = -1; Vector3[] vertices = TransformUtil.CovertTransformsToVertices(m_points); var polyLine = GeomUtil.GetClosestPolyLineToPoint(transform.position, vertices, m_isClosed);//获取距离当前点最近的边 if (polyLine.startIndex > -1 && polyLine.endIndex > -1) { closestIndex = m_isReverseOnStart ? polyLine.startIndex : polyLine.endIndex; } return(closestIndex); }
/// <summary> /// 初期化 /// </summary> private void Initialize(List <Vector2> points) { int size = points.Count; //角数が3未満の場合はエラー if (size < 3) { throw new ArgumentException(); } this.vertices = points; //凸性判定 float baseCCW = 0f; for (int i = 0; i < size; ++i) { Vector2 p0 = points[i]; Vector2 p1 = points[(i + 1) % size]; Vector2 p2 = points[(i + 2) % size]; //CCW値の計算 float ccw = GeomUtil.CCW(p0, p1, p2); if (baseCCW == 0f && ccw != 0f) { baseCCW = ccw; } if (ccw * baseCCW < 0) { throw new ArgumentException("Polygon is not convex."); } } if (baseCCW > 0f) { rotation = Rotation.CCW; } else { rotation = Rotation.CW; } //線分の登録 edges = new List <LineSegment>(); for (int i = 0; i < size; ++i) { Vector2 p1 = points[i]; Vector2 p2 = points[(i + 1) % size]; //p1の次の頂点 //2つ頂点から辺の線分を作成して登録 edges.Add(new LineSegment(p1, p2)); } }
/// <summary> /// 初期化 /// </summary> private void Initialize(List <Vector2> points) { int size = points.Count; //角数が3未満の場合はエラー if (size < 3) { throw new ArgumentException(); } //最も遠い座標のインデックスを求める int index = 0; float maxDistance = 0f; float distance = 0f; for (int i = 0; i < size; ++i) { distance = points[i].magnitude; if (distance > maxDistance) { maxDistance = distance; index = i; } } mostFarIndex = index; //最も遠い座標の外積を求める Vector2 p0 = points[(index + (size - 1)) % size]; Vector2 p1 = points[index]; Vector2 p2 = points[(index + 1) % size]; mostFarCross = GeomUtil.CCW(p0, p1, p2); //頂点リストの作成 vertices = new List <PolygonVertex>(); for (int i = 0; i < size; ++i) { p0 = points[(i + (size - 1)) % size]; p1 = points[i]; p2 = points[(i + 1) % size]; float cross = GeomUtil.CCW(p0, p1, p2); float angle = GeomUtil.TwoVectorAngle(p1, p0, p2); if (cross * mostFarCross < 0f) { angle = 360f - angle; } vertices.Add(new PolygonVertex(p1, angle, i)); } }
public override void DrawEllipticArc(double cx, double cy, double aradius, double bradius, double tilt, double startangle, double sweepangle) { if (thinlinemode != ThinLineModeFlag.OwnThinLines) { base.DrawEllipticArc(cx, cy, aradius, bradius, tilt, startangle, sweepangle); return; } /* stipplebit = 0x8000; * * int px=0,py=0,nx,ny; * bool first = true; * * GeomUtil.FlattenEllipticArc(cx, cy, aradius, bradius, tilt, startangle, sweepangle, flattentol, true, (x, y,moveto) => * { * nx = GFXUtil.RealToInt(x); * ny = GFXUtil.RealToInt(y); * if (!first) * Line_Internal(px, py, nx, ny, true); //TODO: can we skip last pixel except on last segment? * else * first = false; * * * px = nx; * py = ny; * });*/ int px = 0, py = 0, nx, ny; int num = Clipper.ClipEllipticArc(cx, cy, aradius, bradius, tilt, startangle, sweepangle, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY); for (int l = 0; l < num; l += 2) { stipplebit = 0x8000; GeomUtil.FlattenEllipticArc(cx, cy, aradius, bradius, tilt, clipbuffer[l], clipbuffer[l + 1] - clipbuffer[l], flattentol, true, (x, y, moveto) => { nx = GFXUtil.FloatToInt(x); ny = GFXUtil.FloatToInt(y); if (!moveto) { Line_Internal(px, py, nx, ny, true); //TODO: can we skip last pixel except on last segment? } px = nx; py = ny; }); } }
public List <Vector3> Generate(float multiplier, float length, Vector3 pos, Quaternion rot, int segments) { var verts = new List <Vector2>(); float stepSize = length / segments; for (int i = 0; i < segments; i++) { float x = i * stepSize; float y = amplitude * Mathf.Sin(2 * multiplier * i * stepSize * Mathf.PI); verts.Add(new Vector2(x, y)); } return(GeomUtil.GetTFVerts(verts.ToArray(), pos, rot)); }
public List <Vector3> Generate(float rx, float ry, Vector3 pos, Quaternion rot, int segments) { var verts = new List <Vector2>(); float stepSize = 2 * Mathf.PI / segments; for (int i = 0; i < segments; i++) { float x = rx * Mathf.Cos(i * stepSize); float y = ry * Mathf.Sin(i * stepSize); verts.Add(new Vector2(x, y)); } return(GeomUtil.GetTFVerts(verts.ToArray(), pos, rot)); }
void Update() { //bool intersect = GeomUtil.GetTwoLineIntersection(lineStart1.position,lineEnd1.position, lineStart2.position, lineEnd2.position, out Vector3 intersectionPoint, out float t1, out float t2); bool intersect = GeomUtil.GetTwoLineSegmentsIntersection(lineStart1.position, lineEnd1.position, lineStart2.position, lineEnd2.position, out Vector3 intersectionPoint, out float t1, out float t2); if (intersect) { intersection.position = intersectionPoint; Debug.Log($"t1:{t1}, t2:{t2}"); } else { intersection.position = Vector3.zero; } }