c# - 线条形状看起来很奇怪
问题描述
上次我问如何在不使用线条渲染器的情况下绘制线条,我自己找到了答案
但是当我完成编码时,线条的角度增加了,线条呈现出斜面形状。
(以下 2 行比较)
这张图是我画线的概念。
我错了什么?
我的主要代码是
public class MyUILineRenderer : Graphic{
public Vector3[] pointPos;
public float[] angles;
public MyUIGridRenderer gridRenderer;
public Vector2Int gridSize = new Vector2Int(1, 1);
public float lineThickness = 0.5f;
public float width;
public float height;
public float unitWidth;
public float unitHeight;
public List<Vector3> edgePos;
public List<Vector3> segmentPos = new List<Vector3>();
protected override void OnPopulateMesh(VertexHelper vh)
vh.Clear();
edgePos.Clear();
segmentPos.Clear();
width = rectTransform.rect.width;
height = rectTransform.rect.height;
unitWidth = width / (float)gridSize.x;
unitHeight = height / (float)gridSize.y;
if (calAngle)
{
angles = new float[pointPos.Length];
}
//case of point count less than 2
if (pointPos.Length < 2)
{
return;
}
//Get Edge Points
for (int i = 0; i < pointPos.Length - 1; i++)
{
int index = i * 4;
GetEdgePoint(vh, pointPos[i], pointPos[i + 1], index);
}
//Get segment points
GetSegmentPoint(vh);
//draw line with segment points
int count = pointPos.Length * 2 - 2;
for (int i = 0; i < count; i += 2)
{
vh.AddTriangle(i + 0, i + 1, i + 3);
vh.AddTriangle(i + 0, i + 2, i + 3);
}
}
}
我从这段代码中得到边缘点
private void GetEdgePoint(VertexHelper vh, Vector3 point, Vector3 nextPoint, int i)
{
UIVertex vertex = UIVertex.simpleVert;
//vertex.color = color;
//Calculate grid size to screen size
Vector3 pos = new Vector3(unitWidth * point.x, unitHeight * point.y);
Vector3 nextpos = new Vector3(unitWidth * nextPoint.x, unitHeight * nextPoint.y);
Vector3 normal = Vector3.Cross(pos, nextpos);
Vector3 side = Vector3.Cross(normal, nextpos - pos);
side.Normalize();
//get edge Point (4 points)
vertex.position = pos + side * (lineThickness);
edgePos.Add(vertex.position);
vertex.position = pos + side * (-lineThickness);
edgePos.Add(vertex.position);
vertex.position = nextpos + side * (lineThickness);
edgePos.Add(vertex.position);
vertex.position = nextpos + side * (-lineThickness);
edgePos.Add(vertex.position);
}
获取分段点代码
private void GetSegmentPoint(VertexHelper vh)
{
UIVertex vertex = UIVertex.simpleVert;
vertex.color = color;
segmentPos.Add(edgePos[0]);
vertex.position = edgePos[0];
vh.AddVert(vertex);
segmentPos.Add(edgePos[1]);
vertex.position = edgePos[1];
vh.AddVert(vertex);
//Get segment points
if (pointPos.Length > 2)
{
int index = 0;
for (int i = 0; i < pointPos.Length - 2; i++)
{
Vector3 vec = Vector3.zero;
if (MyMath.LineLineIntersection(out vec, edgePos[index], edgePos[index + 2] - edgePos[index], edgePos[index + 6], edgePos[index + 4] - edgePos[index + 6]))
{
segmentPos.Add(vec);
vertex.position = vec;
vh.AddVert(vertex);
}
else
{
vec = vertex.position = edgePos[index + 3] + (edgePos[index + 5] - edgePos[index + 3]) / 2;
segmentPos.Add(vec);
vh.AddVert(vertex);
Debug.Log(index + " up");
}
if (MyMath.LineLineIntersection(out vec, edgePos[index + 1], edgePos[index + 3] - edgePos[index + 1], edgePos[index + 7], edgePos[index + 5] - edgePos[index + 7]))
{
segmentPos.Add(vec);
vertex.position = vec;
vh.AddVert(vertex);
}
else
{
vec = vertex.position = edgePos[index + 2] + (edgePos[index + 4] - edgePos[index + 2]) / 2;
segmentPos.Add(vec);
vh.AddVert(vertex);
Debug.Log(index + " down");
}
index += 4;
}
}
//Set last edge points to segment points
segmentPos.Add(edgePos[edgePos.Count - 2]);
vertex.position = edgePos[edgePos.Count - 2];
vh.AddVert(vertex);
segmentPos.Add(edgePos[edgePos.Count - 1]);
vertex.position = edgePos[edgePos.Count - 1];
vh.AddVert(vertex);
}
从边缘点代码计算线交点
public static bool LineIntersection(Vector3 a, Vector3 b, Vector3 c, Vector3 d, out Vector3 x)
{
Vector3 lineVec3 = c - a;
Vector3 vec1 = b - a;
Vector3 vec2 = d - c;
//Vector3 lineVec3 = linePoint2 - linePoint1;
Vector3 crossVec1and2 = Vector3.Cross(vec1, vec2);
Vector3 crossVec3and2 = Vector3.Cross(lineVec3, vec2);
float det = Vector3.Dot(lineVec3, crossVec1and2);
//두선이 평행인 경우
if (Mathf.Abs(det) < 0.0001f)
{
x = Vector3.zero;
return false;
}
x = a + (vec1 * (Vector3.Dot(crossVec3and2, crossVec1and2) / crossVec1and2.sqrMagnitude));
return true;
}
解决方案
如果您准备好缓冲区,为什么要混合线条和顶点?
//draw line with segment points
for (int i = 0; i < vh.currentVertCount; i += 4)
{
vh.AddTriangle(i + 0, i + 1, i + 3);
vh.AddTriangle(i + 0, i + 2, i + 3);
}
推荐阅读
- database - ef 核心回滚中的 savechanges() 异常是否在上下文中更改?
- abap - 我不明白 READ TABLE inside LOOP 是如何工作的
- ios - 取消循环外的 DispatchWorkItem - Swift
- c# - 处理 DispatcherTimer.Tick 方法时出错
- c++ - Ncurses 表单中的字段验证存在问题
- azure - 在 Azure 数据工厂中根据文件名创建文件夹
- python - 在另一个数组的特定列中查找数组的最近元素
- python - Web2py SmartGrid 显示每个用户的数据
- android - 每行弹性盒布局的最大项目数
- reactjs - 状态改变时我的组件没有重新加载有什么解决办法吗