求画斜线和文字旋转自动匹配算法——By CJ From eYes(300分)

  • 主题发起人 主题发起人 CJ
  • 开始时间 开始时间
C

CJ

Unregistered / Unconfirmed
GUEST, unregistred user!
1.求教报表单元格斜线分割的算法(最多分3斜线4格)
2.斜线格内文字排列算法:
1. 如果斜线格可以放下所有文字, 要求能计算不同排
列(左, 中, 右)方式下的文字起始位置
2. 如果放不下所有文字, 要求斜线格能自动扩大.
加一句:
要考虑文字旋

 
还是写错. 是"可以考虑文字旋转", 不是"要", 最好"不要"
 
哦哦,这问题很好啊,我也感兴趣,
文字旋转要用 tLogFont
EReport里只做到了插入多条斜线,但还没有做到斜线与旋转字体的配合
 
刚从计算机世界报上得知,Word 2000可实现单元内画斜线等功能。
另,我们用Word5.0的Microsoft Drawing来实现表内斜线、文字的贴入,效果很好!
Word5.0需1.44FD*6,只装Drawing,仅需1.44FD*2即可。现在的Word功能太强了,
但唯独无Drawing这个好用的工具。想要吗?(看样子世只有本人有了):-))
 
不要工具, 要算法
 
画斜线较容易,能够画出斜线就能够求出斜线的角度。文字的轮廓框也容易,用
canvas.textWidth,canvas.TextHeight可以得到没有旋转的字符串的轮廓。
难一点的是在斜线与斜线及表格线组成的多边形中确定能否容纳旋转后的轮廓矩形。
假设旋转字体的基线与所画斜线平行,则能否容纳字符的解法如下:
1。做一条斜线的平行线L1,与斜线的距离为字符的高度
2。求L1与多边形的交点P1,P2
3。求出P1,P2的距离D12
4。如果D12>=Canvas.TextWidth(YourString),则能够容纳字符串,否则调整表格
旋转字体: 见已答问题。
计算左中右的起始位置:小学算术+旋转
不旋转,能否容纳: 先找出水平边最大的三角形或梯形,再参考上述算法
 
细节呢?
请包括小学算术那部分
 
三步走:
1.计算角度:打印区域可能是一个三角也可能是一个四边形:
a.如果是三角形则角度向最长边靠近:平分最长边的两个夹角,哪条角平分
线最长取哪条平分线的角度;
b.如果是四边形则复杂一些,先取两条对角线,角度向最长的一条靠近;平分
该对角线所在两个顶点的角,哪条角平分线最长取哪条角平分线有角度.
2.字体旋转有三种方式:
a.字体并不旋转,但字的排列旋转;这种旋转反而用得较多,符合中国人习惯,
将要打印内容分解成单个字,形成多个矩形,按上述角度排列这几个矩形,
计算其逻辑长度和宽度,测试是否能放进原定区域,如果不够则适当放大
原区域;
b.字体按上述角度的垂线旋转,字体排列按上述角度旋转,实际上可以使用
字体不旋转时的TextWidth和TextHeight, 只有一个矩形,测试是否能放
进原定区域,如果不够则适当放大原区域;
c.字体和字体的排列均按上述角度旋转,这也需要将内容分解成单个字,但
其矩形是与上述角度平等的;实际上这个矩形等于每个字的最大宽度乘上
每个字的高度和,也只有一个矩形,测试是否能放进原定区域,如果不够则
适当放大原区域.
是否能放进原区域算法较简单:先按目标矩形的宽度求原定区域的最大矩
形,比较面积大小,再按目标矩形的长度求原定区域的最大矩形,再比较面
积大小,两次有一次失败则失败.取原定区域最小的面积放大原区域或缩
小字体.
3.计算每一个字的位置,画上去即可.
 
能给出具体实现的例程吗? 加200分
 
to eyes, 问题挺有意思,可惜没时间做呀。你要的算法应该是有了,把我同barton
的算法结合起来就是一个典型的中文表格之表头的算法。
 
大家继续呀,那么有趣的问题,能做出来,我再出300,这东西比其它实用多了
 
to CJ, eYes: 没时间完成, 但是可以给你们一些小帮助如旋转,求教函数.
const
FPI180 = pi / 180;
F180PI = 180 / pi;
Delta = 0.0001;
type
HJPoint = record
x:do
uble;
y:do
uble;
z:do
uble;
end;
//Sin of angle given by degree
function SinA(value: integer):do
uble;
begin
result:=Sin(value*FPI180);
end;
//cos of degree
function CosA(value: integer):do
uble;
begin
Result:=Cos(value*FPI180);
end;
function TanA(value: integer):do
uble;
begin
result:=Sin(value*fPi180)/Cos(value*fPi180);
end;

//get a new point away from p1 with a given angle and distance
function Polar(p1: HJPoint;
angle: integer;
dist:do
uble): HJPoint;
begin
result.x:=cos(angle*FPi180)*abs(dist)+p1.x;
result.y:=sin(angle*FPi180)*abs(dist)+p1.y;
end;
//roatata a point p round baseP, at a given angle
function RotatePoint(const P, baseP: HJPoint;
angle: integer): HJPoint;
var
x,y:do
uble;
begin
x:=p.x-baseP.x;
y:=p.y-BaseP.y;
result.x:=BaseP.x+x*CosA(Angle)-y*SinA(Angle);
result.y:=BaseP.y+x*SinA(Angle)+y*CosA(Angle);
result.z:=p.z;
end;

//get the intercecting state of two lines p1p2, p3p4, if they are not
//parall out Parameter, PinL returns the new point position in line1
function Intersect(p1,p2,p3,p4: HJPoint;
var PinL:do
uble): boolean;
//pinl: location of point in line1(p1,p2), <0 left, 0 start, 1 end, >1 right
var
k1,k2,k3,
y21,x21,y43,x43,y13,
xx1,yy1,
x,y:do
uble;
lstate: integer;
{ 1-l1hor, 2-l1ver, 4-l2hor, 8-l2ver }
begin
result:=false;
lstate:=0;
y21:=p2.y-p1.y;
x21:=p2.x-p1.x;
y43:=p4.y-p3.y;
x43:=p4.x-p3.x;
y13:=p1.y-p3.y;
if abs(y21) < delta then
lstate:=lstate or 1;
{l1 horrizental}
if abs(x21) < delta then
lstate:=lstate or 2;
{l1 vertical}
if abs(y43) <= delta then
lstate:=lstate or 4;
{l2 horrizental}
if abs(x43) <= delta then
lstate:=lstate or 8;
{l2 vertical}
case lstate of
0: //both nomal
begin
K1:=y21/x21;
k2:=x43/y43;
k3:=y43/x43;
if not (abs(k1-k3) <= delta) then
begin
result:=true;
x:=(k2*y13-k1*k2*p1.x+p3.x)/(1-k1*k2);
xx1:=x-p1.x;
PinL:=xx1/x21;
end;
end;
1: //line1 is hor
begin
result:=true;
y:=p1.y;
k2:=x43/y43;
x:=k2*(y-p3.y)+p3.x;
xx1:=x-p1.x;
PInL:=xx1/x21;
end;
2: { l1 ver }
begin
result:=true;
x:=p1.x;
k2:=y43/x43;
y:=k2*(x-p3.x)+p3.y;
yy1:=y-p1.y;
PInL:=yy1/y21;
end;
4: { l2 hor }
begin
result:=true;
y:=p3.y;
k1:=x21/y21;
x:=k1*(y-p1.y)+p1.x;
xx1:=x-p1.x;
PInL:=xx1/x21;
end;
3,5,7,10,12,13,14,15:{ both hor/both ver/null length }
result:=false;
6: { l1 ver l2 hor }
begin
result:=true;
y:=p3.y;
yy1:=y-p1.y;
PInL:=yy1/y21;
end;
8: { l2 ver }
begin
result:=true;
x:=p3.x;
xx1:=x-p1.x;
PInL:=xx1/x21;
end;
9: { l1 hor l2 ver }
begin
result:=true;
xx1:=p3.x-p1.x;
PInL:=xx1/x21;
end;
end;
{case}
if abs(pinl)<=delta then
pinl:=0
else
if abs(1-pinl)<=delta then
pinl:=1;
end;
 
好象小学数学也不简单:(
eYes:你看如何?
 
只好如此了.
 
后退
顶部