日期:2014-05-17  浏览次数:20900 次

画图问题,所用的点的坐标都挺大,求解决
本帖最后由 wang1234587 于 2013-12-31 19:46:18 编辑
我现在用的画图方法就是,在form的paint事件中写代码
大致就是先做一个空的Bitmap,然后用这个bitmap来生成graphics,之后在graphics上画图。已经试验成功。

现在我遇到的问题就是,我要画的图形所用的点是我算出来的点,这些点的坐标都很大,例如
序号 纵坐标X(m) 横坐标Y(m)
1 4202295.843 36385684.77
2 4202213.42 36385385.36
3 4201804.845 36385180.4
4 4201813.056 36385192.95
5 4201919.653 36385339.69
6 4202067.898 36385543.94
...
这些点还有好多好多,然而bitmap宽和高的最大值也才不过2000吧。。。。

我应该怎么操作才能使:①由于坐标值太大,点数很多,生成的图形都能出现在画布上,(且出现在中央啊,因为点的坐标都很大,从很大才开始的)   ②图形应该涉及的范围很广,一次肯定不能较好的显示出来,最好可以使这个图形能够实现放大,缩小,移动
③默认的坐标原点在左上角,很不方便,怎么使用自己的坐标来画图
当然了,优先解决我第一个问题啊,急急急!
最好两个问题都能解答下。    由于本人小白,超级白,所以恳请解答的时候最好附带代码示例。。

------解决方案--------------------
你是使用位图绘图,这可以获得“永久的输出”(你可以赋值给某个组件的image属性),但在你这个需求下不推荐使用(创建位图需要占用大量内存和操作时间),尤其是还需要缩放的情况(即便用位图,也不会是在Paint事件下)。
首先,你应该在Paint事件的e.graphics中绘图。这一过程不要通过创建位图实现。

例如:
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillEllipse(new SolidBrush(Color.Red), 100, 100, 3, 3);
        }
这相当于在Paint事件时将绘图绘制在了窗口画布上(而不是位图上)。当然,这并不“永久”。绘制在窗口上的图形随时会被擦除,但擦除时Paint事件会被再次触发,上面的代码会被再次执行,因此图像看上去像是永久的。

由于每次窗口被擦除时,并不是所有区域都需要重绘。这有个“脏矩形”的概念。每次Paint事件的触发都是因为出现了被擦除的矩形。e.ClipRectangle就是脏矩形。
画点事实上是画圆,它有一个矩形的区域。你可以将每个点的矩形区域与脏矩形比较,发现有相交的部分,再执行具体的画点操作。
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            Rectangle rect=new Rectangle(100,100,3,3);
            if (e.ClipRectangle.IntersectsWith(rect))
            {
                e.Graphics.FillEllipse(new SolidBrush(Color.Red), rect);
            }
使用上面的代码,无论你的点有多少,你都只会绘制窗口可见区域内无效矩形内的部分。这就解决了你第一个问题——范围和效率。

关于第二个问题:
显然,如果在Paint里编写绘图语句,那么它所使用的坐标和位置都可以是相对的。
你定义一个左上角坐标pointLT 
再定义一个缩放比k,使用逻辑控制这两个值,然后刷新(Refresh()方法。
绘图里添加对坐标和区域缩放和平移的代码。

下面的代码是相对完整的,满足你需求的代码:
 
        Point pointLT = new Point(0, -0);
        Double k = 1;
        private void Form1_Paint(object sender, PaintEventArgs e)
&nb