2013-09-26 2 views
2

enter image description hereКак нарисовать линию между двумя точками на изображении в android?

привет всем, У меня есть этот образ, и я хочу, чтобы нарисовать линию «путь» между двумя точками.

то, что я пробовал:

это сделать путь, используя основную точку, которая является сохранение в базе данных. «x, y для точки» и провести линию между несколькими точками до достижения конечной точки. как на изображении № 2 enter image description here

Я думаю, что если я делю изображение на квадратную сетку, например 15 * 15, и даю каждому квадрату x, y, тег, где тег может быть 0,1, что означает стена или любая вещь 0 не может ходить бросить его 1 u может. и создайте ванну динамически.

вот и все, что у меня есть на данный момент :), если есть какой-то другой способ, я этого не знаю. плз помогите мне :)

Update:

-Пользователь может увеличивать/уменьшать. -что я пытаюсь сделать, это что-то вроде this

ответ

2

Вы можете использовать класс Path. Удачи!

3

Вы можете изменить Bitmap напрямую, или вы можете поместить SurfaceView поверх растрового изображения и нарисовать на SurfaceView. Все, что вам нужно сделать в этом сценарии, - это нарисовать ваши линии в методе onDrawSurfaceView.

Я рисую много строк в моем Turtle Draw приложения ... вот как я расширяю SurfaceView

public class DrawView extends SurfaceView { 

    Paint paint = new Paint(); 

    List <float[]> lines = new ArrayList <float[]>(); 
    List <Integer> colors = new ArrayList <Integer>(); 
    int curColor = Color.WHITE; 
    int bgColor = Color.BLACK; 

    Bitmap mBitmap; 

    ImageView turtle; 

    float curX, curY, curTurn = 0f; 

    Matrix transform = new Matrix(); 

    public DrawView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     mBitmap = getBitmapFromDrawable(context); 
     paint.setColor(Color.BLACK); 
     paint.setStrokeWidth(DpiUtils.getPxFromDpi(getContext(), 2)); 
     setScrollContainer(true); 
     // clear(); 
    } 

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

    } 

    public void addLine(float...l) { 
     synchronized(lines) { 
      lines.add(l); 
      colors.add(curColor); 
     } 
    } 

    public List <float[]> getLines() { 
     return lines; 
    } 

    public List <Integer> getColors() { 
     return colors; 
    } 

    @Override 
    public void onDraw(final Canvas canvas) { 

     synchronized(lines) { 
      super.onDraw(canvas); 
      int i = 0; 
      for (float[] l: lines) { 
       paint.setAntiAlias(true); 
       paint.setColor(colors.get(i++)); 
       canvas.drawLines(l, paint); 
       curX = l[2]; 
       curY = l[3]; 
      } 

      transform.setTranslate(curX - 13, curY - 13); 
      transform.preRotate(360 - curTurn, 13, 13); 

      paint.setColor(Color.BLACK); 
      canvas.drawBitmap(mBitmap, transform, paint); 
     } 
    } 

    public void setTurn(float turn) { 
     this.curTurn = turn; 
    } 

    public void clear() { 
     lines.clear(); 
     colors.clear(); 
     DisplayMetrics metrics = DpiUtils.getDisplayMetrics(getContext()); 

     curX = metrics.widthPixels/2f; 
     curY = (metrics.heightPixels/2f) - DpiUtils.getPxFromDpi(getContext(), 50); 
     curTurn = 0; 

     scrollTo(0, 0); 
    } 

    public static Bitmap getBitmapFromAsset(Context context, String strName) { 
     AssetManager assetManager = context.getAssets(); 

     InputStream istr; 
     Bitmap bitmap = null; 
     try { 
      istr = assetManager.open(strName); 
      bitmap = BitmapFactory.decodeStream(istr); 
     } catch (IOException e) { 
      return null; 
     } 

     return bitmap; 
    } 

    public static Bitmap getBitmapFromDrawable(Context context) { 
     Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.turtle_26); 
     return icon; 
    } 

    public void setDrawColor(int color) { 
     paint.setColor(color); 
     curColor = color; 
    } 

    public int getDrawColor() { 
     return curColor; 
    } 

    int x, y = 0; 
    int scrollByX, scrollByY = 0; 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     int action = (event.getAction() & MotionEvent.ACTION_MASK); 

     if (action == MotionEvent.ACTION_DOWN) { 
      x = (int) event.getX() + scrollByX; 
      y = (int) event.getY() + scrollByY; 
     } else if (action == MotionEvent.ACTION_MOVE) { 
      scrollByX = x - (int) event.getX(); 
      scrollByY = y - (int) event.getY(); 
      scrollTo(scrollByX, scrollByY); 
     } 

     return true; 
    } 

    @Override 
    public void scrollTo(int x, int y) { 
     // TODO Auto-generated method stub 
     super.scrollTo(x, y); 
     scrollByX = x; 
     scrollByY = y; 
    } 

    @Override 
    public void setBackgroundColor(int color) { 
     // TODO Auto-generated method stub 
     super.setBackgroundColor(color); 
     bgColor = color; 
    } 

    public int getBackgroundColor() { 
     return bgColor; 
    } 

} 
+0

Что произойдет, если пользователь начнет увеличивать/уменьшать изображение? и может у меня дать образец кода, если он есть, потому что доза не работает со мной :( – Omarj

1

Если я понимаю хорошо, ваша главная задача не делать рисовать линии над изображением. Вы ищете WHICH PATH для перехода на заданную карту, динамически. Это верно?

Ну, если это так, вы ищете A* search algorithm. Это хорошо известный метод поиска путей и очень распространенный в играх и других приложениях, которым необходим такой ИИ.

Вы можете разработать собственную реализацию этого алгоритма, соответствующую вашим потребностям, или вы можете попробовать использовать API от третьего лица.

Адрес one можно использовать с кодом Google. Это простая версия java и apache, поэтому ее можно использовать в вашем приложении для Android.

Но подождите, я тоже коротко посмотрел на github, и кажется, что есть lot more различных реализаций этого готового к использованию!

Search web и вы также найдете много статей, учебных пособий, статей ...

Удачи!

EDIT

Как объяснены в комментариях ниже, ваша главная задача заключается в Динамично процессе «карта», чтобы найти «стены», так что вы можете применить * поиск, а затем, наконец, рисовать линии прежде всего.

Ну, для динамических образов вам потребуется некоторая сторонняя библиотека, чтобы сделать это, их много, но, вероятно, лучшим решением является использование OpenCV. Он совместим с Android, имеет хорошую документацию и много статей об этом. Вот tutorial с примером поиска «линий» на изображении. Это может быть применено и к вашим картам. Вероятно, вам нужно будет настроить порог , пока вы не обнаружите только более толстые линии стен.

+0

thx. но я уже сейчас это :) но проблема, когда я пытаюсь применить A * find-path " динамически «мне нужно знать все препятствия или делать что-то, что нужно для обработки изображений, которые трудно использовать для напольного изображения, как тот, который я прикреплял, если у вас нет хорошей идеи? – Omarj

+0

OK! Хорошо, я отредактирую свой ответ. Но в следующий раз имейте в виду, что более точные вопросы приведут к лучшим решениям ...;) – PFROLIM

0

пытается искать белый цвет пикселей в изображении (это будет ваш путь, который вы можете пройти бросок)

0

Моего ответа предполагает, что вы пытаетесь вычислить самый простой путь для кого-то, чтобы путешествовать из черного круга к красному кругу. Не обращайте внимания на этот ответ, если вы ищете помощь только с реальной живописью линий. Я также предполагаю, что вы можете заранее определить все точки пересечения. Если вам нужно программно вывести их из рисунка, вы, вероятно, должны начать с нового вопроса.

Я бы начал с пунктов (x, y), которые вы предлагаете, но оставьте значение тега. Затем я бы добавил соединения между этими точками как связанный объект, который добавляет больше деталей, чем значение вашего тега. Каждая точка будет иметь набор подключений к другим соседним точкам. В каждом соединении я бы добавил кучу атрибутов для использования в ваших вычислениях, таких как расстояние, препятствия и любые другие улучшения, такие как привилегии. Расстояние было бы легким (намек: используйте теорему Пифагора). Препятствия могут включать двери, ступени, лифты и т. Д. Привилегии могут включать зоны с ограниченным доступом (что диагональный коридор рядом с верхней частью диаграммы выглядит ограниченным).

Похоже, что на черной отправной точке вы можете отправиться на восток или на запад. Это было бы два разных пути. Первый пункт на востоке предложил бы четыре варианта: пройти через дверь на север, дверь на юг, продолжить на восток или вернуться на запад. Опция «Запад» вернется к исходной точке, в которой путь можно игнорировать как цикл. Опция на юге вернется только к этой точке, где ее можно игнорировать как петлю. Вариант на север интересен тем, что он должен продолжаться по диагональному коридору и в конечном итоге предлагать путь к месту назначения, хотя, очевидно, не лучший путь. Опция на восток продолжит работу и, в конце концов, вернет несколько вариантов. Когда путь достигает места назначения, он отмечает положительный отклик и трудность в том, чтобы попасть туда на основе пройденных соединений (расстояние, препятствия и привилегии).

Реализация этого будет включать введение Пути, который включает в себя список пройденных точек, а также накопленную трудность каждого соединения по этим точкам. Начиная с начала, я попытался бы написать что-то, что отделяет один шаг во всех направлениях, а не пытается полностью пройти весь путь. Добавьте к накопленной сложности с каждым шагом. Если точка является местом назначения, то у вас есть успешный путь (хотя это может быть не самый эффективный путь). Если точка уже находится в пути, то это цикл, поэтому прекратите прохождение этого пути. Если накопленная трудность пути больше, чем другая, которая уже найдена, прекратите пересечение этого пути.

0

Я не думаю, что это возможно без использования OpenGL (и позволяя ему выполнять преобразование положения X/Y ваших линий в фактическое положение X/Y на экране).

В OpenGL вы должны визуализировать изображение плана здания в 2D-плоскости.Вам нужно будет предварительно вычислить позиции пространства мира (x, y, z) каждой точки пересечения, между которыми вы будете рисовать линии, и создать коллекцию, в которой каждая позиция имеет массив других позиций, к которым она может подключиться. Затем вам нужно будет выполнить (рекурсивную) логику, чтобы определить, какие точки находятся между начальной и конечной точками, и провести двумерные линии между ними.

Таким образом, это очень возможно, но необходимость панорамирования и масштабирования в значительной степени устраняет необходимость в камере, которая, где OpenGL приходит.

панорамирование и масштабирование будут обрабатываться путем перемещения камеры вокруг, в то время как сохраняя его в пределах предопределенных границ, чтобы (на основе выбранного FOV) он не отображался (слишком много) за краем изображения.

1

Вы можете использовать Dijkstra's_algorithm, чтобы найти кратчайший путь.

enter image description here

Есть более эффективные способы сделать это как A* алгоритм, но я думаю, что Дейкстры является наиболее легко реализовать.

+0

, что я пытаюсь сделать :) У вас есть идея, как построить его в моем случае? – Omarj

Смежные вопросы