2011-08-10 100 views

回答

9

你必须找出数字背后的数学。三角形和星星很容易画出来。下面是你如何绘制一个心脏:http://www.mathematische-basteleien.de/heart.htm

要绘制特殊路径,你应该通过添加点,椭圆等创建它们。画布支持指定路径的剪贴蒙版,因此您可以设置剪贴蒙版的面具,将路径推向矩阵,绘制心脏的内容,然后再次弹出。

这是我在做,以实现对Andriod的模拟2D页面卷曲效果是什么:http://code.google.com/p/android-page-curl/

希望这有助于!

1
+0

我没有得到u.Plz解释我。 –

+0

您需要将复杂的形状分为原始形状。例如,您可以使用两个半圆和两条线来绘制心脏。三角形 - 选择3个点并使用drawLine()连接它们,或者更好地将数组传递给drawLines(); – Im0rtality

21

对于未来的直接回答者,我已经画出了一个几乎对称的明星荷兰国际集团帆布,作为图像中所示:

Star Image

主要工具是用路径。

假设你有设置:

Paint paint = new Paint(); 
paint.setColor(Color.WHITE); 
paint.setAntiAlias(true); 
paint.setStyle(Paint.Style.STROKE); 

Path path = new Path(); 

然后在你的OnDraw你可以像我这样用下面的路径。它可以正确缩放到任何尺寸帆布

@Override 
protected void onDraw(Canvas canvas) { 

    float mid = getWidth()/2; 
    float min = Math.min(getWidth(), getHeight()); 
    float fat = min/17; 
    float half = min/2; 
    float rad = half - fat; 
    mid = mid - half; 

    paint.setStrokeWidth(fat); 
    paint.setStyle(Paint.Style.STROKE); 

    canvas.drawCircle(mid + half, half, rad, paint); 

    path.reset(); 

    paint.setStyle(Paint.Style.FILL); 


     // top left 
     path.moveTo(mid + half * 0.5f, half * 0.84f); 
     // top right 
     path.lineTo(mid + half * 1.5f, half * 0.84f); 
     // bottom left 
     path.lineTo(mid + half * 0.68f, half * 1.45f); 
     // top tip 
     path.lineTo(mid + half * 1.0f, half * 0.5f); 
     // bottom right 
     path.lineTo(mid + half * 1.32f, half * 1.45f); 
     // top left 
     path.lineTo(mid + half * 0.5f, half * 0.84f); 

     path.close(); 
     canvas.drawPath(path, paint); 

    super.onDraw(canvas); 

} 
+2

其他答案倾向于说,你需要在每行之后调用moveTo来创建一个填充的多边形,这对我来说不起作用。谢天谢地,你的答案取得了诀窍! – npace

8

此方法将返回一个路径,其中给定宽度的平方内给定的角数。添加更多的参数来处理小半径等等。

private Path createStarBySize(float width, int steps) { 
    float halfWidth = width/2.0F; 
    float bigRadius = halfWidth; 
    float radius = halfWidth/2.0F; 
    float degreesPerStep = (float) Math.toRadians(360.0F/(float) steps); 
    float halfDegreesPerStep = degreesPerStep/2.0F; 
    Path ret = new Path(); 
    ret.setFillType(FillType.EVEN_ODD); 
    float max = (float) (2.0F* Math.PI); 
    ret.moveTo(width, halfWidth); 
    for (double step = 0; step < max; step += degreesPerStep) { 
     ret.lineTo((float)(halfWidth + bigRadius * Math.cos(step)), (float)(halfWidth + bigRadius * Math.sin(step))); 
     ret.lineTo((float)(halfWidth + radius * Math.cos(step + halfDegreesPerStep)), (float)(halfWidth + radius * Math.sin(step + halfDegreesPerStep))); 
    } 
    ret.close(); 
    return ret; 
} 
+0

这样一个真棒例程没有upvotes!惊人! – rupps

0

如果您需要在正方形内绘制星形,可以使用下面的代码。

posXposY是围绕恒星尖端的正方形左上角的坐标(正方形实际上未绘制)。

size是正方形的宽度和高度。

a是明星的顶尖。路径顺时针创建。

这绝不是一个完美的解决方案,但它可以很快完成工作。

public void drawStar(float posX, float posY, int size, Canvas canvas){ 

      int hMargin = size/9; 
      int vMargin = size/4; 

      Point a = new Point((int) (posX + size/2), (int) posY); 
      Point b = new Point((int) (posX + size/2 + hMargin), (int) (posY + vMargin)); 
      Point c = new Point((int) (posX + size), (int) (posY + vMargin)); 
      Point d = new Point((int) (posX + size/2 + 2*hMargin), (int) (posY + size/2 + vMargin/2)); 
      Point e = new Point((int) (posX + size/2 + 3*hMargin), (int) (posY + size)); 
      Point f = new Point((int) (posX + size/2), (int) (posY + size - vMargin)); 
      Point g = new Point((int) (posX + size/2 - 3*hMargin), (int) (posY + size)); 
      Point h = new Point((int) (posX + size/2 - 2*hMargin), (int) (posY + size/2 + vMargin/2)); 
      Point i = new Point((int) posX, (int) (posY + vMargin)); 
      Point j = new Point((int) (posX + size/2 - hMargin), (int) (posY + vMargin)); 

      Path path = new Path(); 
      path.moveTo(a.x, a.y); 
      path.lineTo(b.x, b.y); 
      path.lineTo(c.x, c.y); 
      path.lineTo(d.x, d.y); 
      path.lineTo(e.x, e.y); 
      path.lineTo(f.x, f.y); 
      path.lineTo(f.x, f.y); 
      path.lineTo(g.x, g.y); 
      path.lineTo(h.x, h.y); 
      path.lineTo(i.x, i.y); 
      path.lineTo(j.x, j.y); 
      path.lineTo(a.x, a.y); 

      path.close(); 

      canvas.drawPath(path, paint); 
} 
8

对于大家,需要心脏形状:

import android.content.Context; 
    import android.graphics.Canvas; 
    import android.graphics.Color; 
    import android.graphics.Paint; 
    import android.graphics.Paint.Style; 
    import android.graphics.Path; 
    import android.view.View; 

    public class Heart extends View { 

     private Path path; 

     private Paint paint; 

     public Heart(Context context) { 
      super(context); 

      path = new Path(); 
      paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     } 

      @Override 
      protected void onDraw(Canvas canvas) { 
       super.onDraw(canvas); 

       // Fill the canvas with background color 
       canvas.drawColor(Color.WHITE); 
       paint.setShader(null); 

       float width = getContext().getResources().getDimension(R.dimen.heart_width); 
       float height = getContext().getResources().getDimension(R.dimen.heart_height); 

       // Starting point 
       path.moveTo(width/2, height/5); 

       // Upper left path 
       path.cubicTo(5 * width/14, 0, 
         0, height/15, 
         width/28, 2 * height/5); 

       // Lower left path 
       path.cubicTo(width/14, 2 * height/3, 
         3 * width/7, 5 * height/6, 
         width/2, height); 

       // Lower right path 
       path.cubicTo(4 * width/7, 5 * height/6, 
         13 * width/14, 2 * height/3, 
         27 * width/28, 2 * height/5); 

       // Upper right path 
       path.cubicTo(width, height/15, 
         9 * width/14, 0, 
         width/2, height/5); 

       paint.setColor(Color.RED); 
       paint.setStyle(Style.FILL); 
       canvas.drawPath(path, paint); 

      } 
    } 

对不起,所有的数字,但这些工作对我最好的:)结果看起来是这样的:

enter image description here

+0

裁剪图像.. – Prabs

0

它很好用Shape类的实例))

@Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    HeartShape shape = new HeartShape(); 
    ShapeDrawable shapeDrawable = new ShapeDrawable(shape); 
    shapeDrawable.setColorFilter(new LightingColorFilter(0, Color.BLUE)); 

    LinearLayout linearLayout = new LinearLayout(this); 
    linearLayout.setLayoutParams(new LinearLayout.LayoutParams(350 * 3, 350 * 3)); 
    linearLayout.setBackground(shapeDrawable); 

    setContentView(linearLayout); 
    } 

创建一个形状类是渲染好的心

public class HeartShape extends Shape { 

    private final int INVALID_SIZE = -1; 

    private Path mPath = new Path(); 
    private RectF mRectF = new RectF(); 

    private float mOldWidth = INVALID_SIZE; 
    private float mOldHeight = INVALID_SIZE; 

    private float mScaleX, mScaleY; 

    public HeartShape() { 

    } 

    @Override 
    public void draw(Canvas canvas, Paint paint) { 
    canvas.save(); 
    canvas.scale(mScaleX, mScaleY); 

    float width = mRectF.width(); 
    float height = mRectF.height(); 

    float halfWidth = width/2; 
    float halfHeight = height/2; 

    float stdDestX = 5 * width/14; 
    float stdDestY = 2 * height/3; 

    PointF point1 = new PointF(stdDestX, 0); 
    PointF point2 = new PointF(0, height/15); 
    PointF point3 = new PointF(stdDestX/5, stdDestY); 
    PointF point4 = new PointF(stdDestX, stdDestY); 

    // Starting point 
    mPath.moveTo(halfWidth, height/5); 

    mPath.cubicTo(point1.x, point1.y, point2.x, point2.y, width/28, 2 * height/5); 
    mPath.cubicTo(point3.x, point3.y, point4.x, point4.y, halfWidth, height); 

    canvas.drawPath(mPath, paint); 

    canvas.scale(-mScaleX, mScaleY, halfWidth, halfHeight); 
    canvas.drawPath(mPath, paint); 

    canvas.restore(); 
    } 

    @Override 
    protected void onResize(float width, float height) { 
    mOldWidth = mOldWidth == INVALID_SIZE ? width : Math.max(1, mOldWidth); 
    mOldHeight = mOldHeight == INVALID_SIZE ? height : Math.max(1, mOldHeight); 

    width = Math.max(1, width); 
    height = Math.max(1, height); 

    mScaleX = width/mOldWidth; 
    mScaleY = height/mOldHeight; 

    mOldWidth = width; 
    mOldHeight = height; 


    mRectF.set(0, 0, width, height); 
    } 

    @Override 
    public void getOutline(@NonNull Outline outline) { 
    // HeartShape not supported outlines 
    } 

    @Override 
    public HeartShape clone() throws CloneNotSupportedException { 
    HeartShape shape = (HeartShape) super.clone(); 
    shape.mPath = new Path(mPath); 
    return shape; 
    } 

} 

enter image description here