public static bool IsOn(this Vertex v0, Vertex v1, Vertex v2) { return(CGAlgorithm.IsOn( new Vector2(( float )v0.x, ( float )v0.y), new Vector2(( float )v1.x, ( float )v1.y), new Vector2(( float )v2.x, ( float )v2.y) )); }
public static List <Vector2> Combine(List <Vector2> exVertices, List <List <Vector2> > inPolygons) { // inP.Clear(); // exP.Clear(); List <Vector2> inP = new List <Vector2>(); List <Vector2> exP = new List <Vector2>(); //List<Vector2> exVertices = new List<Vector2>(tree.exterior.vertices);//new List<Vector2>(poly.exteriorRing.vertices); // List<Polygon> inPolygons = new List<Polygon>(tree.interiors); // List<Vector2> inVertices = new List<Vector2>(); // foreach(Polygon poly in inPolygons){ // inVertices.AddRange(poly.vertices); // } while (inPolygons.Count > 0) { Vector2 inVertex = inPolygons[0][0]; int index = 0; for (int i = 0; i < inPolygons.Count; i++) { if (GetRightMostVertex(inPolygons[i], ref inVertex)) { index = i; } } Intersection inter = Intersection.none; if (CGAlgorithm.SegmentSkewPoly(inVertex, inVertex + RIGHT_DISTANCE, exVertices, ref inter)) { if (inter.Type == PointType.ON_EDGE) { exVertices.Insert(inter.EdgeEndIndex, inter.Point0); } Combine(ref exVertices, ref inP, ref exP, inPolygons[index], inter.Point0, inVertex); } else { //Debug.LogError("The " + index +" interior polygon cannot combine to exterior polygon !"); } inPolygons.RemoveAt(index); } if (!ForceEarCut.AreVerticesClockwise(exVertices, 0, exVertices.Count)) { exVertices.Reverse(); } return(exVertices); }
private Vector3 [] RecalculateVerticesByCurve(TriangleNet.Mesh mesh, AnimationCurve curve, float factor = Mathf.PI) // 3.1415926f ) { int size = mesh.vertices.Count; //求各点距边最近距离; float[] nearests = new float[size]; float furthest = float.MinValue; for (int i = 0; i < size; i++) { var point = mesh.vertices[i]; nearests [i] = 0; if (point.label == 0) { nearests [i] = float.MaxValue; foreach (var edge in mesh.Edges.Where(e => e.Label != 0)) { var v0 = mesh.vertices[edge.P0]; var v1 = mesh.vertices[edge.P1]; Vector2 position;// = Vector3.zero; float distance = CGAlgorithm.PointToSegementDistance(point.Vector2(), v0.Vector2(), v1.Vector2(), out position); //Debug.Log ( "Distance : " + distance ); if (distance < nearests [i]) { nearests [i] = distance; } if (distance > furthest) { furthest = distance; } } } } // 用 y = sqrt{1- (1-x )^2} 函数计算各点的Z值; Vector3[] result = new Vector3[size]; var average = nearests.Average(); for (int j = 0; j < size; j++) { var point = mesh.vertices[j]; Vector3 pos = point.Vector2(); var t = 1f - nearests[j] / furthest; pos.z = -Mathf.Sqrt(1f - t * t) * average * factor; //var t = nearests[j] / furthest; //pos.z = - curve.Evaluate(t) * average * factor; result [j] = pos; } return(result); }
public override void Execute( ) { var pointView = evt.data as PointView; var polyView = pointView.poly; var polyEntity = lookup.libs[polyView]; int count = polyEntity.Points.Count; if (count <= 3) { return; } var index = polyView.points.IndexOf(pointView); var preIndex = (count + index - 1) % count; var nextIndex = (index + 1) % count; //Calc new curve position var point_0 = polyEntity.Points[preIndex]; var point_1 = polyEntity.Points[index]; var point_2 = polyEntity.Points[nextIndex]; var p0 = point_0.position; var p1 = point_1.position; var p2 = point_2.position; var h0 = Bezier.CalcHandler(p0, p1, point_0.curvePosition); var h1 = Bezier.CalcHandler(p1, p2, point_1.curvePosition); var newCurvePos = (h0 + h1) * 0.5f; Vector2 skew = (Vector2)newCurvePos; if (CGAlgorithm.Intersect2D_2SkewSegments(p0, h0, p2, h1, ref skew)) { var cIsLeft = Mathf.Sign(CGAlgorithm.IsLeft(p0, p2, p1)); var sIsLeft = Mathf.Sign(CGAlgorithm.IsLeft(p0, p2, skew)); if (cIsLeft * sIsLeft > 0) { newCurvePos = Bezier.CalcCurve(p0, p2, ( Vector3 )skew); } } var pointEntity = polyEntity.Points[index]; var lineView = polyView.lines[index]; var preLine = polyView.lines[preIndex]; var nextPoint = polyView.points[nextIndex]; preLine.endPoint = nextPoint; preLine.curvePosition = newCurvePos;// pointEntity.position; preLine.OnRender( ); pointView.OnRecycle( ); lineView.OnRecycle( ); polyView.points.Remove(pointView); polyView.lines.Remove(lineView); //polyEntity.Points [ preIndex ].isCurve = true; polyEntity.Points [preIndex].curvePosition = newCurvePos; // pointEntity.position; polyEntity.Points.RemoveAt(index); }
void HandleOnUpdateCurve( ) { var count = Mathf.Ceil(1 / curveDetail); //Build the curve var handler = Bezier.CalcHandler(startPosition, endPosition, curvePosition);; //var handler = curvePosition;// //Bezier.Control(startPosition, endPosition, curvePosition); var center = Bezier.Square(startPosition, endPosition, handler, 0.5F); //centerPosition = new Vector3 ( center.x, center.y, 0 ); var vertices = new List <Vector3>(); var triangles = new List <int>(); var uv = new List <Vector2>(); var normals = new List <Vector3>(); var tangents = new List <Vector4>(); float UVX = 0F; Vector2 I0, I1, I2, I3; for (int i = 0; i < count; i++) { var pre = Bezier.Square(startPosition, endPosition, handler, (float)(i - 1) / count); var cur = Bezier.Square(startPosition, endPosition, handler, (float)i / count); var next = Bezier.Square(startPosition, endPosition, handler, (float)(i + 1) / count); var preTegent = cur - pre; var nextTegent = next - cur; var normal = Vector3.back; var preBinormal = Vector3.zero; var nextBinormal = Vector3.zero; Vector3.OrthoNormalize(ref normal, ref preTegent, ref preBinormal); Vector3.OrthoNormalize(ref normal, ref nextTegent, ref nextBinormal); var preOffset = width * 0.5F * preBinormal; var nextOffset = width * 0.5F * nextBinormal; var p0 = pre + preOffset; // (Vector2)(pre + preOffset); var p1 = cur + preOffset; // (Vector2) (cur + preOffset); var p2 = cur + nextOffset; // (Vector2) (cur + nextOffset); var p3 = next + nextOffset; // (Vector2) (next + nextOffset); var p4 = pre - preOffset; // (Vector2) (pre - preOffset); var p5 = cur - preOffset; // (Vector2) (cur - preOffset); var p6 = cur - nextOffset; // (Vector2) (cur - nextOffset); var p7 = next - nextOffset; // (Vector2) (next - nextOffset); var preLength = Vector3.Distance(cur, pre); var nextLength = Vector3.Distance(next, cur); int size = vertices.Count; if (size != 0 && CGAlgorithm.Intersect2D_2Segments(p0, p1, p2, p3, out I0, out I1) > 0) { int interIndex = size - 2; vertices [interIndex] = I0; vertices.AddRange(new Vector3 [] { p6, I0, p3, p7 }); triangles.AddRange(new int [] { size, size + 2, size + 1, size, size + 3, size + 2, size - 1, size, interIndex }); } else if (size != 0 && CGAlgorithm.Intersect2D_2Segments(p4, p5, p6, p7, out I2, out I3) > 0) { int interIndex = size - 1; vertices [interIndex] = I2; vertices.AddRange(new Vector3 [] { I2, p2, p3, p7 }); triangles.AddRange(new int [] { size, size + 2, size + 1, size, size + 3, size + 2, interIndex, size + 1, size - 2 }); } else { vertices.AddRange(new Vector3 [] { p6, p2, p3, p7 }); triangles.AddRange(new int [] { size, size + 2, size + 1, size, size + 3, size + 2 }); } var preUVX = UVX; UVX += nextLength / width; uv.AddRange(new Vector2 [] { new Vector2(preUVX, 0), new Vector2(preUVX, 1), new Vector2(UVX, 1), new Vector2(UVX, 0) }); normals.AddRange(new Vector3 [] { Vector3.back, Vector3.back, Vector3.back, Vector3.back }); tangents.AddRange(new Vector4 [] { new Vector4(-1, 0, 0, -1), new Vector4(-1, 0, 0, -1), new Vector4(-1, 0, 0, -1), new Vector4(-1, 0, 0, -1) }); } Vertices = vertices.ToArray( ); Triangles = triangles.ToArray( ); UV = uv.ToArray( ); Normals = normals.ToArray( ); Tangents = tangents.ToArray( ); }
public static bool Operate(List <Vector2> subjPoly, List <Vector2> operPoly, out List <Vector2> result, OPERATION operation = OPERATION.OR) { result = new List <Vector2>(); int sn = subjPoly.Count; int on = operPoly.Count; if (!ForceEarCut.AreVerticesClockwise(subjPoly, 0, sn)) { subjPoly.Reverse(); } //当union == UNION.NOT时,operPoly 应该是逆时针方向。 if (operation == OPERATION.NOT) { if (ForceEarCut.AreVerticesClockwise(operPoly, 0, on)) { operPoly.Reverse(); } } else { if (!ForceEarCut.AreVerticesClockwise(operPoly, 0, on)) { operPoly.Reverse(); } } List <VertexNode> entering = new List <VertexNode>(); List <VertexNode> subjList = new List <VertexNode>(); List <VertexNode> operList = new List <VertexNode>(); VertexNode.FillNodeList(subjList, subjPoly); VertexNode.FillNodeList(operList, operPoly); int oi, oj, si, sj; InterFactor factor; // = InterFactor.none; for (si = 0, sj = sn - 1; si < sn; sj = si++) { for (oi = 0, oj = on - 1; oi < on; oj = oi++) { int nInter = CGAlgorithm.IntersectFactor(subjPoly[sj], subjPoly[si], operPoly[oj], operPoly[oi], out factor); if (nInter == 1) { VertexNode subjNode = new VertexNode(subjList, sj, subjPoly, factor.t, factor.inbound); VertexNode operNode = new VertexNode(operList, oj, operPoly, factor.u, factor.inbound); subjNode.Other = operNode; subjList.Add(subjNode); operList.Add(operNode); if (operation == OPERATION.NOT) { if (!factor.inbound) { entering.Add(operNode); } } else if (operation == OPERATION.OR) { if (factor.inbound) { entering.Add(operNode); } } else if (operation == OPERATION.AND) { if (factor.inbound) { entering.Add(subjNode); } } } } } if (entering.Count == 0) { return(false); } subjList.Sort(); operList.Sort(); while (entering.Count > 0) { VertexNode nextNode = entering[0]; entering.RemoveAt(0); VertexNode startNode = nextNode; result.Add(nextNode.Vlaue); nextNode = nextNode.Next; while (nextNode != startNode && nextNode.Other != startNode) { result.Add(nextNode.Vlaue); if (nextNode.Kind == VerType.Intersection) { if (nextNode.inbound) { if (entering.Contains(nextNode)) { entering.Remove(nextNode); } else if (entering.Contains(nextNode.Other)) { entering.Remove(nextNode.Other); } } nextNode = nextNode.Other.Next; } else { nextNode = nextNode.Next; } } } return(true); }
public void CalculateBevelOutline(List <Vector2> vertices, float strokeWidth, ref List <Vector3> verts, ref List <Vector2> uvs, ref List <int> tris) { int n = vertices.Count; int initIndex = verts.Count; int i = 0; int vertNum = initIndex; float pFactor = 0, nFactor = 0; Vector2 pVer = vertices[n - 1]; Vector2 cVer = vertices[0]; Vector2 nVer = vertices[1]; float pDis = Vector2.Distance(pVer, cVer); float nDis; // = Vector2.Distance(cVer, nVer); // int sign = ForceEarCut.ComputeSpannedAreaSign(pVer, cVer, nVer); Vector2 firstSkewPoint = pVer; Debug.LogError(gameObject.name + " is going on to enter while ... ! "); while (i < n + 1) { nDis = Vector2.Distance(cVer, nVer); if (nDis < strokeWidth) { pDis = Vector2.Distance(pVer, nVer); i++; // cVer = nVer; nVer = vertices[i % n]; continue; } pFactor = pDis / strokeWidth; nFactor = nDis / strokeWidth; Vector2 perPC = CGAlgorithm.Perp(pVer, cVer, strokeWidth); Vector2 perCN = CGAlgorithm.Perp(cVer, nVer, strokeWidth); int sign = ForceEarCut.ComputeSpannedAreaSign(pVer, cVer, nVer); if (sign < 0) { // sign < 0 : // p // \ // \ // === c --> n === Vector2 skewPoint = cVer + perPC; //CGAlgorithm.Intersect2D_2SkewSegments(pVer + perPC, cVer + perPC , cVer + perCN, nVer + perCN, ref skewPoint) ; if (CGAlgorithm.Intersect2D_2SkewSegments(pVer + perPC, cVer + perPC, cVer + perCN, nVer + perCN, ref skewPoint)) { if (vertNum > initIndex) { verts[vertNum - 1] = skewPoint; } verts.Add(pVer); verts.Add(skewPoint); verts.Add(cVer); verts.Add(nVer + perCN); uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(1, pFactor)); uvs.Add(new Vector2(0, pFactor)); uvs.Add(new Vector2(1, pFactor + nFactor)); if (_facing == Facing.FACE_FORWARD) { tris.Add(vertNum); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 3); tris.Add(vertNum + 1); } else if (_facing == Facing.FACE_BACK) { tris.Add(vertNum); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 3); } vertNum += 4; } } else { // or sign > 0 : // p // / // / // === n <-- c === // // }else{ //--------------------------------------------------------------------------- verts.Add(pVer); verts.Add(cVer + perPC); verts.Add(cVer); verts.Add(cVer + perCN); verts.Add(nVer + perCN); uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(1, pFactor)); uvs.Add(new Vector2(0, pFactor)); uvs.Add(new Vector2(1, pFactor)); uvs.Add(new Vector2(1, pFactor + nFactor)); if (_facing == Facing.FACE_FORWARD) { tris.Add(vertNum); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 3); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 4); tris.Add(vertNum + 3); } else if (_facing == Facing.FACE_BACK) { tris.Add(vertNum); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 3); tris.Add(vertNum + 2); tris.Add(vertNum + 3); tris.Add(vertNum + 4); } vertNum += 5; } i++; pVer = cVer; cVer = nVer; nVer = vertices[i % n]; pDis = nDis; } }
public void CalculateMeshData(List <Vector2> vertices, float strokeWidth, ref List <Vector3> verts, ref List <Vector2> uvs, ref List <int> tris) { int n = vertices.Count; int initIndex = verts.Count; int i = 0; int vertNum = initIndex; float pFactor = 0, nFactor = 0; Vector2 pVer = vertices[n - 1]; Vector2 cVer = vertices[0]; Vector2 nVer = vertices[1]; float pDis = Vector2.Distance(pVer, cVer); float nDis; // = Vector2.Distance(cVer, nVer); // int sign = ForceEarCut.ComputeSpannedAreaSign(pVer, cVer, nVer); Vector2 firstSkewPoint = pVer; while (i < n + 1) { nDis = Vector2.Distance(cVer, nVer); if (nDis < strokeWidth) { pDis = Vector2.Distance(pVer, nVer); i++; // cVer = nVer; nVer = vertices[i % n]; continue; } pFactor = pDis / strokeWidth; nFactor = nDis / strokeWidth; Vector2 perPC = CGAlgorithm.Perp(pVer, cVer, strokeWidth); Vector2 perCN = CGAlgorithm.Perp(cVer, nVer, strokeWidth); Vector2 skewPoint = cVer + perPC; //CGAlgorithm.Intersect2D_2SkewSegments(pVer + perPC, cVer + perPC , cVer + perCN, nVer + perCN, ref skewPoint) ; Vector2 pcDir = (cVer - pVer).normalized * strokeWidth * 5; Vector2 cnDir = (cVer - nVer).normalized * strokeWidth * 5; if (CGAlgorithm.Intersect2D_2SkewSegments( pVer + perPC, cVer + perPC + pcDir, cVer + perCN + cnDir, nVer + perCN, ref skewPoint)) { if (vertNum == initIndex) { firstSkewPoint = skewPoint; } else { verts[vertNum - 1] = skewPoint; } verts.Add(pVer); verts.Add(skewPoint); verts.Add(cVer); if (i == n) { verts.Add(firstSkewPoint); } else { verts.Add(nVer); //(nVer + perCN); } uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(1, pFactor)); uvs.Add(new Vector2(0, pFactor)); uvs.Add(new Vector2(1, pFactor + nFactor)); if (_facing == Facing.FACE_FORWARD) { tris.Add(vertNum); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 3); tris.Add(vertNum + 1); } else if (_facing == Facing.FACE_BACK) { tris.Add(vertNum); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 3); } vertNum += 4; } else { Debug.LogError("Outline .... no intersect???"); } i++; pVer = cVer; cVer = nVer; nVer = vertices[i % n]; pDis = nDis; } }
// public PolyMesh Area{set; get;} public bool Contans(Vector3 v) { Vector3 p = (transform.parent.localToWorldMatrix * transform.worldToLocalMatrix).MultiplyPoint3x4(v); return(CGAlgorithm.WN_PnPoly(p, GetComponentInChildren <PolyMesh>().GetEdgePoints())); }