1. 程式人生 > >Android 判斷一個點是否在封閉的Path內或不規則的圖形內

Android 判斷一個點是否在封閉的Path內或不規則的圖形內

最近在寫畫板程式,要判斷一個點在一個閉合的path內或者是一個不規則的圖形內,這個可不好解決網上查了一堆有算法雲雲的,直到看到一個大神的帖子 其實可以相當的簡單幾句話的是 核心程式碼:

//------關鍵部分 判斷點是否在 一個閉合的path內--------//
            if(event.getAction()==MotionEvent.ACTION_DOWN){
                //構造一個區域物件,左閉右開的。  
                RectF r=new RectF();  
                //計算控制點的邊界  
                mPath.computeBounds(r, true);  
                //設定區域路徑和剪輯描述的區域  
                re.setPath(mPath, new Region((int)r.left,(int)r.top,(int)r.right,(int)r.bottom));  
                //判斷觸控點是否在封閉的path內 在返回true 不在返回false
                Log.e("","--判斷點是否則範圍內----"+re.contains((int)event.getX(), (int)event.getY()));
              }  

主要是用了 mPath.computeBounds(r, true);來計算邊界 產生Region來判斷

 全部示例程式碼:

package com.example.touchtest;
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View; 

public class TestView extends View{ 
     //----繪製軌跡----
    private float mX;  
    private float mY;   
    private final Paint mGesturePaint = new Paint();  
    private final Path mPath = new Path();  
    //------檢測點是否在path內
    private boolean isDraw=false;
    Region re=new Region();
    
    public TestView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGesturePaint.setColor(context.getResources().getColor(android.R.color.holo_green_dark));
        mGesturePaint.setStyle(Paint.Style.STROKE); 
        mGesturePaint.setStrokeWidth(4.0f);
    } 
    public TestView(Context context) {
        super(context);
        mGesturePaint.setColor(context.getResources().getColor(android.R.color.holo_green_dark));
        mGesturePaint.setStyle(Paint.Style.STROKE); 
        mGesturePaint.setStrokeWidth(4.0f);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawPath(mPath, mGesturePaint); 
    } 
    
    @Override  
    public boolean onTouchEvent(MotionEvent event)  
    {
        if(isDraw){
            //------關鍵部分 判斷點是否在 一個閉合的path內--------//
            if(event.getAction()==MotionEvent.ACTION_DOWN){
                //構造一個區域物件,左閉右開的。  
                RectF r=new RectF();  
                //計算控制點的邊界  
                mPath.computeBounds(r, true);  
                //設定區域路徑和剪輯描述的區域  
                re.setPath(mPath, new Region((int)r.left,(int)r.top,(int)r.right,(int)r.bottom));  
                //在封閉的path內返回true 不在返回false
                Log.e("","--判斷點是否則範圍內----"+re.contains((int)event.getX(), (int)event.getY()));
              }  
             return true;
          } 
        switch (event.getAction())  
        {  
            case MotionEvent.ACTION_DOWN:   
                  touchDown(event);
                 break;  
            case MotionEvent.ACTION_MOVE:  
                touchMove(event);  
                break;
            case MotionEvent.ACTION_UP: 
                mPath.close(); 
                isDraw=true; 
                break;
        }  
        //更新繪製  
        invalidate();  
        return true; 
    } 
    
  //---------------下邊是劃線部分----------------------------//  
    //手指點下螢幕時呼叫  
    private void touchDown(MotionEvent event)  
    {   
        //重置繪製路線,即隱藏之前繪製的軌跡  
        mPath.reset();  
        float x = event.getX();  
        float y = event.getY(); 
        mX = x;  
        mY = y;    
        mPath.moveTo(x, y);  
    }   
    //手指在螢幕上滑動時呼叫  
   private void touchMove(MotionEvent event)  
    {  
        final float x = event.getX();  
        final float y = event.getY();   
        final float previousX = mX;  
        final float previousY = mY;   
        final float dx = Math.abs(x - previousX);  
        final float dy = Math.abs(y - previousY); 
        //兩點之間的距離大於等於3時,連線連線兩點形成直線  
        if (dx >= 3 || dy >= 3)  
        {  
            //兩點連成直線  
            mPath.lineTo(x, y);   
            //第二次執行時,第一次結束呼叫的座標值將作為第二次呼叫的初始座標值  
            mX = x;  
            mY = y;  
        }  
    }  
}

                                                                               執行

經測試可以很準確的判斷 touch觸控點是否在上邊繪製不規則圖形內,搞繪圖的小夥伴們趕緊拿去開心的玩耍吧!哈哈

總結:技術是個不斷積累的過程,對一個平臺的熟悉程度決定了你的實現能力和快速解決問題的能力。萬能的百度當然可以 但是也要有人去摸索分享出來 大家才能收益,感謝大神的分享精神 原文地址:http://blog.csdn.net/havakey/article/details/6649553 

不斷學習不斷積累,苦逼IT男的必由之路。