2015-11-02 26 views
4

以下问题可能听起来有点愚蠢,但我猜愚蠢没有限制,所以在这里。我在Android中使用Canvas绘制心脏,并没有绘制心脏的问题,但我无法在会议中使心脏变得锐利。我的心脏看起来像enter image description here在Android中用尖角绘制一颗心

CODE:

  left_x_moveto = 200; 
      left_y_moveto = 45; 

      left_x1 = 197; 
      left_y1 = -35; 
      left_x2 = 60; 
      left_y2 = 20; 
      left_x3 = 193; 
      left_y3 = 130; 

      right_x_moveto = 200; 
      right_y_moveto = 45; 

      right_x1 = 197; 
      right_y1 = -35; 
      right_x2 = 345; 
      right_y2 = 20; 
      right_x3 = 193; 
      right_y3 = 130; 



      heart_outline_paint.setColor(getResources().getColor(R.color.heart_outline_color)); // Change the boundary color 
     heart_outline_paint.setStrokeWidth(15); 
     heart_outline_paint.setStyle(Paint.Style.STROKE); 

     path.moveTo(left_x_moveto, left_y_moveto); 
     path.cubicTo(left_x1, left_y1, left_x2, left_y2, left_x3, left_y3); 

     path.moveTo(right_x_moveto, right_y_moveto); 
     path.cubicTo(right_x1, right_y1, right_x2, right_y2, right_x3, right_y3); 
     canvas.drawPath(path, heart_outline_paint); 

有什么我试过到目前为止:

  1. 减少或增加的left_x_movetoleft_y_moveto点,反之亦然,但心脏是完全毁容的,我无法找到原因。

right_x_moveto = 198right_y_moveto = 45,心脏看起来像

enter image description here

我不知道为什么会这样。

  • 减小heart_outline_paint的宽度会给我我想要什么,但我想厚度的心脏的如此降低setStrokeWidth同样不是一个选项。
  • 总之,我想无论是曲线MEET和合并并不仅仅是MEET。 任何帮助将不胜感激。提前致谢。

    +0

    你有没有尝试使用[Path.close()](http://developer.android.com/intl/es/reference /android/graphics/Path.html#close())? –

    +0

    不,我在哪里关闭它?在drawPath之后? – San

    +0

    是的,我会尽力。 –

    回答

    5

    您需要执行一些此操作。

    1. 关闭通过path.close()的路径。
    2. 您需要设置行程加入通过heart_outline_paint.setStrokeJoin(Paint.Join.MITER);

    一个path只有当它连续引出关闭。因此,我修改了代码,以便path.close()可以正确完成。以下是代码。

    protected void onDraw(Canvas canvas) { 
        super.onDraw(canvas); 
    
        heart_outline_paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
        heart_outline_paint.setStrokeJoin(Paint.Join.MITER); 
        path = new Path(); 
    
        int left_x_moveto = 200; 
        int left_y_moveto = 45; 
    
        int left_x1 = 180; 
        int left_y1 = -20; 
        int left_x2 = 30; 
        int left_y2 = 20; 
        int left_x3 = 193; 
        int left_y3 = 130; 
    
        int right_x_moveto = 200; 
        int right_y_moveto = 45; 
    
        int right_x1 = 214; 
        int right_y1 = -20; 
        int right_x2 = 375; 
        int right_y2 = 20; 
        int right_x3 = 193; 
        int right_y3 = 130; 
    
        heart_outline_paint.setColor(Color.RED); // Change the boundary color 
        heart_outline_paint.setStrokeWidth(15); 
        heart_outline_paint.setStyle(Paint.Style.STROKE); 
    
        path.moveTo(left_x_moveto, left_y_moveto); 
        path.cubicTo(left_x1, left_y1, left_x2, left_y2, left_x3, left_y3); 
        path.cubicTo(right_x2, right_y2, right_x1, right_y1, right_x_moveto, right_y_moveto); 
    
        path.close(); 
    
        canvas.drawPath(path, heart_outline_paint); 
    } 
    

    Paint.Join.MITER是你想要做什么的人。以锐角

    联接相遇的

    外边缘现在这个MITER加入作品仅当该角度< = 90度。但在此,根据您提供的值,角度为90度,因此MITER连接不起作用。我已经修改了这些值以获得以下图像。图像不是确切的,但你需要玩的价值得到正确的。
    enter image description here


    您可以设置ROUND join方法得到以下。
    enter image description here

    问题出在​​。很难让MITTER加入工作,而不会让心脏形状变​​形。因此,我试着用lineToarcTo来代替cubicTo来创建一个简单的心脏。以下是该代码。您会注意到我已将画布旋转至45度,然后绘制出心形。这纯粹是为了方便,所以坐标很简单,不涉及毕达哥拉斯定理。

    protected void onDraw(Canvas canvas) { 
        super.onDraw(canvas); 
    
        heart_outline_paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
        heart_outline_paint.setStrokeJoin(Paint.Join.MITER); 
        heart_outline_paint.setColor(Color.RED); // Change the boundary color 
        heart_outline_paint.setStrokeWidth(15); 
        heart_outline_paint.setStyle(Paint.Style.STROKE); 
        path = new Path(); 
    
        float length = 100; 
        float x = canvas.getWidth()/2; 
        float y = canvas.getHeight()/2; 
    
        canvas.rotate(45,x,y); 
    
        path.moveTo(x,y); 
        path.lineTo(x-length, y); 
        path.arcTo(new RectF(x-length-(length/2),y-length,x-(length/2),y),90,180); 
        path.arcTo(new RectF(x-length,y-length-(length/2),x,y-(length/2)),180,180); 
        path.lineTo(x,y); 
        path.close(); 
    
        canvas.drawPath(path, heart_outline_paint); 
    } 
    

    这段代码的最终渲染图像低于:
    enter image description here

    +0

    谢谢你付出的努力,意味着很多!我会改变像我需要的点,但你已经完成了一个伟大的工作..帽子掉队.. – San

    +0

    我已经使用'lineTo'和'arcTo',绘制一个心脏形状与'MITTER'加入按预期工作。为了简单起见,我已将所有内容都放在'onDraw'方法中。您应该将'path'和'paint'创建移动到构造函数中。 – Henry

    +0

    采取点,感谢您的意见。 – San

    0

    发生什么事情是线的厚度是在一边画,而不是在两边。在真正的MS漆时尚:

    (左边是发生了什么,右边是你想要的。黑色是线的实际位置将宽度为1px,红色是“填充”,第二,第三到第十五像素,heart_outline_paint.setStrokeWidth(15);enter image description here

    要解决此问题,请尝试从右边的x线中减去该线的宽度的一半,然后将其添加到左边的x线。这样做将解决此问题,而不是修复它

    +0

    通过说“线的宽度”,你指的是我需要用我用来绘制心脏的点来做点什么吗? – San

    +0

    是的。我的意思是,在这种情况下,'right_x3'应该变成'right_x3 - (15/2)'(15因为'heart_outline_paint.setStrokeWidth(15);'),'left_x3'应该变成'left_x3 +(15/2) '。如上所述,这是一个解决方法,而不是解决方法。 –

    +0

    当我尝试的时候,我得到了 - http://prntscr.com/8y3jtg – San