Translate

воскресенье, 17 июня 2012 г.

Программирование под android для начинающих. Решение треугольника по теореме косинусов


 Рассмотрим процесс разработки несложного приложение на android c использование этой системы для проектирования интерфейса и применением математических функций Java.



  Приложение должно делать следующее: мы подаем исходную информацию программе в виде набора точек с известными координатами(они должны отображаться списком), а программа должна рассчитывать:
-расстояние между двумя точками по из названиям
-угол 1-2-3, где 1,2,3 - введенные названия точек


  Очевидно, что расстояние между двумя точками несложно найти по теореме Пифагора: S=корень((X2-X1)^2+(Y2-Y1)^2)

  Сложнее дело с нахождением угла между тремя точками по их координатам. Пусть эти 3 точки образуют треугольник, который мы будем решать.
  Сначала найдем все 3 стороны треугольника по теорем Пифагора и решим треугольник по трем сторонам, применив теорему косинусов:

  Алгоритм решения треугольника по 3 сторонам:



 
   Запишем теорему косинусов для стороны с:
  с^2=a^2+b^2-2*a*b*cos(C)
  Преобразуем:
  -2*a*b*cos(C)=c^2-a^2-b^2
  cos(C)=(c^2-a^2-b^2)/(-2*a*b)
  C=arccos( (c^2-a^2-b^2)/(-2*a*b) )

  Мы нашли угол C по теореме косинусов. Точно также можно найти остальные 2 угла:

  B=arccos( (b^2-a^2-c^2)/(-2*a*c) )
  A=arccos( (a^2-c^2-b^2)/(-2*c*b) )

 


    Разместим в string.xml в строке gui описание интерфейса приложения. Тут находится документация системы проектирования интерфейса, которую мы используем.

  Создадим переменную для учета количества пунктов для обработки и массив, содержащий объекты класса Point(не более 100 штук), который мы опишем немного позднее. Проинициализируем в onCreate() наш интерфейс:

 
  public class CheckerActivity extends GUIActivity {
        private int count=0;
        private Point[] array = new Point[100];
    
    public void onCreate(Bundle savedInstanceState) {
         try{
            requestWindowFeature(Window.FEATURE_NO_TITLE); //Убираем верхнюю панель с названием приложения
            super.onCreate(savedInstanceState);
            super.Init(getString(R.string.gui));
                  }
                 catch(Exception e) {
            e.printStackTrace();
                  }
}


  Создадим и опишем прозрачный класс Point:
package com.checker;
public class Point {
   double x;
   double y;
   String name;
   
   public Point(double _x, double _y, String _name) {
       x=_x;
       y=_y;
       name=_name;
   }
   
   public String toString() {
       return name+"    "+x+"     "+y;
   }
}

  Теперь запрограммируем кнопку, по нажатию на который в массив должна добавляться новая точка:
public void onClick(View arg0) {
        if(arg0.getTag().equals("add")) {//Вот таким образом мы проверяем, на какую кнопку нажал пользователь - сравнивая идентификатор с тегом нажатой кнопки.
        try {
                                       //Конструкция gui.getText(<имя поля>) считывает текст из поля с идентификатором <имя поля>. Что такое имя поля (мы его определяем при описании интерфейса в XML, читать тут)
          array[count]=new Point(Double.parseDouble(gui.getText("field2")),Double.parseDouble(gui.getText("field3")),gui.getText("field1"));//Вызовем конструктор созданного нами класса. 

          count++;
          Output();
          gui.setText("","field1");//Аналогично методу getText(). Первый аргумент - записывамый текст
          gui.setText("","field2");
          gui.setText("","field3");
        }
        catch(Exception e) {
              Toast.makeText(this, "Неккоректные данные", Toast.LENGTH_LONG).show();//Если возникла ошибка - например, юзер ввел в поля для координат что-то, что не является числом, следует вывести сообщение и больше ничего не делать
            }
        }
                      //Здесь будут обработчики событий нажатия на другие кнопки
}
   
  Напишем метод Output(), которые будет выводить список точек с известными координатами в текстовое поле:
private void Output() {
        String output="";
        
        for (int i=0;i<count;i++) {
        output+=array[i].toString()+"\n";
        }
        
        gui.setText(output,"info");   
}
  
  Повесим обработчик на кнопку Reset - он должен сбрасывать все:
if(arg0.getTag().equals("clear")) {
            count=0;
            Output();
}

  Переходим к самому главному - программной логике. Напишем метод, который будет находить расстояние между двумя точками - по названиям:




private double Dist(String name1, String name2) {
        try {
                                     //Определим переменные для координта пунктов
        double x1=0;
        double x2=0;
        double y1=0;
        double y2=0;
        
        
        for (int i=0;i<count;i++) {//Сейчас мы будем искать в массиве наши пункты - если из названия совпадут с данными, найдено
            if(array[i].name.equals(name1)) {
                                                       //Нашли))
            x1=array[i].x;
            y1=array[i].y;
            }
            
                                         //Аналогично
            if(array[i].name.equals(name2)) {
            x2=array[i].x;
            y2=array[i].y;
            }
            
        }
        
        double res=Math.round(Math.pow((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1), 0.5)*1000000)/(double)(1000000);//Посчитаем по теореме Пифагора и округлим
        return res;
        }
        catch(Exception e) {
              Toast.makeText(this, "Ошибка", Toast.LENGTH_LONG).show();
        }
        return 0;
}





  Отлично, теперь можем оживить кнопку, отвечающую за расчет расстояния между двумя пунктами:
if(arg0.getTag().equals("s")) {
             String name1=gui.getText("n1");
             String name2=gui.getText("n2");
        
            String res=Dist(name1, name2)+"";
            gui.setText(res,"res");
 }
  Алгоритм решения треугольника по трем сторонам достаточно примитивен, поэтому можно поместить его прямо в обработчик кнопки(вообще, этого стоит избегать, если код алгоритма превышает 10 строк):
if(arg0.getTag().equals("an")) {
                                     //Взяли углы
        String name1=gui.getText("an1");
        String name2=gui.getText("an2");
        String name3=gui.getText("an3");
        
                                     //Посчитали стороны
        double c=Dist(name1, name3);
        double a=Dist(name1, name2);
        double b=Dist(name2, name3);
        
                                     //Нашли угол при центальнойц точке по теореме косинусов
        double angle=Math.round(Math.acos((c*c-b*b-a*a)/(-2*b*a))*180/Math.PI*1000000)/(double)(1000000);
        
        
                      String res=angle+"";
                      gui.setText(res,"res");
 }

Комментариев нет:

Отправить комментарий

Related Posts Plugin for WordPress, Blogger...