2012-04-14 20 views
7

THANKS Torious, đã nhận nó:Làm một ma trận cho một smuge/effet dao động (xem hình ảnh) trong Android

private void smudge() { 


     for (int i = 0; i < COUNT*2; i += 2) { 

      float xOriginal = matrixOriganal[i+0]; 
      float yOriginal = matrixOriganal[i+1]; 

      float distX = Math.abs(pointX-xOriginal); 
      float distY = Math.abs(pointY-yOriginal); 

      float dist = FloatMath.sqrt(distX*distX + distY*distY); 

      float coof = (bubbleSize - dist)/bubbleSize; 

     float oc = (float) -Math.sin(coof * 2*Math.PI) * 0.15f ; 

      if (dist < bubbleSize) 
      { 
      matrixVertsMoved[i+0] = xOriginal + smudgeAmount * (coof+oc); 
      matrixVertsMoved[i+1] = yOriginal; 
      } 
      else 
      { 
      matrixVertsMoved[i+0] = xOriginal; 
      matrixVertsMoved[i+1] = yOriginal; 
      } 


     } 

     invalidate(); 
    } 

cũ: Ngay bây giờ tôi có mã này Tôi đã thực hiện dựa trên mẫu api đi kèm với SDK.

public class main extends Activity { 

    //////////////////////////////////////////////////////// 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
     setContentView(R.layout.main); 

     LinearLayout ll01 = (LinearLayout)findViewById(R.id.linearLayout1); 

     SampleView sv = new SampleView(this); 
     ll01.addView(sv); 
    } 

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

    private static class SampleView extends View { 
     static int WIDTH = 8; // sections 
     static int HEIGHT = 8; 
     static int COUNT = (WIDTH + 1) * (HEIGHT + 1); // total verts count 

     Bitmap mBitmap; // declaring a bitmap 
     float[] matrixVertsMoved = new float[COUNT*2]; // declaring an array with double amount of vert count, one for x and one for y 
     float[] matrixOriganal = new float[COUNT*2]; 

     float clickX; 
     float clickY; 

     static void setXY(float[] array, int index, float x, float y) { 
      array[index*2 + 0] = x; 
      array[index*2 + 1] = y; 
     } 

     /// 

     public SampleView(Context context) { 
      super(context); 
      setFocusable(true); 

      mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.w); 


      // construct our mesh 
      int index = 0; 
      for (int y = 0; y <= HEIGHT; y++) { 
       float fy = mBitmap.getHeight() * y/HEIGHT; 

       for (int x = 0; x <= WIDTH; x++) { 
        float fx = mBitmap.getWidth() * x/WIDTH; 
        setXY(matrixVertsMoved, index, fx, fy); 
        setXY(matrixOriganal, index, fx, fy); 
        index += 1; 
       } 

      } 

     } 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

     @Override 
     protected void onDraw(Canvas canvas) { 


      canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, matrixVertsMoved, 0, null, 0, null); 

      Paint p1 = new Paint(); 
      p1.setColor(0x660000FF); 

      Paint p2 = new Paint(); 
      p2.setColor(0x99FF0000); 

      Paint p3 = new Paint(); 
      p3.setColor(0xFFFFFB00); 

      for (int i = 0; i < COUNT*2; i += 2) { 
       float x = matrixOriganal[i+0]; 
       float y = matrixOriganal[i+1]; 
       canvas.drawCircle(x, y, 4, p1); 

       float x1 = matrixOriganal[i+0]; 
       float y1 = matrixOriganal[i+1]; 
       float x2 = matrixVertsMoved[i+0]; 
       float y2 = matrixVertsMoved[i+1]; 
       canvas.drawLine(x1, y1, x2, y2, p1); 
      } 

      for (int i = 0; i < COUNT*2; i += 2) { 
       float x = matrixVertsMoved[i+0]; 
       float y = matrixVertsMoved[i+1]; 
       canvas.drawCircle(x, y, 4, p2); 
      } 

      canvas.drawCircle(clickX, clickY, 6, p3); 


     } 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

     private void smudge() { 


      for (int i = 0; i < COUNT*2; i += 2) { 

       float xOriginal = matrixOriganal[i+0]; 
       float yOriginal = matrixOriganal[i+1]; 

       float dist_click_to_origin_x = clickX - xOriginal; // distance from current vertex in the original matrix to the place clicked. 
       float dist_click_to_origin_y = clickY - yOriginal; 

       float kv_kat = dist_click_to_origin_x*dist_click_to_origin_x + dist_click_to_origin_y*dist_click_to_origin_y; 

       float pull = (1000000/kv_kat/FloatMath.sqrt(kv_kat)); 

       if (pull >= 1) { 
        matrixVertsMoved[i+0] = clickX; 
        matrixVertsMoved[i+1] = clickY; 
       } else { 
        matrixVertsMoved[i+0] = xOriginal + dist_click_to_origin_x * pull; 
        matrixVertsMoved[i+1] = yOriginal + dist_click_to_origin_y * pull; 
       } 

      } 


     } 


//////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

     @Override 
     public boolean onTouchEvent(MotionEvent event) { 

       clickX = event.getX(); 
       clickY = event.getY(); 
       smudge(); // change the matrix. 
       invalidate(); // calls a redraw on the canvas. 

      return true; 
     } 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

    } 

Điều quan trọng là chức năng quấn ở cuối. Đây là những gì nó tạo ra.

// chấm màu xanh dương là các đỉnh của ma trận gốc, trong khi các chấm màu đỏ cho biết cách chúng di chuyển từ nhấp chuột (dấu chấm màu vàng).

enter image description here

Tuy rằng tôi cần là nó không véo ở một đỉnh, nhưng để sắp xếp các vết bẩn nó, như thế này.

enter image description here

Ví dụ, chức năng smudge này có thể kéo dài trong pixel hoặc đỉnh tọa độ từ bắt đầu từ đâu dấu mờ, x và y bù đắp và sức mạnh của các vết bẩn, ví dụ: cách cứng nên là các đỉnh xung quanh bị ảnh hưởng.

Bất kỳ ý tưởng nào về cách thực hiện điều đó?

chỉnh sửa: về cơ bản tôi đang cố gắng để làm một cái gì đó tương tự như http://www.andwobble.com/

Cảm ơn!

Trả lời

2

Ok, tôi có bản trình diễn (Flash) hoạt động giống như những gì bạn cần.

Tôi chưa chuyển đổi lưới kết cấu, nhưng chỉ có các đỉnh, do đó khó xác minh xem hiệu quả có đúng như dự định hay không, nhưng có vẻ là một bước đi đúng hướng.

Dù sao, đây là mã; nó ở AS3 nhưng tôi nghi ngờ nó sẽ khó hiểu.

Một số lưu ý:

  • CENTER trong các mã dưới đây sẽ là điểm khởi đầu của hoạt động smudge, như bạn mô tả nó ở trên. controlPoint sẽ là điểm kết thúc.
  • Tôi đang sử dụng Vector3D, nhưng chỉ sử dụng tọa độ 2D của nó.
  • CENTER, controlPoint và đầu vào vertex được coi như trong cùng một hệ tọa độ. Thay vào đó, bạn có thể xử lý trước CENTER để liên quan đến hệ thống tọa độ cục bộ của lưới của bạn. Sau đó, bạn có thể tách các biến đổi thành/từ hệ tọa độ tương đối/cục bộ trong mã bên dưới.
  • Chức năng hậu cần được sử dụng để chuyển đổi từ rìa của vòng tròn ảnh hưởng mà không ảnh hưởng, ảnh hưởng đầy đủ. Bạn có thể sử dụng một số chức năng khác cho hiệu ứng tương tự.
  • Tôi nghĩ rằng việc sử dụng thao tác "kéo đến điểm kiểm soát" thứ hai bổ sung với cường độ nhỏ hơn và chuyển tiếp ít dốc hơn sẽ làm cho hiệu ứng tốt hơn; ngay bây giờ tất cả các đỉnh được chuyển hoàn toàn sang (gần) 100% ảnh hưởng di chuyển về phía điểm điều khiển một chút quá nhiều trong unison, tôi cảm thấy.

Hãy dùng thử và cho tôi biết nếu bạn gặp khó khăn khi hiểu mã AS3.

private function log(t:Number):Number { 
     return 1/(1 + Math.pow(Math.E, -t)); 
    } 

    private function transformVertex(vertex:Vector3D, controlPoint:Vector3D):Vector3D { 

     // get control point relative to center of influence 
     // (this could actually be calculated in pre-processing, as 
     // it doesn't change between vertices) 
     var controlPointRel:Vector3D = controlPoint.subtract(CENTER); 

     // get vertex relative to center of influence 
     var rel:Vector3D = vertex.subtract(CENTER); 

     // get distance of vertex from center 
     var dst:Number = rel.length/RADIUS; 
     if (dst > 1) return vertex; // vertex outside circle of influence 


     // PULL TO CONTROL POINT 

     // tScale controls the steepness of the transition from the 
     // edge of the circle. 1 = logistic transition, >1 = steeper 
     var tScale:Number = 1.7; 
     var t:Number = (1 - dst) * 12 * tScale - 6; // [-6, 6] 
     t = log(t); 

     controlPointRel = controlPointRel.clone(); 
     controlPointRel.scaleBy(t); 
     // ALTERNATIVE, try this too: 
     // controlPointRel.scaleBy(t * (1 - dst)); 

     rel = rel.add(controlPointRel); 

     // relative to absolute 
     return rel.add(CENTER); 

    } 
+0

Cảm ơn, trong khi đó, tôi chủ yếu tìm ra chức năng ban đầu là gì. Xem mã đã chỉnh sửa với các nhận xét ở trên. :) –

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