调整大小,重新定位......和性能问题后,创建一个新的GraphicsPath? [英] Create a new GraphicsPath after resizing, reposition ... and performance problem?

查看:56
本文介绍了调整大小,重新定位......和性能问题后,创建一个新的GraphicsPath?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的GraphicsPath更新机制非常简单和干净,它使用新的更新输入(参数)重新创建它。例如,使用GraphicsPath of Rectangle,而不是平移,缩放GraphicsPath(移动后,调整大小)我只需更新左上角的Point(Location)和Size(Width and Height),然后创建一个新的RectPath GraphicsPath使用这些更新的参数。



这非常干净,代码很容易理解。但是我遇到了这个问题,那就是当我需要将一个旋转变换应用于GraphicsPath时,在这种情况下Rectangle的例子是不合适的,例如,假设GraphicsPath现在是一个Arrow(由连线组成)。用于创建GraphicsPath的函数只能创建一个右箭头,因此每次调用它(即使更新了新参数)也只会创建一个右箭头(不是向上和向下...)。因此,如果我对右箭头的GraphicsPath应用90度旋转变换,然后调整大小并移动旋转的GraphicsPath,我就不能使用我的函数来更新GraphicsPath,除了我必须添加一些旋转GraphicsPath的代码功能。但是这个函数放在一个Paint处理程序中,这意味着每次Paint被触发时,它都会在绘制之前从头开始创建GraphicsPath(带有旋转)。



我不喜欢我认为这是一种干净的方式,以防必须通过移动和调整大小来应用旋转变换。因为我只需要旋转GraphicsPath一次而不是每次引发Paint事件时都旋转它。我不知道这样做是否可以接受?我确信它在我的项目中是可以接受的(关于性能),但它不是干净的代码。我不想添加一些代码来将GraphicsPath旋转到我的函数。 (使用新的更新参数重新创建GraphicsPath的功能)。



所以我找不到更好的解决方案。要只旋转一次(当用户需要时),我必须以另一种方式更新GraphicsPath,正如我所说的,我认为我必须将转换,缩放,旋转(以及其他任何可能的)转换应用于GraphicsPath而不是重新使用新的更新参数创建它。这听起来很干净但不是真的,即使我被困在这里。新问题与缩放转换有关,缩放会根据需要调整GraphicsPath的大小,但它也会重新定位GraphicsPath,我的想法是在不改变GraphicsPath的位置(位置)的情况下调整大小,因此缩放会使事情变得更复杂。我已经尝试将GraphicsPath的中心转换为(0,0)点,缩放它并将其转换回某些水平和垂直差异。这应该工作,但也许我计算水平和垂直差异(用于翻译)错误。



缩放对我来说也很难完全重新定位GraphicsPath因为缩放的计算并不完全准确。即使在想要的位置(被视为固定的原始位置)和更新的位置之间也会产生一个小的误差甚至1点。



请给我一个这个想法。我真的很遗憾我的第一个机制是udpate GraphicsPath,简单但干净但不能帮我在绘图之前向GraphicsPath添加更多转换,除了我必须在函数中添加相应的代码并每次都执行它(包括什么时候没有必要这么做。当Paint事件被解雇时。



我的帮助将非常感谢!

谢谢!



VipHaLong

My GraphicsPath updating mechanism is really simple and clean, that''s re-creating it with new updated inputs (parameters). For example, with a GraphicsPath of Rectangle, instead of translating, scaling the GraphicsPath (after moving, resizing) I just simply update the left-top Point (Location) and the Size (Width and Height) and then create a new GraphicsPath of Rectangle with those updated parameters.

This works very very cleanly and the code is easy to follow. But I''m facing a problem with this, that''s when I need a rotating transformation applied to the GraphicsPath, the example of Rectangle in this case is not suitable, suppose, for example, the GraphicsPath now is of an Arrow (consists of connected lines). The function used to create the GraphicsPath can create only a Right Arrow, so calling to it every time (even with new parameters updated) will create only a Right Arrow (not Up and Down...). So if I apply a 90 degree rotating transformation to that GraphicsPath of Right Arrow, then resize and move the rotated GraphicsPath, I can''t use my function to update the GraphicsPath, except that I have to add some code of rotating the GraphicsPath to the function. But this function is placed in a Paint handler, that means every time Paint is fired, it will create the GraphicsPath (with rotating) from scratch before drawing.

I don''t think that''s a clean way in case of having to apply a rotating transformation with moving and resizing. Because I just need to rotate the GraphicsPath only 1 time instead of rotating it every time Paint event is raised. I wonder it doing so is acceptable? I''m sure that it is acceptable in my project (about the performance) but it''s not clean code. I don''t want to add some code to rotate the GraphicsPath to my function. (the function for recreating GraphicsPath with new updated parameters).

So I can''t find a better solution. To rotate only 1 time (when user needs), I have to update the GraphicsPath another way, as I said, I think I have to apply transformation of translating, scaling, rotating (and anything else possible) to the GraphicsPath instead of re-creating it with new updated parameters. This sounds clean but not really, even I''m stuck at this. The new problem is related to scaling transformation, scaling will resize the GraphicsPath as I want but it also re-positions the GraphicsPath, my idea is resizing without changing the location (position) of the GraphicsPath, so scaling can make things more complicated. I''ve tried translating the GraphicsPath''s center to (0,0) point, scale it and translate it back with certain horizontal and vertical differences. That should work, but maybe I calculate the horizontal and vertical differences (for translating back) wrong.

Scaling can also be hard for me to reposition the GraphicsPath exactly because that the calculation for scaling is not completely exact. That can produce a small error of even 1 point different between the wanted position (the orginal position which is considered as fixed) and the updated position.

Please give me an idea for this. I''m really regret for my first mechanism to udpate GraphicsPath, simple but clean but can''t help me add more transformations to the GraphicsPath before drawing except that I have to add corresponding code to the function and execute it every time (including the time when it is not necessary to do) when Paint event is fired.

Your help would be highly appreciated!
Thanks!

VipHaLong

推荐答案

感谢您的澄清。我认为你已经有了一个很好的解决方案。



我唯一担心的是在油漆上重新创建一些路径。显然它不是必需的。您可以以某些路径的形式预先创建一些形状库,并将这些对象存储为某些集合,例如,您可以将其全部呈现的控件类。创建这些形状不是渲染的一部分。在 Paint 处理程序或覆盖 OnPaint 方法中,您可以将这些对象放在需要的位置并执行适当的转换以缩放/旋转他们。例如,你真的只需要一个箭头。



我认为你担心变换操作的成本太高了。恰恰相反,你应该更好地依靠它的性能,这应该是你所有运营链中最好的之一。无论如何,关于渲染性能的问题,我会做一些研究,但我认为你已经走上了正确的道路。



只进行预创作我在上面提到了渲染。更一般地说,不要害怕保留一些可重复使用的对象作为控件,笔,刷子,路径等的实例成员。当你处置你的控件实例时,不要忘记处理它们(其中许多实现 System.IDisposable)



-SA
Thank you for clarification. I think you already almost have a good solution.

The only concern I would have is having some paths the be recreated on paint. It''s clear that it''s not needed. You can pre-create some "library of shapes" in the form of some paths and store these objects as some set which is the member of, for example, your class of control where you render it all. Creation of these shapes is not a part of rendering. In your Paint handler or overridden OnPaint method, you can put these objects where needed and perform appropriate transformation to scale/rotate them. For example, you really need only one arrow.

I think you concern about the transform operation cost too much. Just the opposite, you should better rely on its performance, which should be one of the best in all your operation chain. Anyway, of performance of rendering is concern, I would do a little research, but I think you are already on a right path.

Only carry out the pre-creation I mentioned above out of rendering. More generally, don''t be afraid of keeping some reusable object as instance members of your control, pens, brushed, paths and more. Only don''t forget to dispose them (many of them implement System.IDisposable) when you dispose the instance of your control.

—SA


使用缩放时的问题是如何将GraphicsPath精确地重新定位到原始位置(固定位置)之后缩放。



正如我在关于我试图实现这一目标的问题中提到的那样,但我意识到根据缩放因子,这并不容易和不稳定。我试图找到另一种方式。这是:



步骤如下:

- 缩放GraphicsPath。

- 将GrahicsPath翻译为原来的位置。



The problem when using scaling is how to re-position the GraphicsPath exactly to the original position (the fixed position) after scaling.

As I mentioned in the question about the way I tried to achieve this but I realize that it''s not easy and unstable depending on the scaling factors. And I tried to find out another way. Here it is:

The steps are:
- Scale the GraphicsPath.
- Translate the GrahicsPath to the original position.

private void ScaleWithoutChangingPosition(GraphicsPath gp, float scalex, float scaley){
   //Scale first
   Matrix m = new Matrix();
   m.Scale(scalex, scaley);
   gp.Transform(m);
   //Translate then
   m.Reset();
   float left = float.MaxValue, top = float.MaxValue;
   foreach(PointF p in gp.PathPoints){
      if(left > p.X) left = p.X;
      if(top > p.Y) top = p.Y;
   }
   m.Translate(fixedPosition.X - left, fixedPosition.Y - top);
   gp.Transform(m);
}





这里重要的是我如何在缩放后找到GraphicsPath的新位置,这肯定是确切的我想要的。



谢谢!



The important thing here is how I find the new location of GraphicsPath after scaling and it''s surely exact as I want.

Thanks!


这篇关于调整大小,重新定位......和性能问题后,创建一个新的GraphicsPath?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆