请教:canvas.pen.width可设置线型宽度,width为integer类型,如何定义比 width := 1 还要细的线型呢?有什么方法使width的

  • 主题发起人 主题发起人 huangbaili
  • 开始时间 开始时间
H

huangbaili

Unregistered / Unconfirmed
GUEST, unregistred user!
请教:canvas.pen.width可设置线型宽度,width为integer类型,如何定义比 width := 1 还要细的线型呢?有什么方法使width的值精确到比如0.1之类的值?(50分)<br />请教:canvas.pen.width可设置线型宽度,width为integer类型,如何定义比 width := 1 还要细的线型呢?有什么方法使width的值精确到比如0.1之类的值?
 
HI:
1是画布能支持的最小单位,如果Width=0也使用最小值,在屏幕上与Width=1没有
区别,但在输出WMF图形则不一样,为1时会随比例缩放;
如果你的画布需要定义更精细的线宽,可以使用映射,例如将100X100的画布映射
为1000X1000,这样Width=20才相当原来的Width=2,Width=2相当原来的Width=0.2。

[例]

SetWindowExtEx(Canvas.Handle, 1000, 1000, nil);
SetViewportExtEx(Canvas.Handle, 100, 100, nil);
 
小弟不才:我试了一下,竟没有任何效果,不知是何原因?
 
只有一个象素,当然一样
 
在屏幕上是看不出来的(除非WINDOWS画线时帮你写一个反走样算法,或你自己写)。
你输出到WMF上放大来看,也许能看出来。输出打印也会有效果,因为打印机的分辨率
较高。
映射是逻辑上的,而我们的屏幕从物理上决定了不可能输出再细的线段了,但打印机
或其它输出设备可以。
 
按照楼上的那们哥们的意思,我在屏幕上是不可以得到更细的线条了,可我在看股票分析
软件的时候,K线的线条就比较细,不知是我的眼睛不对劲还是我的机器屏幕太超前了,
另外,如何重新定义某一区域的坐标原系?
 
应该是你眼睛的问题:)
 
SetWindowExtEx(Cnv.Handle, pWinExt^.cX, pWinExt^.cY, nil);
SetWindowOrgEx(Cnv.Handle, pWinOrg^.X, pWinOrg^.Y, nil);****
SetViewportExtEx(Cnv.Handle, pViewExt^.cX, pViewExt^.cY, nil);
SetViewportOrgEx(Cnv.Handle, pViewOrg^.X, pViewOrg^.Y, nil);****
 
问题比较有新意
计算机只能以像素为最小显示单位,但反过来想,只要你的眼睛觉得很细,就达到效果了。
可以设计一个反走样函数,用适当灰度的像素进行组合编码,应该可以实现的。

股票系统一般的黑背景,用蓝绿色等色彩画线,会觉得很细。
 
能说说反走样函数的具体实际方法吗?本人就是在写一个股票分析程序,有人在这方面(
K线图的显示)有比较好的思路,可否交流一下。
 
呵呵!刚好我也做过一个股票分析软件(不过只是自己分析用)^_^
我对于K线图的做法是自己先定义一个新的画笔单元,为此还专门写了一个绘图控件!
下面是一个定义的Draw过程:
procedure DrawLines (Ind:Integer);
Var A:Integer;
RY,Incr:Extended;
Clr:TColor;
ZY:Integer;
Rgn:HRgn;
PrevDef:Boolean;
TempR:TRect;
Ext:Extended;
FuncOK:Boolean;
TP:Array [0..1] of TPoint;
begin
TempR:=Rect (R.Left,R.Top,R.Right+1,R.Bottom+1);
Rgn:=CreateRectRgnIndirect (TempR);
SelectClipRgn (DrawCanvas.Handle,Rgn);
Clr:=FSeries[Ind].Color;
RY:=(R.Bottom-R.Top)/(FVisRect.Y2-FVisRect.Y1);
Incr:=(FVisRect.X2-FVisRect.X1)/(R.Right-R.Left);
XParser.X:=FVisRect.X1;
PrevDef:=False;
with DrawCanvas do
begin
Pen.Style:=psSolid;
Pen.Color:=Clr;
Ext:=0;
ZY:=0;
For A:=R.Left to R.Right do
begin
try
Ext:=XParser.Value;
FuncOK:=not XParser.CalcError;
except
FuncOK:=False;
end;
If FuncOK then
begin
ZY:=R.Bottom-Round((Ext-FVisRect.Y1)*RY);
If NOT PrevDef then
begin
Pixels [A,ZY]:=Clr;
MoveTo (A,ZY);}
TP[0].X:=A;
TP[0].Y:=ZY;
end
else
begin
LineTo (A,ZY);
TP[1].X:=A;
TP[1].Y:=ZY;
PolyLine (TP);
DrawLine (TP[0].X,Tp[0].Y,TP[1].X,TP[1].Y,Clr);
If NOT
(((TP[0].Y<0) AND (TP[1].Y<0)) OR
((TP[0].Y>Height) AND (TP[1].Y>Height))) then
DrawCanvas.PolyLine (TP);
TP[0]:=TP[1];
end;
PrevDef:=True;
end
else
PrevDef:=False;
XParser.X:=XParser.X+Incr;
end; {For A:=R.Left to R.Right}
If PrevDef then
Pixels [R.Right,ZY]:=Clr;
end; {with DrawCanvas}
SelectClipRgn (DrawCanvas.Handle,0);
DeleteObject (Rgn);
end;
 
什么是反走样(antialiasing)?
就是在显示器上显示图形时,直线段或图形边界或多或少会呈锯齿状。原因是图形信号是连续的,而在光栅显示系统中
,用来表示图形的却是一个个离散的象素。这种用离散量表示连续量引起的失真现象称之为走样(aliasing);用于减少
或消除这种效果的技术称为反走样(antialiasing)。光栅图形的走样现象除了阶梯状的边界外,还有图形细节失真(图
形中的那些比象素更窄的细节变宽),狭小图形遗失等现象。常用的反走样方法主要有:提高分辨率、区域采样和加权
区域采样。
摘自——《光栅图形学》一书。
实现的最简方法是用中点算法转换为直线。
一个长度小于一像素的直线将如何实现呢?因为它的长度太小以至不能精确表现,所以你可以随便按它应该的模样画,
首先把线拉伸到一个像素长,然后降低它的亮度。这也就是为什么一条非常短的直线看上去很暗,而当它变长时,它就
会变亮;当它是一个像素长时,它在所在点上将能够被正常的画出。
 
万分感激各位仁兄的鼎力相助,本人的QQ号为:99667812,望能与各位多多联系。
另:在不违背版权的情况下,YB_unique仁兄可否将你写的分析软件源码给我过一个,包括
那个画图控件。再次感谢!!!!

 
有关“卡笛尔坐标t系”的问题,请教如何在一个form的某一区域重新定义一个坐标,新
定义的坐标的每一个单位是form的每一个单位的10倍,请给段代码。谢了!!!
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
I
回复
0
查看
738
import
I
后退
顶部