Java 计算直线无穷大时的斜率
我正在用Java(特别是Android)制作一些东西,显示如下内容: 用户可以拖动长方体的角,如预期的那样,虚线应该相应地移动,始终有3条水平线(一条一半,一条25%,一条75%位于顶部和底部之间)和3条垂直线。但是,如果左边缘或右边缘为无穷大(用户第一次看到屏幕时为无穷大),则其外观如下所示: 我如何更改代码,使无限的斜坡边缘得到考虑,并仍然显示所需的屏幕?下面是我的代码,用于检测虚线的位置、坡度,以及最终绘制到屏幕上的虚线Java 计算直线无穷大时的斜率,java,android,canvas,line,paint,Java,Android,Canvas,Line,Paint,我正在用Java(特别是Android)制作一些东西,显示如下内容: 用户可以拖动长方体的角,如预期的那样,虚线应该相应地移动,始终有3条水平线(一条一半,一条25%,一条75%位于顶部和底部之间)和3条垂直线。但是,如果左边缘或右边缘为无穷大(用户第一次看到屏幕时为无穷大),则其外观如下所示: 我如何更改代码,使无限的斜坡边缘得到考虑,并仍然显示所需的屏幕?下面是我的代码,用于检测虚线的位置、坡度,以及最终绘制到屏幕上的虚线 //get edge slopes to calculate d
//get edge slopes to calculate dashed lines
//c1X is the top left corner X position, c2X is for the top right corner, etc.
float topLineSlope = (c2Y - c1Y)/(c2X - c1X);
float rightLineSlope = (c3Y - c2Y)/(c3X - c2X);
float bottomLineSlope = (c4Y - c3Y)/(c4X - c3X);
float leftLineSlope = (c1Y - c4Y)/(c1X - c4X);
//b in y=mx+b
float topLineB = c1Y - (topLineSlope * c1X);
float rightLineB = c2Y - (rightLineSlope * c2X);
float bottomLineB = c3Y - (bottomLineSlope * c3X);
float leftLineB = c4Y - (leftLineSlope * c4X);
//final dashed line coordinates
float topLineMiddleX = (c1X + c2X) / 2.0f;
float topLineMiddleY = topLineSlope * topLineMiddleX + topLineB;
float bottomLineMiddleX = (c3X + c4X) / 2.0f;
float bottomLineMiddleY = bottomLineSlope * bottomLineMiddleX + bottomLineB;
float leftLineMiddleX = (c4X + c1X) / 2.0f;
float leftLineMiddleY = leftLineSlope * leftLineMiddleX + leftLineB;
float rightLineMiddleX = (c2X + c3X) / 2.0f;
float rightLineMiddleY = rightLineSlope * rightLineMiddleX + rightLineB;
float topLineLeftX = (c1X + topLineMiddleX) / 2.0f;
float topLineLeftY = topLineSlope * topLineLeftX + topLineB;
float bottomLineLeftX = (c4X + bottomLineMiddleX) / 2.0f;
float bottomLineLeftY = bottomLineSlope * bottomLineLeftX + bottomLineB;
float topLineRightX = (topLineMiddleX + c2X) / 2.0f;
float topLineRightY = topLineSlope * topLineRightX + topLineB;
float bottomLineRightX = (c3X + bottomLineMiddleX) / 2.0f;
float bottomLineRightY = bottomLineSlope * bottomLineRightX + bottomLineB;
float leftLineTopX = (c1X + leftLineMiddleX) / 2.0f;
float leftLineTopY = leftLineSlope * leftLineTopX + leftLineB;
float rightLineTopX = (c2X + rightLineMiddleX) / 2.0f;
float rightLineTopY = rightLineSlope * rightLineTopX + rightLineB;
float leftLineBottomX = (leftLineMiddleX + c4X) / 2.0f;
float leftLineBottomY = leftLineSlope * leftLineBottomX + leftLineB;
float rightLineBottomX = (c3X + rightLineMiddleX) / 2.0f;
float rightLineBottomY = rightLineSlope * rightLineBottomX + rightLineB;
canvas.drawLine(topLineMiddleX, topLineMiddleY, bottomLineMiddleX, bottomLineMiddleY, dashedLine);
canvas.drawLine(leftLineMiddleX, leftLineMiddleY, rightLineMiddleX, rightLineMiddleY, dashedLine);
canvas.drawLine(topLineLeftX, topLineLeftY, bottomLineLeftX, bottomLineLeftY, dashedLine);
canvas.drawLine(topLineRightX, topLineRightY, bottomLineRightX, bottomLineRightY, dashedLine);
canvas.drawLine(leftLineTopX, leftLineTopY, rightLineTopX, rightLineTopY, dashedLine);
canvas.drawLine(leftLineBottomX, leftLineBottomY, rightLineBottomX, rightLineBottomY, dashedLine);
如果它始终是一个底部完全水平的矩形,则根本不需要使用坡度,只需在两个内部标高处从左到右绘制一条水平线,例如:
bottom + (top - bottom) / 3
bottom + 2 * (top - bottom) / 3
自上而下的垂直线也是如此
这基本上只是执行以下操作,假设左下角是离原点最近的点:
hspread = (right - left) / 3
line (top, left + hspread) - (bottom, left + hspread)
line (top, left + 2 * hspread) - (bottom, left + 2 * hspread)
vspread = (top - bottom) / 3
line (bottom + vspread, left) - (bottom + vspread, right)
line (bottom + 2 * vspread, left) - (bottom + 2 * vspread, right)
如果角可以独立移动(即,它不必是矩形),您仍然不需要涉及坡度
然后,您需要做的是找到每边上的点,这些点等于沿直线的1/3和2/3距离,并将它们连接起来。对于一条线(x1,y1)-(x2,y2)
,您只需使用以下命令即可沿该线找到点4/5
:
x = x1 + (x2-x1) * 4/5
y = y1 + (y2-y1) * 4/5
例如,如果形状是这样的:
(x1,y1) (x2,y2)
___--+
+----' \
| \
| \
| \
| \
+----------------+
(x3,y3) (x4,y4)
:
:
:......
(0,0)
(对“图形”表示歉意),最上面的水平线可以绘制为:
line (x3 + (x1-x3) * 2/3, y3 + (y1-y3) * 2/3)
- (x4 + (x2-x4) * 2/3, y4 + (y2-y4) * 2/3)
这是我找到给定直线中点的更一般化的形式
因此,在这两种情况下,您所需要的只是一个基于起点和终点(您已经有了)的线条绘制原语,而不必混淆潜在的无限斜率。如果您不使用直线或斜率方程,这是非常容易的。您所做的是通过查找x坐标对的平均值来计算所有x坐标。然后将这些x坐标代入边的方程中。正如您已经确定的,如果坡度是无限的,那么这将不起作用。有一个非常简单的解决方案。你所要做的就是用计算x坐标的方法计算y坐标,问题就消失了 如果不了解更多有关该计划的信息,我无法确定地回答。也就是说,我对你可以尝试的东西有一些想法,但我对每一个都有相关的问题:
- a) 计算应用程序首次加载时的所有位置,并将其传递给新的活动/片段;或
- b) 加载应用程序时(在加载图像之前的屏幕中)异步生成实际绘制的画布,然后将实际画布传递给新活动/片段
- a)使用静态预计算角度和手动传递的给定坐标,计算循环早期的特殊线路坡度,直到剩余部分完全加载为止。满载后,计算实际坡度。在初始加载时-当应用程序首次使用时-提供默认值。在随后的每个出口上,存储坐标、坡度等值,并在再次加载该屏幕时检索它们
- b)仅在屏幕完成加载后进行计算并生成框,即将其作为最后一步,并且仅由依赖于完成的任务触发
- c)在生成长方体之前,检查左右边缘是否不等于无穷大。在(我想是窗口对象?)上使用侦听器来观察左右边值的变化。
- …或者使用一个asynctask,它只会不断检查边值,直到它们都不是无穷大,然后在满足此条件后立即退出
- 请注意……您是在片段中运行它,还是在活动中运行它
请注意,我只是简单地看了一下数学本身,没有发现任何问题,因此我假设它是好的,因为您说加载完成后没有问题。不使用
mx+b
行格式。
Display d = getWindowManager().getDefaultDisplay();
Point point = new Point();
d.getSize(point);
int width = point.x;
int height = point.y;