在android中绘制一个箭头

时间:2013-07-17 10:09:51

标签: android android-imageview android-canvas

我正在尝试绘制一个箭头指向上图中的对象。我已经能够编写代码来绘制线但是似乎无法找到绘制箭头的方法。我写的用于绘制可拖动线的代码如下。我需要在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部分得到了帮助

3 个答案:

答案 0 :(得分: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()中的第三个值,您应该完成。对不起,如果我有点匆匆忙忙,我有点厌倦打字,如果你需要帮助就做评论。

答案 1 :(得分:1)

如果您设法从输入事件中绘制一条线,您可能还会在其末端绘制一个指示方向的三角形。

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

答案 2 :(得分: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;
    }
}

只需在你的线的两侧调用它,它就会在每一侧画一个箭头!