最近一直關心Android/Blender計畫,簡稱AB計畫。我找到一個很不錯的軟體工具min3d,下載網址如下:
經測試其重要範例執行畫面如下:
本社群由Nantou.py使用者社群以及國立虎尾科技大學電機資訊學院負責維護,它是一群熱愛智慧生活科技以及Python的專業教師所組成,大家一同快樂地研究有關數位生活中人工智慧、大數據、物聯網、雲端服務、APPS、福祉科技、感知網路服務、車載網路服務、及網際網路等資通訊技術,並運用這些資通訊以及Python技術來提升我們的日常生活品質,建立更好的生活環境。
2011年6月27日 星期一
2011年6月11日 星期六
[Android Sensor] 感測器模擬軟體的使用
下載sensorsimulator-1.1.1.zip放在http://code.google.com/p/openintents/downloads/detail?name=sensorsimulator-1.1.1.zip&can=2&q=
以前的文章 利用感測器模擬程式來開發感測器應用程式,發表在http://cheng-min-i-taiwan.blogspot.com/2010/03/blog-post_26.html
使用sensorsimulator-1.1.1,修改ApiDemo在com.example.android.apis.os套件下Sensors程式,藍色字為修訂的程式。
以前的文章 利用感測器模擬程式來開發感測器應用程式,發表在http://cheng-min-i-taiwan.blogspot.com/2010/03/blog-post_26.html
使用sensorsimulator-1.1.1,修改ApiDemo在com.example.android.apis.os套件下Sensors程式,藍色字為修訂的程式。
package com.example.sensors;
import org.openintents.sensorsimulator.hardware.Sensor;
import org.openintents.sensorsimulator.hardware.SensorEvent;
import org.openintents.sensorsimulator.hardware.SensorEventListener;
import org.openintents.sensorsimulator.hardware.SensorManagerSimulator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
public class Sensors extends Activity {
/** Tag string for our debug logs */
private static final String TAG = "Sensors";
private SensorEventListener mEventListenerAccelerometer;
private SensorEventListener mEventListenerLight;
private SensorEventListener mEventListenerTemperature;
private SensorEventListener mEventListenerOrientation;
private SensorEventListener mEventListenerMagneticField;
//private SensorManager mSensorManager;
private SensorManagerSimulator mSensorManager;
private GraphView mGraphView;
private class GraphView extends View implements SensorListener
{
private Bitmap mBitmap;
private Paint mPaint = new Paint();
private Canvas mCanvas = new Canvas();
private Path mPath = new Path();
private RectF mRect = new RectF();
private float mLastValues[] = new float[3*2];
private float mOrientationValues[] = new float[3];
private int mColors[] = new int[3*2];
private float mLastX;
private float mScale[] = new float[2];
private float mYOffset;
private float mMaxX;
private float mSpeed = 1.0f;
private float mWidth;
private float mHeight;
public GraphView(Context context) {
super(context);
mColors[0] = Color.argb(192, 255, 64, 64);
mColors[1] = Color.argb(192, 64, 128, 64);
mColors[2] = Color.argb(192, 64, 64, 255);
mColors[3] = Color.argb(192, 64, 255, 255);
mColors[4] = Color.argb(192, 128, 64, 128);
mColors[5] = Color.argb(192, 255, 255, 64);
mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mRect.set(-0.5f, -0.5f, 0.5f, 0.5f);
mPath.arcTo(mRect, 0, 180);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
mCanvas.setBitmap(mBitmap);
mCanvas.drawColor(0xFFFFFFFF);
mYOffset = h * 0.5f;
mScale[0] = - (h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
mScale[1] = - (h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
mWidth = w;
mHeight = h;
if (mWidth < mHeight) {
mMaxX = w;
} else {
mMaxX = w-50;
}
mLastX = mMaxX;
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
synchronized (this) {
if (mBitmap != null) {
final Paint paint = mPaint;
final Path path = mPath;
final int outer = 0xFFC0C0C0;
final int inner = 0xFFff7010;
if (mLastX >= mMaxX) {
mLastX = 0;
final Canvas cavas = mCanvas;
final float yoffset = mYOffset;
final float maxx = mMaxX;
final float oneG = SensorManager.STANDARD_GRAVITY * mScale[0];
paint.setColor(0xFFAAAAAA);
cavas.drawColor(0xFFFFFFFF);
cavas.drawLine(0, yoffset, maxx, yoffset, paint);
cavas.drawLine(0, yoffset+oneG, maxx, yoffset+oneG, paint);
cavas.drawLine(0, yoffset-oneG, maxx, yoffset-oneG, paint);
}
canvas.drawBitmap(mBitmap, 0, 0, null);
float[] values = mOrientationValues;
if (mWidth < mHeight) {
float w0 = mWidth * 0.333333f;
float w = w0 - 32;
float x = w0*0.5f;
for (int i=0 ; i<3 ; i++) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(x, w*0.5f + 4.0f);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
paint.setColor(outer);
canvas.scale(w, w);
canvas.drawOval(mRect, paint);
canvas.restore();
canvas.scale(w-5, w-5);
paint.setColor(inner);
canvas.rotate(-values[i]);
canvas.drawPath(path, paint);
canvas.restore();
x += w0;
}
} else {
float h0 = mHeight * 0.333333f;
float h = h0 - 32;
float y = h0*0.5f;
for (int i=0 ; i<3 ; i++) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(mWidth - (h*0.5f + 4.0f), y);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
paint.setColor(outer);
canvas.scale(h, h);
canvas.drawOval(mRect, paint);
canvas.restore();
canvas.scale(h-5, h-5);
paint.setColor(inner);
canvas.rotate(-values[i]);
canvas.drawPath(path, paint);
canvas.restore();
y += h0;
}
}
}
}
}
public void onSensorChanged(int sensor, float[] values) {
//Log.d(TAG, "sensor: " + sensor + ", x: " + values[0] + ", y: " + values[1] + ", z: " + values[2]);
synchronized (this) {
if (mBitmap != null) {
final Canvas canvas = mCanvas;
final Paint paint = mPaint;
if (sensor == SensorManager.SENSOR_ORIENTATION) {
for (int i=0 ; i<3 ; i++) {
mOrientationValues[i] = values[i];
}
} else {
float deltaX = mSpeed;
float newX = mLastX + deltaX;
int j = (sensor == SensorManager.SENSOR_MAGNETIC_FIELD) ? 1 : 0;
for (int i=0 ; i<3 ; i++) {
int k = i+j*3;
final float v = mYOffset + values[i] * mScale[j];
paint.setColor(mColors[k]);
canvas.drawLine(mLastX, mLastValues[k], newX, v, paint);
mLastValues[k] = v;
}
if (sensor == SensorManager.SENSOR_MAGNETIC_FIELD)
mLastX += mSpeed;
}
invalidate();
}
}
}
public void onAccuracyChanged(int sensor, int accuracy) {
// TODO Auto-generated method stub
}
}
/**
* Initialization of the Activity after it is first created. Must at least
* call {@link android.app.Activity#setContentView setContentView()} to
* describe what is to be displayed in the screen.
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
// Be sure to call the super class.
super.onCreate(savedInstanceState);
// mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensorManager = SensorManagerSimulator.getSystemService(this,
SENSOR_SERVICE);
mSensorManager.connectSimulator();
mGraphView = new GraphView(this);
setContentView(mGraphView);
initListeners();
}
private void initListeners() {
mEventListenerAccelerometer = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
mGraphView.onSensorChanged(SensorManager.SENSOR_MAGNETIC_FIELD, values);
// mTextView1.setText("Accelerometer: " + values[0] + ", "
// + values[1] + ", " + values[2]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
mEventListenerMagneticField = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
// mTextView2.setText("Compass: " + values[0] + ", " + values[1]
// + ", " + values[2]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
mEventListenerOrientation = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
mGraphView.onSensorChanged(SensorManager.SENSOR_ORIENTATION, values);
// mTextView3.setText("Orientation: " + values[0] + ", "
// + values[1] + ", " + values[2]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
mEventListenerTemperature = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
// mTextView4.setText("Temperature: " + values[0] + ", "
// + values[1] + ", " + values[2]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
mEventListenerLight = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
// mTextView5.setText("Light: " + values[0]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
}
@Override
protected void onResume() {
super.onResume();
/* mSensorManager.registerListener(mGraphView,
SensorManager.SENSOR_ACCELEROMETER |
SensorManager.SENSOR_MAGNETIC_FIELD |
SensorManager.SENSOR_ORIENTATION,
SensorManager.SENSOR_DELAY_FASTEST);*/
mSensorManager.registerListener(mEventListenerAccelerometer,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_FASTEST);
mSensorManager.registerListener(mEventListenerMagneticField,
mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_FASTEST);
mSensorManager.registerListener(mEventListenerOrientation,
mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_FASTEST);
mSensorManager.registerListener(mEventListenerTemperature,
mSensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE),
SensorManager.SENSOR_DELAY_FASTEST);
mSensorManager.registerListener(mEventListenerLight,
mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
SensorManager.SENSOR_DELAY_FASTEST);
}
@Override
protected void onStop() {
// mSensorManager.unregisterListener(mGraphView);
mSensorManager.unregisterListener(mEventListenerAccelerometer);
mSensorManager.unregisterListener(mEventListenerMagneticField);
mSensorManager.unregisterListener(mEventListenerOrientation);
mSensorManager.unregisterListener(mEventListenerTemperature);
mSensorManager.unregisterListener(mEventListenerLight);
super.onStop();
}
}
2011年6月10日 星期五
[Android UI 教學(7)] 記憶上次執行結果
1. 在紅色方塊處按下mouse右鍵,選擇source再選擇Override/Implement Methods
2.輸入程式
3. 在編輯框內輸入資料,然後離開程式,再執行程式,您會發現上次輸入狀態還在。
2.輸入程式
package com.example.sum;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class SumActivity extends Activity {
/** Called when the activity is first created. */
private String PREF_NUM1="NUM1";
private String PREF_NUM2="NUM2";
private String PREF_SUM="SUM";
EditText et1, et2;
Button bt;
TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1 = (EditText) findViewById(R.id.EditText01);
et2 = (EditText) findViewById(R.id.EditText02);
tv = (TextView) findViewById(R.id.TextView01);
bt = (Button) findViewById(R.id.Button01);
bt.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
double d1,d2;
d1 = Double.parseDouble(et1.getText().toString());
d2 = Double.parseDouble(et2.getText().toString());
tv.setText(Double.toString(d1+d2));
}
});
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
SharedPreferences pref = getSharedPreferences ("pref_apn" , MODE_PRIVATE);
Editor ed = pref.edit();
ed.putString(PREF_NUM1, et1.getText().toString());
ed.putString(PREF_NUM2, et2.getText().toString());
ed.putString(PREF_SUM, tv.getText().toString());
ed.commit();
super.onPause();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
SharedPreferences pref = getSharedPreferences("pref_apn" , MODE_PRIVATE);
et1.setText(pref.getString(PREF_NUM1, ""));
et2.setText(pref.getString(PREF_NUM2, ""));
tv.setText(pref.getString(PREF_SUM, ""));
super.onResume();
}
}
3. 在編輯框內輸入資料,然後離開程式,再執行程式,您會發現上次輸入狀態還在。
[Android UI 教學(6)] 總和計算應用程式
1. 建立新專案
2. 刪除預設的TextView
3. 新增2個EditText, 1個Button, 1個TextView
4. 修改Text屬性
5. 輸入程式
6. 執行結果
2. 刪除預設的TextView
3. 新增2個EditText, 1個Button, 1個TextView
4. 修改Text屬性
5. 輸入程式
package com.example.sum;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class SumActivity extends Activity {
/** Called when the activity is first created. */
EditText et1, et2;
Button bt;
TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1 = (EditText) findViewById(R.id.EditText01);
et2 = (EditText) findViewById(R.id.EditText02);
tv = (TextView) findViewById(R.id.TextView01);
bt = (Button) findViewById(R.id.Button01);
bt.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
double d1,d2;
d1 = Double.parseDouble(et1.getText().toString());
d2 = Double.parseDouble(et2.getText().toString());
tv.setText(Double.toString(d1+d2));
}
});
}
}
6. 執行結果
[Android UI 教學(4)] 建立字串資源
2011年6月7日 星期二
[Android UI 教學(3)] 建立簡單的對話盒
原程式請參考[Android UI 教學(2)] 建立有圖示功能表請修訂下列文字
package com.example.menu;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MenuDesignActivity extends Activity {
/** Called when the activity is first created. */
public static final int ADD_ID = Menu.FIRST ;
public static final int DELETE_ID = Menu.FIRST + 1;
public static final int ABOUT_ID = Menu.FIRST + 2;
public static final int EXIT_ID = Menu.FIRST + 3;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
menu.add(0, ADD_ID, 0, "Add").setIcon(R.drawable.icon);
menu.add(0, DELETE_ID, 1, "Del");
menu.add(0, ABOUT_ID, 2, "About");
menu.add(0, EXIT_ID, 3, "Exit");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId()){
case ADD_ID:
setTitle("新增項目");
break;
case DELETE_ID:
setTitle("刪除項目");
break;
case ABOUT_ID:
setTitle("關於");
openAboutDialog();
break;
case EXIT_ID:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
public void openAboutDialog()
{
new AlertDialog.Builder(this)
.setTitle("關於")
.setMessage("南開科大")
//按下確認按鈕後的事件
.setPositiveButton("ok",
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialoginterface, int i)
{
}
}
)
.show();
}
}
[Android UI 教學(1)] 文字型功能表設計
請先參考[Android UI 教學(1)] 文字型功能表設計1. 建立專案
2. 在下圖中第一個紅色框位置上按下滑鼠右鍵,選擇「Source」選單,再選「Override/Implement Method」。
3. 把onCreateOptionsMenu()和onOptionsItemSelected()兩個事件程序打勾,按下OK鍵後,會產生相對應的事件處理程序的框架。
4. 指令說明
public abstract MenuItem add (int groupId, int itemId, int order, CharSequence title)
功能:增加功能選單
groupId: 群組代碼
itemId:選項代碼
order:選單次序
title:選單標題
5. 輸入下列程式(藍色)
2. 在下圖中第一個紅色框位置上按下滑鼠右鍵,選擇「Source」選單,再選「Override/Implement Method」。
3. 把onCreateOptionsMenu()和onOptionsItemSelected()兩個事件程序打勾,按下OK鍵後,會產生相對應的事件處理程序的框架。
4. 指令說明
public abstract MenuItem add (int groupId, int itemId, int order, CharSequence title)
功能:增加功能選單
groupId: 群組代碼
itemId:選項代碼
order:選單次序
title:選單標題
5. 輸入下列程式(藍色)
package com.example.menu;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MenuDesignActivity extends Activity {
/** Called when the activity is first created. */
public static final int ADD_ID = Menu.FIRST ;
public static final int DELETE_ID = Menu.FIRST + 1;
public static final int ABOUT_ID = Menu.FIRST + 2;
public static final int EXIT_ID = Menu.FIRST + 3;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
menu.add(0, ADD_ID, 0, "Add");
menu.add(0, DELETE_ID, 1, "Del");
menu.add(0, ABOUT_ID, 2, "About");
menu.add(0, EXIT_ID, 3, "Exit");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId()){
case ADD_ID:
setTitle("新增項目");
break;
case DELETE_ID:
setTitle("刪除項目");
break;
case ABOUT_ID:
setTitle("關於");
break;
case EXIT_ID:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
}
2011年6月1日 星期三
Java Native Interface (JNI) Android算數篇(使用NDK) -- Fibonacci Sequence
籠子裡有一對新生的兔子。假設每對兔子每個月會生出一對兔子,但新生的兔子要滿兩個月才能生出下一代兔子,則一年之後,會有多少對兔子?
費波那西數列(Fibonacci Sequence),又譯費波拿契數、斐波那契數列、費氏數列、黃金分割數列。
費波那西數列由 0 和 1 開始,之後的費波那西係數就由之前的兩數相加。
前幾個費波那西係數是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,………………
大家放心,今天不是來討論數學況且數學不太認識我,這次是將Fibonacci用JNI方式實作在Android上。
費波那西數列(Fibonacci Sequence),又譯費波拿契數、斐波那契數列、費氏數列、黃金分割數列。
費波那西數列由 0 和 1 開始,之後的費波那西係數就由之前的兩數相加。
前幾個費波那西係數是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,………………
大家放心,今天不是來討論數學況且數學不太認識我,這次是將Fibonacci用JNI方式實作在Android上。
訂閱:
文章 (Atom)