Qt 在任意宽度的两点之间绘制矩形

Qt 在任意宽度的两点之间绘制矩形,qt,opengl,math,2d,Qt,Opengl,Math,2d,当用户在触摸屏上滑动手指时,我试图在两个(2D)点之间画一条线。为此,我计划在每次触摸更新时在上一次触摸更新的X和Y与最近一次触摸更新的X和Y之间绘制一个矩形。当用户在屏幕上滑动手指时,这将创建一条连续的实线。但是,我也希望这一行具有任意宽度。我的问题是,我应该如何计算每个矩形(x1,y1,x2,y2)所需的坐标 -- 另外:如果有人知道我如何将抗锯齿应用到这条直线上,那将是一个巨大的帮助。计算起点和终点之间的向量 V.X := Point2.X - Point1.X; V.Y := Point

当用户在触摸屏上滑动手指时,我试图在两个(2D)点之间画一条线。为此,我计划在每次触摸更新时在上一次触摸更新的X和Y与最近一次触摸更新的X和Y之间绘制一个矩形。当用户在屏幕上滑动手指时,这将创建一条连续的实线。但是,我也希望这一行具有任意宽度。我的问题是,我应该如何计算每个矩形(x1,y1,x2,y2)所需的坐标

--


另外:如果有人知道我如何将抗锯齿应用到这条直线上,那将是一个巨大的帮助。

计算起点和终点之间的向量

V.X := Point2.X - Point1.X;
V.Y := Point2.Y - Point1.Y;
然后计算一个与之垂直的坐标(只需交换X和Y坐标)

使垂直线正常化

Length = sqrt(P.X * P.X + P.Y * P.Y); //Thats length of perpendicular
N.X = P.X / Length;
N.Y = P.Y / Length; //Now N is normalized perpendicular
计算形成矩形的4个点,方法是将标准化垂直线相加,然后将其乘以所需宽度的一半

R1.X := Point1.X + N.X * Width / 2;
R1.Y := Point1.Y + N.Y * Width / 2;
R2.X := Point1.X - N.X * Width / 2;
R2.Y := Point1.Y - N.Y * Width / 2;
R3.X := Point2.X + N.X * Width / 2;
R3.Y := Point2.Y + N.Y * Width / 2;
R4.X := Point2.X - N.X * Width / 2;
R4.Y := Point2.Y - N.Y * Width / 2;
使用这4个点绘制矩形

图片如下:


编辑:回答注释:如果X和Y相同,则直线正好是对角线,与对角线垂直的直线是对角线。标准化是一种使长度等于1的方法,因此本例中线条的宽度不取决于垂直度长度(此处等于线条长度)。

如果我理解正确,您有两个端点,即a(x1,y1)和B(x2,y2),矩形的任意宽度为w。我假设端点正好位于矩形较短边的中间,这意味着最终矩形角坐标的距离为w/2到A和B

可以通过以下公式计算直线的坡度:

s1=(y2-y1)/(x2-x1)//假设x1!=x2

短边的斜率为s2=-1/s1

我们有斜率,我们有距离,我们有参考点

然后,我们可以为每个角点导出两个方程:

在一个靠近

C(x3,y3):

(y3-y1)/(x3-x1)=s2/(按斜率)

(y3-y1)^2+(x3-x1)^2=(w/2)^2//

将(y3-y1)替换为a,将(x3-x1)替换为b

a=b*s2//斜率方程

//将a替换为b*s2

b^2*s2^2+b^2=(w/2)^2//距离等式

b^2=(w/2)^2/(s2^2+1)

b=sqrt((w/2)^2/(s2^2+1))

我们知道w和s2,因此计算b

如果b已知,我们可以推导出x3

x3=b+x1

还有一个

a=b*s2

所以y3

y3=b*s2+y1

我们有一个角点C(x3,y3)

为了计算更靠近A的另一个角点,比如D(x4,y4),斜率方程可以构造为

(y1-y4)/(x1-x4)=s2 应采用上述计算方法

用B(x2,y2)替换A(x1,y1)可以计算其他两个角。

简单方法(我将“宽度”称为线条的厚度):

我们需要计算2个值,4个角的x轴偏移和y轴偏移。这很容易

该生产线的尺寸为:

width = x2 - x1

height = y2 - y1
现在x移位(我们称之为xS):

要求直线的长度,请使用毕达哥拉斯定理:

length = square_root(width * width + height * height)
现在你有了x移位和y移位

First coordinate is: (x1 - xS, y1 + yS)

Second: (x1 + xS, y1 - yS)

Third: (x2 + xS, y2 - yS)

Fourth: (x2 - xS, y2 + yS)

就这样!(这些坐标是逆时针绘制的,这是OpenGL的默认值)

我很困惑,所以你有左上角(x1,y1)和右下角(x2,y2),需要用这些点创建一个矩形吗?坐标不就是[(x1,y1),(x2,y1),(x1,y2),(x2,y2)]?我需要处理的所有信息都是用户手指在屏幕上的先前位置和最新位置。我需要在两者之间画一条任意宽度的线。注意,矩形也需要居中。这并不像你想象的那么简单。这个骇人听闻的例子可能有用,也可能没用。(注意顶部矩形上的第二个坐标实际上应该是150,50,但希望你能理解我的意思)你为什么打算使用矩形?为什么不使用粗线段?DatenWalf:在我开发的平台上,OpenGL只允许1px宽的抗锯齿线。非常感谢您的回复,非常感谢。我们现在就开始工作。非常感谢,非常感谢您的帮助!我发现这更容易理解。虽然我不明白投票结果最高的答案。@Krom Stern请用这4个点详细说明
绘制矩形。
你的答案很好,但我对用这4个点确定矩形的大小感到困惑。请帮忙。谢谢。@SalmanKhakwani:我不知道怎么解释得更简单些。到底是什么让你们困惑?我下面的问题,你们的回答似乎非常适合这个问题。你能回答这个问题吗,这对我很有帮助:)回答得好。不过我还是放弃了P中间变量。也许值得将“*Width/2”合并到N中。谢谢,这节省了我的时间。对于那些使用Qt绘图的人:->使用QPolygon绘制4点ST(R1X、R1Y、R2X、R2Y、R3X、R3Y和R4X、R4Y),并使用变量类型完美地绘制为“双精度/浮点”而不是“int”,以避免在两个输入点倾斜时丢失点。
length = square_root(width * width + height * height)
First coordinate is: (x1 - xS, y1 + yS)

Second: (x1 + xS, y1 - yS)

Third: (x2 + xS, y2 - yS)

Fourth: (x2 - xS, y2 + yS)