2011-08-10 115 views
9

Tôi có thể vẽ hình tròn và hình chữ nhật trên canvas bằng cách sử dụng path.addCircle() và path.addRect(). Giống như tôi muốn chạm vào i am để vẽ hình tam giác, sao, vuông và tim. Tôi có thể làm như thế nào? Hãy cho tôi một cách với ví dụ mẫu. Cảm ơnandroid cách vẽ hình tam giác, sao, hình vuông, trái tim trên canvas

+0

Hey nickfrancis.me, tôi muốn làm điều tương tự. Bạn có thể vui lòng chia sẻ mã với tôi không? Cảm ơn. – anddev

Trả lời

9

Bạn phải tìm hiểu toán học đằng sau con số đó. Hình tam giác và ngôi sao khá dễ vẽ. Đây là cách bạn có thể vẽ một trái tim: http://www.mathematische-basteleien.de/heart.htm

Để vẽ các đường dẫn đặc biệt, bạn nên tạo chúng bằng cách thêm điểm, dấu ba chấm, vv Vải sẽ hỗ trợ cắt mặt nạ của một con đường cụ thể, để bạn có thể đặt mặt nạ cắt của trái tim , đẩy các đường dẫn đến ma trận, vẽ nội dung của trái tim và sau đó bật lại.

Đó là những gì tôi đang làm để đạt được một trang 2D hiệu lực thi hành curl mô phỏng trên Andriod: http://code.google.com/p/android-page-curl/

Hope this helps!

1
+0

Tôi không nhận được u.Plz giải thích cho tôi. –

+0

Bạn cần chia các hình dạng phức tạp thành các hình dạng nguyên thủy. Ví dụ bạn có thể vẽ trái tim bằng cách sử dụng hai nửa vòng tròn và hai dòng. Tam giác - chọn 3 điểm và kết nối chúng với drawLine() hoặc thậm chí vượt qua các điểm pf mảng tới drawline(); – Im0rtality

21

Đối người tìm kiếm câu trả lời trực tiếp trong tương lai, tôi đã vẽ một ngôi sao gần như đối xứng với chúng tôi ing vải, như thể hiện trong hình ảnh:

Star Image

Công cụ chính được sử dụng Paths.

Giả sử bạn đã thiết lập:

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

Path path = new Path(); 

Sau đó, trong bạn OnDraw bạn có thể sử dụng đường dẫn như tôi làm dưới đây. Nó sẽ mở rộng đúng kích thước cho bất kỳ kích thước nào canvas

@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

Các câu trả lời khác có xu hướng nói rằng bạn cần phải gọi moveTo sau mỗi dòngĐể tạo một đa giác được điền, không hoạt động đối với tôi. Rất may, câu trả lời của bạn đã thực hiện thủ thuật! – npace

8

phương pháp này sẽ trả về một đường với số góc được đặt trong một hình vuông có chiều rộng nhất định. Thêm các thông số khác để xử lý bán kính nhỏ và những thứ như vậy.

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

làm thế nào một thói quen tuyệt vời như vậy không có upvotes! Kinh ngạc! – rupps

0

Nếu bạn cần vẽ một ngôi sao bên trong hình vuông, bạn có thể sử dụng mã bên dưới.

posXposY là tọa độ cho góc trên bên trái của hình vuông bao quanh các đầu của ngôi sao (hình vuông không thực sự được vẽ).

size là chiều rộng và chiều cao của hình vuông.

a là đỉnh đầu của ngôi sao. Đường dẫn được tạo theo chiều kim đồng hồ.

Đây không phải là giải pháp hoàn hảo, nhưng công việc này được thực hiện rất nhanh chóng.

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

Đối với tất cả mọi người rằng cần có một hình trái tim:

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

      } 
    } 

Xin lỗi vì tất cả những con số nhưng những làm việc tốt nhất cho tôi :) Kết quả trông như thế này:

enter image description here

+0

cắt hình ảnh .. – Prabs

0

Rất tốt để sử dụng thể hiện của lớp 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); 
    } 

Tạo một lớp hình dạng mà là làm đẹp Tim

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

Các vấn đề liên quan