Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 计算直线无穷大时的斜率_Java_Android_Canvas_Line_Paint - Fatal编程技术网

Java 计算直线无穷大时的斜率

Java 计算直线无穷大时的斜率,java,android,canvas,line,paint,Java,Android,Canvas,Line,Paint,我正在用Java(特别是Android)制作一些东西,显示如下内容: 用户可以拖动长方体的角,如预期的那样,虚线应该相应地移动,始终有3条水平线(一条一半,一条25%,一条75%位于顶部和底部之间)和3条垂直线。但是,如果左边缘或右边缘为无穷大(用户第一次看到屏幕时为无穷大),则其外观如下所示: 我如何更改代码,使无限的斜坡边缘得到考虑,并仍然显示所需的屏幕?下面是我的代码,用于检测虚线的位置、坡度,以及最终绘制到屏幕上的虚线 //get edge slopes to calculate d

我正在用Java(特别是Android)制作一些东西,显示如下内容:

用户可以拖动长方体的角,如预期的那样,虚线应该相应地移动,始终有3条水平线(一条一半,一条25%,一条75%位于顶部和底部之间)和3条垂直线。但是,如果左边缘或右边缘为无穷大(用户第一次看到屏幕时为无穷大),则其外观如下所示:

我如何更改代码,使无限的斜坡边缘得到考虑,并仍然显示所需的屏幕?下面是我的代码,用于检测虚线的位置、坡度,以及最终绘制到屏幕上的虚线

//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坐标,问题就消失了

如果不了解更多有关该计划的信息,我无法确定地回答。也就是说,我对你可以尝试的东西有一些想法,但我对每一个都有相关的问题:

  • 我觉得奇怪的是,当屏幕第一次加载时,左右边缘等于无穷大。你的左右边缘位置基于什么?它们是否提前储存?基于屏幕尺寸和密度?如果它是基于屏幕尺寸,你不应该有这个问题。按如下方式测量屏幕宽度(可能因Android版本而异,但有很多在线教程):

    在计算任何东西之前先计算这些值。根据屏幕边缘调整初始坐标位置

  • 框是否每次都以相同的坐标开始?在你上面运行的应用程序之前,应用程序中是否有一个屏幕?如果两者都是,则:

    • a) 计算应用程序首次加载时的所有位置,并将其传递给新的活动/片段;或
    • b) 加载应用程序时(在加载图像之前的屏幕中)异步生成实际绘制的画布,然后将实际画布传递给新活动/片段
  • 您在活动/片段生命周期的哪个部分运行该方法?如果要在onResume()中运行它,请尝试在循环的早期运行它的各个方面,或者尽早进行特殊计算。更具体地说:

    • 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;