5

我正在尝试绘制一个箭头来指向图像中的对象。我已经能够编写代码来绘制线条,但似乎无法找到一种方法来绘制箭头。我编写的用于绘制可拖动线的代码如下。我需要在 ACTION_UP 事件上绘制一个箭头到线指向的方向

if(event.getAction() ==MotionEvent.ACTION_DOWN) {         
     if (count==1){ 
          x1 = event.getX();
          y1 = event.getY();
          System.out.println(count+"count of value a;skd");
          Toast.makeText(getApplicationContext(), ""+(radius+count), Toast.LENGTH_LONG).show();

          Log.i(TAG, "coordinate x1 : "+String.valueOf(x1)+" y1 : "+String.valueOf(y1));
     }
}
else if(event.getAction() ==MotionEvent.ACTION_MOVE){

     imageView.setImageBitmap(bmp2);
     x2 = event.getX();
     y2 = event.getY();
     posX=(float)(x1+x2)/2;
     posY=(float)(y1+y2)/2;
     radius=(float) Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))/2;
     onDraw();
     Toast.makeText(getApplicationContext(), ""+radius, Toast.LENGTH_LONG).show();
}

嗨,对于任何仍然需要帮助的人。这就是我最后的做法 float h=(float) 30.0;

    float phi = (float) Math.atan2(y2 - y1, x2 - x1); 
    float angle1 = (float) (phi - Math.PI / 6); 
    float angle2 = (float) (phi + Math.PI / 6);

    float x3 = (float) (x2 - h * Math.cos(angle1));
    float x4 = (float) (x2 - h * Math.cos(angle2));
    float y3 = (float) (y2 -  h * Math.sin(angle1));
    float y4 = (float) (y2 -  h * Math.sin(angle2));
   c.drawLine(x1, y1,x2,y2 ,pnt);
   c.drawLine(x2, y2,x3,y3 ,pnt);
    c.drawLine(x2, y2,x4,y4 ,pnt);

我从 stackoverflow 中接受的答案和 ios 部分获得了帮助

4

3 回答 3

5

我将如何做到这一点是找到在两点(起点和终点)之间绘制的线的斜率。斜率为 (dy/dx),这将是您箭头的良好起点。假设您希望箭头的底部垂直于箭头的线,要找到底部的斜率,您会找到线斜率的相反倒数。例如,假设您的线的斜率为 2。三角形底边的斜率为 (-1/2),因为您使用 (1/(oldslope)) 并乘以 -1。我不太了解android,但如果我没记错的话,在Java 中,您将使用drawPolygon 方法,并且您必须指定4 个点(3 个唯一点和1 个与第一个相同的点来关闭它)。给定尖端底部的斜率,我们可以得到前两个点和最后一个点。b将是您的基线的长度。如果您采用ϴ=arctan(dy/dx),那将为您提供 x 轴和基线之间的角度。使用该 ϴ 值,您可以ydif = b*sin(ϴ)获取箭头两个底角之间 y 值的差异。做同样的事情,但是用xdif = b*cos(ϴ)给你两个基点之间的 x 值的差异。如果用户绘制的线的最后一个点的位置是(x1, y1),那么三角形的基点的位置将是(x1-(xdif/2), y1-(ydif/2))(x1+(xdif/2), y1+(ydif/2))。这两个点 p1 和 p2 是绘制多边形方法中的第一个、第二个和第四个点。要找到第三个点,我们需要找到原线的角度,方法是ϴ=arctan(dy/dx), 这次使用你原来的 dy/dx. 用那个角度。在我们完成点的实际计算之前,您首先必须知道箭头的尖端实际上应该离行尾多远,在我的例子中,我将使用 var h 和h = 10. 要获得坐标 (x,y),假设线尖的坐标是 (x1, y1),您可以这样做(x1+hcosϴ, y1+hsinϴ)。将其用于 中的第三个值drawPolygon(),您应该完成。抱歉,如果我最后有点匆忙,我有点厌倦了打字,如果您需要帮助,请发表评论。

于 2013-07-17T12:46:33.570 回答
1

如果你设法从输入事件中画了一条线,你可能会在它的末端额外画一个三角形来指示方向。

在另一个项目中,每次触摸网格上的磁点时我都会画一个正方形(如您在此处看到的)抱歉,我现在无法为您提供任何示例代码。但是,如果这对您来说是合适的方法,我可能会稍后发布。

于 2013-07-17T10:24:24.403 回答
1

这是一个很好的代码,它不是我的,它是我转换为 Canvas 的 Java Graphics2D 代码。所有功劳归于编写它的原始人/女士

private void drawArrowHead(Canvas canvas, Point tip, Point tail)
{
    double dy = tip.y - tail.y;
    double dx = tip.x - tail.x;
    double theta = Math.atan2(dy, dx);
    int tempX = tip.x ,tempY = tip.y;
    //make arrow touch the circle
    if(tip.x>tail.x && tip.y==tail.y)
    {
        tempX = (tip.x-10);
    }
    else if(tip.x<tail.x && tip.y==tail.y)
    {
        tempX = (tip.x+10);
    }
    else if(tip.y>tail.y && tip.x==tail.x)
    {
        tempY = (tip.y-10);
    }
    else if(tip.y<tail.y && tip.x==tail.x)
    {
        tempY = (tip.y+10);
    }
    else if(tip.x>tail.x || tip.x<tail.x)
    {
        int rCosTheta = (int) ((10)*Math.cos(theta)) ;
        int xx = tip.x - rCosTheta;
        int yy = (int) ((xx-tip.x)*(dy/dx) + tip.y);
        tempX = xx;
        tempY = yy;
    }


    double x, y, rho = theta + phi;
    for(int j = 0; j < 2; j++)
    {
        x = tempX - arrowLength * Math.cos(rho);
        y = tempY - arrowLength  * Math.sin(rho);

        canvas.drawLine(tempX,tempY,(int)x,(int)y,this.paint);
        rho = theta - phi;
    }
}

只需为您的线的两侧调用它,它就会在每一侧绘制一个箭头!

于 2015-07-07T11:40:38.103 回答