2011-08-10 30 views

Respuesta

9

Tienes que averiguar las matemáticas detrás de esas cifras. El triángulo y la estrella son bastante fáciles de dibujar. Así es como puedes dibujar un corazón: http://www.mathematische-basteleien.de/heart.htm

Para dibujar caminos especiales, debes crearlos agregando puntos, elipses, etc. El lienzo admite una máscara de recorte de una ruta especificada, para que puedas configurar la máscara de recorte de un corazón , empuja los caminos hacia la matriz, dibuja el contenido del corazón y luego vuelve a abrirlo.

Eso es lo que estoy haciendo para lograr una página 2D efecto rizo simulada en Andriod: http://code.google.com/p/android-page-curl/

Espero que esto ayude!

1
+0

No te entendí. Por favor, explícame. –

+0

Necesita dividir formas complejas en primitivas. Por ejemplo, puedes dibujar un corazón usando dos medios círculos y dos líneas. Triángulo: seleccione 3 puntos y conéctelos con drawLine() o incluso mejor pase los puntos de pf array a drawLines(); – Im0rtality

21

Para futuros buscadores de respuesta directa, he dibujado una estrella casi simétrica nosotros ing lienzo, como se muestra en la imagen:

Star Image

La herramienta principal es el uso de rutas.

Asumiendo que tienen configuración:

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

Path path = new Path(); 

Luego, en que OnDraw se puede utilizar la ruta de como lo hago a continuación. Se escalará adecuadamente a cualquier tamaño de lienzo

@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

Otras respuestas tienden a decir que debe llamar a moveTo después de cada línea a para crear un polígono lleno, que no funcionó para mí. Afortunadamente, tu respuesta hizo el truco! – npace

8

este método devolverá un camino con el número de esquinas dadas dentro de un cuadrado de la anchura dada. Agregue más parámetros para manejar un radio pequeño y cosas por el estilo.

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

¡cómo una rutina tan increíble no tiene votos ascendentes! ¡Asombroso! – rupps

0

Si necesita dibujar una estrella dentro de un cuadrado, puede usar el siguiente código.

posX y posY son las coordenadas de la esquina superior izquierda del cuadrado que encierra las puntas de la estrella (el cuadrado no se dibuja realmente).

size es el ancho y la altura del cuadrado.

a es la punta superior de la estrella. La ruta se crea en el sentido de las agujas del reloj.

Esto no es una solución perfecta, pero hace el trabajo muy rápidamente.

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

Para todo el mundo que necesita una forma de corazón:

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

      } 
    } 

Lo siento por todos los números, pero estos funcionaban mejor para mí :) El resultado es idéntico:

enter image description here

+0

recortar la imagen ... – Prabs

0

Es muy bueno usar la instancia de la clase 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); 
    } 

crear una clase de forma, que era agradable render corazón

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

Cuestiones relacionadas