动态创建一个点数组

3
我想使用graphics.DrawCurve绘制曲线,我有分别存储在数组中的x和y值(float x[]float y[])。由于DrawCurve需要点阵列作为输入,因此我需要从浮点数数组x和y转换或动态创建点阵列。有没有什么快速的方法可以做到这一点?
我有大约20000个点要绘制曲线,使用graphics.DrawCurve是否是个好主意?

1
唯一的方法是将这两个数组合并在一起,但是你不是最好从一开始就用一个点列表吗?你尝试过什么? - Sayse
到目前为止,除了搜索之外,我还没有尝试过任何东西。我尝试应用的是首先分配点数组,并在循环中动态收集分配的点数组中的x和y值。但是,到目前为止,我还没有找到如何分配点数组的方法。(为什么会有负投票??) - Lati
1
你是否在寻找 Zip (LINQ)?- 例如(未经测试):xArray.Zip(yArray, (x, y) => (new Point(x,y))).ToArray() - Corak
你到目前为止研究了什么,哪些方法没有奏效?展示一下你尝试过的东西,downvote是因为你没有展示任何研究/努力。 - Sayse
哦,太棒了!所以花上半天时间在谷歌上搜寻问题,并尝试不同的编程组合并不能算作一种努力。下次我会倒立着在谷歌上搜索,以展示我真正为解决问题付出了努力。另一个问题是很难将数组指针和指向数组的指针在搜索结果中区分开来;虽然有足够多的问题和答案提到了数组指针。 - Lati
3个回答

7

有几个问题需要回答。

我找不到如何分配一个点数组。

嗯,分配一个点数组和为任何其他类型的数组分配没有区别:

const int size = 100;
Point[] pointArray = new Point[size];

但是数组缺少一些“便利”。例如,它们具有在初始化(分配)点需要指定的固定大小。如果您需要更多空间,则必须手动创建一个新的(更大的)数组,并将所有值从旧数组复制到新数组。

这就是为什么几乎无论何时您使用数组,您可能最好使用列表:

List<Point> pointList = new List<Point>();

随后,你需要传递一个数组的地方,你可以通过以下方式简单获取:

Point[] pointArray = pointList.ToArray();

动态收集分配点数组中的x和y值。

当你使用列表时,这样做很容易:

pointList.Add(new Point(x, y));

我们不知道您如何填写float x[]float y[]。如果可能的话,我一开始就不会有这两个单独的数组,而是直接使用pointList。但有一个例外:System.Drawing.Point只能使用int值,而不能使用float值。因此,我假设您想收集坐标的int值。

从浮点数数组x和y动态创建点数组

如果您无法更改坐标的收集方式,并且必须使用这些数组进行工作,您可以像这样将它们“压缩”在一起:

IEnumerable<Point> points = x.Zip(y, (xCoord, yCoord) => 
    (new Point((int)xCoord, (int)yCoord));

或者,如果您知道您需要一个数组:

Point[] pointArray = x.Zip(y, (xCoord, yCoord) => 
    (new Point((int)xCoord, (int)yCoord)).ToArray();

为此,您需要能够使用System.Linq(换句话说,高于.Net 2.0)。

如果您无法使用Linq,则必须手动完成。类似于:

int size = Math.Min(x.Length, y.Length);
Point[] pointArray = new Point[size];

for (int index = 0; index < size; index++)
{
  pointArray[index] = new Point((int)x[index], (int)y[index]);
}

非常感谢您提供详细的答案和讨论。我确实有浮点数,并使用以下循环:PointF[] pointArray = new PointF[500]; for(int i = 0; i < 500; i++){ pointArray[i] = new PointF((float)yPoints[i], (float)xPoints[i]); }然而,创建列表并将点添加到该列表无法与Graphics.DrawCurve一起使用。我确实有x轴上的浮点值,并且实际上它与Graphics.DrawCurve很好地配合使用。我还没有尝试Linq解决方案,当我比较这些解决方案的运行时,我会编辑此响应。 - Lati
啊,好的,那么请将我答案中的每个“Point”更改为“PointF”,删除“(int)”转换,并忘记我关于需要“int”的写法 ^_^。我不太明白你所说的“创建列表并将点添加到列表中无法使用Graphics.DrawCurve”的意思。你是否遇到了异常或编译错误?“无法工作”可能意味着任何事情。-- 你是否缺少Graphics.DrawCurve所需的其他参数之一? - Corak
很遗憾,评论框只能输入600个字符,所以我无法详细说明。当我使用以下代码时: 'List<PointF> pointArray = new List<PointF>(); for(int i = 0; i < 500; i++){ pointArray.Add(new PointF((float)yPoints[i], (float)xPoints[i])); } g.DrawCurve(pen, pointArray, 1F);' 我得到了以下错误(错误4 参数2:无法将'System.Collections.Generic.List<System.Drawing.PointF>'转换为'System.Drawing.PointF[]')。 - Lati
是的,这就是我所说的“然后,在您实际需要传递数组的任何地方,您可以通过以下方式轻松获取它:Point[] pointArray = pointList.ToArray();”-- 所以在您的情况下,您需要编写:g.DrawCurve(pen, pointArray.ToArray(), 1F); - Corak

2
您可以创建 List<Point>,它比数组更好。
List<Point> list = new List<Point>();
Point point=new Point(10,15);
list.Add(point);

你可以从两个数组中获取所有的x和y坐标,并将它们组合成点列表,然后使用该列表绘制曲线。

1
这并没有真正回答问题。 - Sayse
1
那实际上回答了问题。然而,Corak提供的解决方案更详细,更好地讨论了这个问题。无论如何,谢谢! - Lati

1

假设两个数组中的值具有相同的索引,您可以遍历它们,创建点并将它们添加到列表中。

List<Point> points = new List<Point>();
for(int i = 0; i < x.Length; i++){
    points.Add(new Point(x[i],y[i]);
}

我认为在这里使用DrawCurve没有什么特别的问题。

如果你需要一个点数组,请使用points.ToArray();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接