晚上好,我在网上知道有类似的问题和一些关于它的教程,但我希望你检查我的代码并更正它。我的意思是,我想知道我的项目有什么问题。 我必须在主面板上绘制一个抛物线图。 我还必须包括两个按钮,放大和缩小,用于缩小和放大"视图"小组的观点(以及抛物线)。 我被建议使用scale var。 这是我的代码:
注意:x0,y0是panel_main x center,y center 我有x,y用于从等式中确定x,y xpc,ypc被转换为窗口比例(像素也是如此) xmin,xmax是具有一定比例的极值,留在面板上
我希望你能给我一个提示,非常感谢!
public void DisegnaParabola()
{
Graphics gs = panel_main.CreateGraphics();
pen.Color = Color.Black;
scale = (x0*2) / zoom; //Pixels equivalent to 1x or 1y
n_punti = (x0*2) / scale; //Number of x math points that are visible in window
xmin = -(n_punti / 2);
xmax = n_punti / 2;
precision = 1 / scale; //Increment of x to have 1px
if (asse_parabola.SelectedIndex == 0) //if Y axis
{
for (double i = xmin + precision; i < xmax; i += precision)
{
rifx = i - precision; //Old points
rifxpc = rifx * scale;
rify = (a * Math.Pow(rifx, 2)) + b * rifx + c;
rifypc = y0 - (rify * scale);
x = i; //New points
y = (a * Math.Pow(x, 2)) + b * x + c;
ypc = y0 - (y * scale);
gs.DrawLine(pen, (float)rifxpc, (float)rifypc, (float)xpc, (float)ypc);
}
}
else
{
scale = (y0*2) / zoom; //Pixels for 1y
n_punti = (y0*2) / scale; //Numbers of y in the window
ymin = -(n_punti / 2);
ymax = n_punti / 2;
for(double i=ymin+precision; i<ymax; i+=precision)
{
rify = y - precision;
rifypc = (y0*2) - rify * scale;
rifx = (a * Math.Pow(rify, 2)) + b * rify + c;
rifxpc = x0 + (rifx * scale);
y = i;
x = (a * Math.Pow(y, 2)) + b * y + c;
xpc = x0 + (x * scale);
gs.DrawLine(pen, (float)rifypc, (float)rifxpc, (float)ypc, (float)xpc);
}
}
lbl_canc.Visible = true;
}
答案 0 :(得分:0)
你的问题实际上包含了几个任务,而且通常关键是将这些任务分开......
有一个问题是获取数据,我会将详细信息留给您,但会展示如何从其余部分中提取数据。
下一个问题是缩放数据。我将向您展示如何完全避免使用此工具并改为使用绘图工具。
第三个是将它们绘制到显示表面。正如您所知,一旦其他问题得到解决,这一点非常简单。
让我们从最重要的一步开始:收集数据。您尝试在同一段代码中创建并缩放和绘制它们。这有很多缺点..
让我们首先以合适的结构收集数据:
List<PointF> points = new List<PointF>();
List<T>
是大部分时间的选择集合;肯定比阵列好多了!在某些方法中,您应该使用从某个公式计算的数据填充该列表。
以下是一个例子:
List<PointF> getPoints(float start, float end, int count, float ymax)
{
List<PointF> points = new List<PointF>();
float deltaX = (end - start) / count;
for (int i = 0; i < count; i++)
{
float x = i * deltaX;
// insert your own formula(s) here!
float y = ymax + (float)Math.Sin(x * somefactor) * ymax;
points.Add(new PointF(x, y));
}
return points;
}
现在是第二个重要部分:如何扩展数据?这可以在创建它们时完成;但同样,将两个分开,使它们变得更加简单。
因此,这是一个函数,它不是缩放数据,而是用于绘制它们的Graphics
对象:
void ScaleGraphics(Graphics g, List<PointF> data)
{
float xmax = data.Select(x => x.X).Max();
float ymax = data.Select(x => x.Y).Max();
float xmin = data.Select(x => x.X).Min();
float ymin = data.Select(x => x.Y).Min();
float width = Math.Abs(xmax - xmin);
float height = Math.Abs(ymax - ymin);
var vr = g.VisibleClipBounds;
g.ScaleTransform(vr.Width / width, vr.Height / height);
}
此方法可确保列表中的所有数据都适合绘图表面。如果要将它们限制为不同的大小,可以将其传入并相应地更改代码。
最后我们需要做实际绘图。我们应该在我们应该的地方,也就是在我们的绘图表面控制的Paint
事件中......:
private void panel1_Paint(object sender, PaintEventArgs e)
{
if (points.Count < 2) return; // no lines to draw, yet
ScaleGraphics(e.Graphics, points);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using ( Pen pen = new Pen(Color.Blue )
{ Width = 1.5f , LineJoin = LineJoin.Round, MiterLimit = 1f} )
e.Graphics.DrawLines(pen, points.ToArray());
}