--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry kind="src" path="src"/>\r
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.project.AndroidClasspathContainerInitializer"/>\r
+ <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkitAndroid</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+#Thu Apr 17 18:22:05 JST 2008\r
+eclipse.preferences.version=1\r
+encoding/<project>=UTF-8\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="jp.ac.kyutech.ai.ylab.shiva">
+ <application android:icon="@drawable/icon">
+ <activity android:name=".NyARToolkitAndroidActivity" android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >\r
+
+<TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello World, NyARToolkitAndroidActivity"
+ />\r
+ \r
+
+</LinearLayout>
--- /dev/null
+ 234 235 240 233 240 234 240 235 240 237 240 238 240 240 240 232
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 228
+ 227 240 240 240 240 240 240 240 240 240 240 240 240 240 240 239
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 231 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 225 149 240 240 186 216 225 174 240 240 240 237 238 240 240 240
+ 150 107 238 231 75 208 115 147 238 228 223 226 237 180 226 240
+ 150 62 181 213 62 187 113 169 197 72 29 237 120 50 53 207
+ 149 63 47 78 53 184 113 101 142 5 150 150 45 217 186 83
+ 121 84 220 222 58 180 121 92 128 109 237 124 155 232 161 64
+ 149 71 240 240 76 210 98 109 122 108 240 129 51 119 161 155
+ 149 186 240 240 98 219 135 152 207 191 236 227 152 77 175 209
+ 235 235 240 233 240 234 240 235 240 236 240 238 240 240 240 240
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 227 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 232 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 225 156 240 240 186 216 225 186 240 240 240 240 240 240 240 240
+ 150 117 240 231 72 206 115 162 240 232 223 237 240 180 226 240
+ 150 74 187 213 51 184 103 168 197 78 29 237 120 50 53 216
+ 144 77 51 74 61 184 106 101 142 5 150 152 52 217 186 85
+ 117 89 219 219 65 184 121 92 128 100 236 125 156 240 170 73
+ 148 71 240 240 76 210 109 109 121 99 240 137 51 120 166 164
+ 140 186 240 240 98 220 150 156 207 192 236 230 152 77 176 212
+ 234 235 240 233 240 234 240 235 240 236 240 238 240 240 240 233
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 239
+ 227 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 232 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 235 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 232 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 228 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 225 156 240 240 182 212 225 180 240 240 240 240 240 240 240 240
+ 150 116 238 228 66 205 115 151 238 236 225 240 240 180 226 240
+ 156 84 186 211 47 184 109 170 200 92 30 240 120 50 53 216
+ 147 83 51 73 50 184 106 110 148 17 151 150 45 217 186 85
+ 127 98 219 219 58 179 109 101 128 107 237 125 155 240 163 72
+ 155 86 240 240 76 201 85 108 121 95 232 137 51 118 153 155
+ 149 189 240 240 98 220 141 154 206 178 235 230 152 77 175 209
+
+ 232 228 239 240 240 240 240 240 240 240 240 207 83 64 155 209
+ 240 240 240 240 240 240 240 240 240 240 226 53 186 161 161 175
+ 240 240 240 240 240 240 240 240 240 240 180 50 217 232 119 77
+ 240 240 240 240 240 240 240 240 240 238 237 120 45 155 51 152
+ 238 240 240 240 240 240 240 240 240 237 226 237 150 124 129 227
+ 240 240 240 240 240 240 240 240 240 240 223 29 150 237 240 236
+ 237 240 240 240 240 240 240 240 240 240 228 72 5 109 108 191
+ 240 240 240 240 240 240 240 240 240 240 238 197 142 128 122 207
+ 235 240 240 240 240 240 240 240 240 174 147 169 101 92 109 152
+ 240 240 240 240 240 240 240 240 240 225 115 113 113 121 98 135
+ 234 240 240 240 240 240 240 240 240 216 208 187 184 180 210 219
+ 240 240 240 240 240 240 240 240 240 186 75 62 53 58 76 98
+ 233 240 240 240 240 240 240 240 240 240 231 213 78 222 240 240
+ 240 240 240 240 240 240 240 240 240 240 238 181 47 220 240 240
+ 235 240 240 240 240 240 240 240 240 149 107 62 63 84 71 186
+ 234 229 227 240 236 234 236 231 229 225 150 150 149 121 149 149
+ 240 240 240 240 240 240 240 240 240 240 240 216 85 73 164 212
+ 240 240 240 240 240 240 240 240 240 240 226 53 186 170 166 176
+ 240 240 240 240 240 240 240 240 240 240 180 50 217 240 120 77
+ 240 240 240 240 240 240 240 240 240 240 240 120 52 156 51 152
+ 238 240 240 240 240 240 240 240 240 240 237 237 152 125 137 230
+ 240 240 240 240 240 240 240 240 240 240 223 29 150 236 240 236
+ 236 240 240 240 240 240 240 240 240 240 232 78 5 100 99 192
+ 240 240 240 240 240 240 240 240 240 240 240 197 142 128 121 207
+ 235 240 240 240 240 240 240 240 240 186 162 168 101 92 109 156
+ 240 240 240 240 240 240 240 240 240 225 115 103 106 121 109 150
+ 234 240 240 240 240 240 240 240 240 216 206 184 184 184 210 220
+ 240 240 240 240 240 240 240 240 240 186 72 51 61 65 76 98
+ 233 240 240 240 240 240 240 240 240 240 231 213 74 219 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 187 51 219 240 240
+ 235 240 240 240 240 240 240 240 240 156 117 74 77 89 71 186
+ 235 229 227 240 236 234 236 232 229 225 150 150 144 117 148 140
+ 233 239 240 240 240 240 240 240 240 240 240 216 85 72 155 209
+ 240 240 240 240 240 240 240 240 240 240 226 53 186 163 153 175
+ 240 240 240 240 240 240 240 240 240 240 180 50 217 240 118 77
+ 240 240 240 240 240 240 240 240 240 240 240 120 45 155 51 152
+ 238 240 240 240 240 240 240 240 240 240 240 240 150 125 137 230
+ 240 240 240 240 240 240 240 240 240 240 225 30 151 237 232 235
+ 236 240 240 240 240 240 240 240 240 240 236 92 17 107 95 178
+ 240 240 240 240 240 240 240 240 240 240 238 200 148 128 121 206
+ 235 240 240 240 240 240 240 240 240 180 151 170 110 101 108 154
+ 240 240 240 240 240 240 240 240 240 225 115 109 106 109 85 141
+ 234 240 240 240 240 240 240 240 240 212 205 184 184 179 201 220
+ 240 240 240 240 240 240 240 240 240 182 66 47 50 58 76 98
+ 233 240 240 240 240 240 240 240 240 240 228 211 73 219 240 240
+ 240 240 240 240 240 240 240 240 240 240 238 186 51 219 240 240
+ 235 240 240 240 240 240 240 240 240 156 116 84 83 98 86 189
+ 234 229 227 240 234 232 235 232 228 225 150 156 147 127 155 149
+
+ 209 175 77 152 227 236 191 207 152 135 219 98 240 240 186 149
+ 155 161 119 51 129 240 108 122 109 98 210 76 240 240 71 149
+ 64 161 232 155 124 237 109 128 92 121 180 58 222 220 84 121
+ 83 186 217 45 150 150 5 142 101 113 184 53 78 47 63 149
+ 207 53 50 120 237 29 72 197 169 113 187 62 213 181 62 150
+ 240 226 180 237 226 223 228 238 147 115 208 75 231 238 107 150
+ 240 240 240 238 237 240 240 240 174 225 216 186 240 240 149 225
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 231
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 239 240 240 240 240 240 240 240 240 240 240 240 240 240 240 227
+ 228 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 232 240 240 240 238 240 237 240 235 240 234 240 233 240 235 234
+ 212 176 77 152 230 236 192 207 156 150 220 98 240 240 186 140
+ 164 166 120 51 137 240 99 121 109 109 210 76 240 240 71 148
+ 73 170 240 156 125 236 100 128 92 121 184 65 219 219 89 117
+ 85 186 217 52 152 150 5 142 101 106 184 61 74 51 77 144
+ 216 53 50 120 237 29 78 197 168 103 184 51 213 187 74 150
+ 240 226 180 240 237 223 232 240 162 115 206 72 231 240 117 150
+ 240 240 240 240 240 240 240 240 186 225 216 186 240 240 156 225
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 232
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 227
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 240 240 240 240 238 240 236 240 235 240 234 240 233 240 235 235
+ 209 175 77 152 230 235 178 206 154 141 220 98 240 240 189 149
+ 155 153 118 51 137 232 95 121 108 85 201 76 240 240 86 155
+ 72 163 240 155 125 237 107 128 101 109 179 58 219 219 98 127
+ 85 186 217 45 150 151 17 148 110 106 184 50 73 51 83 147
+ 216 53 50 120 240 30 92 200 170 109 184 47 211 186 84 156
+ 240 226 180 240 240 225 236 238 151 115 205 66 228 238 116 150
+ 240 240 240 240 240 240 240 240 180 225 212 182 240 240 156 225
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 228
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 232
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 235
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 232
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 227
+ 239 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 233 240 240 240 238 240 236 240 235 240 234 240 233 240 235 234
+
+ 149 149 121 149 150 150 225 229 231 236 234 236 240 227 229 234
+ 186 71 84 63 62 107 149 240 240 240 240 240 240 240 240 235
+ 240 240 220 47 181 238 240 240 240 240 240 240 240 240 240 240
+ 240 240 222 78 213 231 240 240 240 240 240 240 240 240 240 233
+ 98 76 58 53 62 75 186 240 240 240 240 240 240 240 240 240
+ 219 210 180 184 187 208 216 240 240 240 240 240 240 240 240 234
+ 135 98 121 113 113 115 225 240 240 240 240 240 240 240 240 240
+ 152 109 92 101 169 147 174 240 240 240 240 240 240 240 240 235
+ 207 122 128 142 197 238 240 240 240 240 240 240 240 240 240 240
+ 191 108 109 5 72 228 240 240 240 240 240 240 240 240 240 237
+ 236 240 237 150 29 223 240 240 240 240 240 240 240 240 240 240
+ 227 129 124 150 237 226 237 240 240 240 240 240 240 240 240 238
+ 152 51 155 45 120 237 238 240 240 240 240 240 240 240 240 240
+ 77 119 232 217 50 180 240 240 240 240 240 240 240 240 240 240
+ 175 161 161 186 53 226 240 240 240 240 240 240 240 240 240 240
+ 209 155 64 83 207 240 240 240 240 240 240 240 240 239 228 232
+ 140 148 117 144 150 150 225 229 232 236 234 236 240 227 229 235
+ 186 71 89 77 74 117 156 240 240 240 240 240 240 240 240 235
+ 240 240 219 51 187 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 219 74 213 231 240 240 240 240 240 240 240 240 240 233
+ 98 76 65 61 51 72 186 240 240 240 240 240 240 240 240 240
+ 220 210 184 184 184 206 216 240 240 240 240 240 240 240 240 234
+ 150 109 121 106 103 115 225 240 240 240 240 240 240 240 240 240
+ 156 109 92 101 168 162 186 240 240 240 240 240 240 240 240 235
+ 207 121 128 142 197 240 240 240 240 240 240 240 240 240 240 240
+ 192 99 100 5 78 232 240 240 240 240 240 240 240 240 240 236
+ 236 240 236 150 29 223 240 240 240 240 240 240 240 240 240 240
+ 230 137 125 152 237 237 240 240 240 240 240 240 240 240 240 238
+ 152 51 156 52 120 240 240 240 240 240 240 240 240 240 240 240
+ 77 120 240 217 50 180 240 240 240 240 240 240 240 240 240 240
+ 176 166 170 186 53 226 240 240 240 240 240 240 240 240 240 240
+ 212 164 73 85 216 240 240 240 240 240 240 240 240 240 240 240
+ 149 155 127 147 156 150 225 228 232 235 232 234 240 227 229 234
+ 189 86 98 83 84 116 156 240 240 240 240 240 240 240 240 235
+ 240 240 219 51 186 238 240 240 240 240 240 240 240 240 240 240
+ 240 240 219 73 211 228 240 240 240 240 240 240 240 240 240 233
+ 98 76 58 50 47 66 182 240 240 240 240 240 240 240 240 240
+ 220 201 179 184 184 205 212 240 240 240 240 240 240 240 240 234
+ 141 85 109 106 109 115 225 240 240 240 240 240 240 240 240 240
+ 154 108 101 110 170 151 180 240 240 240 240 240 240 240 240 235
+ 206 121 128 148 200 238 240 240 240 240 240 240 240 240 240 240
+ 178 95 107 17 92 236 240 240 240 240 240 240 240 240 240 236
+ 235 232 237 151 30 225 240 240 240 240 240 240 240 240 240 240
+ 230 137 125 150 240 240 240 240 240 240 240 240 240 240 240 238
+ 152 51 155 45 120 240 240 240 240 240 240 240 240 240 240 240
+ 77 118 240 217 50 180 240 240 240 240 240 240 240 240 240 240
+ 175 153 163 186 53 226 240 240 240 240 240 240 240 240 240 240
+ 209 155 72 85 216 240 240 240 240 240 240 240 240 240 239 233
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">NyARToolkitAndroidDemo</string>
+</resources>
--- /dev/null
+package com.tomgibara.android.camera;\r
+\r
+import android.graphics.Bitmap;\r
+import android.graphics.Canvas;\r
+import android.graphics.Paint;\r
+import android.graphics.Rect;\r
+\r
+/**\r
+ * A CameraSource implementation that repeatedly captures a single bitmap.\r
+ * \r
+ * @author Tom\r
+ *\r
+ */\r
+\r
+public class BitmapCamera implements CameraSource {\r
+\r
+ private final Bitmap bitmap;\r
+ private final Rect bounds;\r
+ private final Paint paint = new Paint();\r
+\r
+ public BitmapCamera(Bitmap bitmap, int width, int height) {\r
+ this.bitmap = bitmap;\r
+ bounds = new Rect(0, 0, width, height);\r
+\r
+ paint.setFilterBitmap(true);\r
+ paint.setAntiAlias(true);\r
+ }\r
+ \r
+ @Override\r
+ public int getWidth() {\r
+ return bounds.right;\r
+ }\r
+ \r
+ @Override\r
+ public int getHeight() {\r
+ return bounds.bottom;\r
+ }\r
+ \r
+ @Override\r
+ public boolean open() {\r
+ return true;\r
+ }\r
+ \r
+ @Override\r
+ public boolean capture(Canvas canvas) {\r
+ if (\r
+ bounds.right == bitmap.width() &&\r
+ bounds.bottom == bitmap.height()) {\r
+ canvas.drawBitmap(bitmap, 0, 0, null);\r
+ } else {\r
+ canvas.drawBitmap(bitmap, null, bounds, paint);\r
+ }\r
+ return true;\r
+ }\r
+ \r
+ @Override\r
+ public void close() {\r
+ /* nothing to do */\r
+ }\r
+}\r
--- /dev/null
+package com.tomgibara.android.camera;\r
+\r
+import android.graphics.Canvas;\r
+\r
+/**\r
+ * Provides a simple abstraction for obtaining preview captures from a camera\r
+ * on the Android platform. This interface intended to be used temporarily while\r
+ * the Google Android SDK fails to support camera capture from desktop devices\r
+ * (webcams etc).\r
+ * \r
+ * @author Tom Gibara\r
+ */\r
+\r
+public interface CameraSource {\r
+\r
+ static final String LOG_TAG = "camera";\r
+ \r
+ /**\r
+ * Open the camera source for subsequent use via calls to capture().\r
+ * \r
+ * @return true if the camera source was successfully opened.\r
+ */\r
+ \r
+ boolean open();\r
+ \r
+ /**\r
+ * Close the camera source. Calling close on a closed CameraSource is\r
+ * permitted but has no effect. The camera source may be reopened after\r
+ * being closed.\r
+ */\r
+ \r
+ void close();\r
+ \r
+ /**\r
+ * The width of the captured image.\r
+ * \r
+ * @return the width of the capture in pixels\r
+ */\r
+ \r
+ int getWidth();\r
+ \r
+ /**\r
+ * The height of the captured image.\r
+ * \r
+ * @return the height of the capture in pixels\r
+ */\r
+ \r
+ int getHeight();\r
+ \r
+ /**\r
+ * Attempts to render the current camera view onto the supplied canvas.\r
+ * The capture will be rendered into the rectangle (0,0,width,height).\r
+ * Outstanding transformations on the canvas may alter this.\r
+ * \r
+ * @param canvas the canvas to which the captured pixel data will be written\r
+ * @return true iff a frame was successfully written to the canvas\r
+ */\r
+ \r
+ boolean capture(Canvas canvas);\r
+ \r
+}\r
--- /dev/null
+package com.tomgibara.android.camera;\r
+\r
+import android.graphics.Canvas;\r
+import android.hardware.CameraDevice;\r
+\r
+/**\r
+ * A CameraSource implementation that obtains its bitmaps directly from the\r
+ * device camera.\r
+ * \r
+ * @author Tom Gibara\r
+ *\r
+ */\r
+\r
+public class GenuineCamera implements CameraSource {\r
+\r
+ private final int width;\r
+ private final int height;\r
+ \r
+ private CameraDevice device = null;\r
+ \r
+ public GenuineCamera(int width, int height) {\r
+ this.width = width;\r
+ this.height = height;\r
+ }\r
+ \r
+ @Override\r
+ public int getWidth() {\r
+ return width;\r
+ }\r
+ \r
+ @Override\r
+ public int getHeight() {\r
+ return height;\r
+ }\r
+ \r
+ @Override\r
+ public boolean open() {\r
+ if (device != null) return true;\r
+ device = CameraDevice.open();\r
+ if (device == null) return false;\r
+ \r
+ //parameters for the device mostly as specified in sample app\r
+ CameraDevice.CaptureParams param = new CameraDevice.CaptureParams();\r
+ param.type = 1; // preview\r
+ param.srcWidth = 1280;\r
+ param.srcHeight = 960;\r
+ param.leftPixel = 0;\r
+ param.topPixel = 0;\r
+ param.outputWidth = width;\r
+ param.outputHeight = height;\r
+ param.dataFormat = 2; // RGB_565\r
+ \r
+ //attempt to configure the device here\r
+ if (!device.setCaptureParams(param)) {\r
+ device.close();\r
+ device = null;\r
+ return false;\r
+ }\r
+ \r
+ return true;\r
+ }\r
+ \r
+ @Override\r
+ public void close() {\r
+ if (device == null) return;\r
+ device.close();\r
+ device = null;\r
+ }\r
+ \r
+ @Override\r
+ public boolean capture(Canvas canvas) {\r
+ if (device == null) return false;\r
+ return device.capture(canvas);\r
+ }\r
+\r
+}\r
--- /dev/null
+package com.tomgibara.android.camera;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.net.HttpURLConnection;\r
+import java.net.URL;\r
+import java.net.URLConnection;\r
+\r
+import android.graphics.Bitmap;\r
+import android.graphics.BitmapFactory;\r
+import android.graphics.Canvas;\r
+import android.graphics.Paint;\r
+import android.graphics.Rect;\r
+import android.util.Log;\r
+\r
+/**\r
+ * A CameraSource implementation that obtains its bitmaps via an HTTP request\r
+ * to a URL.\r
+ * \r
+ * @author Tom Gibara\r
+ *\r
+ */\r
+\r
+public class HttpCamera implements CameraSource {\r
+\r
+ \r
+ private static final int CONNECT_TIMEOUT = 1000;\r
+ private static final int SOCKET_TIMEOUT = 1000;\r
+ \r
+ private final String url;\r
+ private final Rect bounds;\r
+ private final boolean preserveAspectRatio;\r
+ private final Paint paint = new Paint();\r
+\r
+ public HttpCamera(String url, int width, int height, boolean preserveAspectRatio) {\r
+ this.url = url;\r
+ bounds = new Rect(0, 0, width, height);\r
+ this.preserveAspectRatio = preserveAspectRatio;\r
+ \r
+ paint.setFilterBitmap(true);\r
+ paint.setAntiAlias(true);\r
+ }\r
+ \r
+ @Override\r
+ public int getWidth() {\r
+ return bounds.right;\r
+ }\r
+ \r
+ @Override\r
+ public int getHeight() {\r
+ return bounds.bottom;\r
+ }\r
+ \r
+ @Override\r
+ public boolean open() {\r
+ /* nothing to do */\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public boolean capture(Canvas canvas) {\r
+ if (canvas == null) throw new IllegalArgumentException("null canvas");\r
+ try {\r
+ Bitmap bitmap = null;\r
+ InputStream in = null;\r
+ int response = -1;\r
+ try {\r
+ //we use URLConnection because it's anticipated that it is lighter-weight than HttpClient\r
+ //NOTE: At this time, neither properly support connect timeouts\r
+ //as a consequence, this implementation will hang on a failure to connect\r
+ URL url = new URL(this.url);\r
+ URLConnection conn = url.openConnection();\r
+ if (!(conn instanceof HttpURLConnection)) throw new IOException("Not an HTTP connection.");\r
+ HttpURLConnection httpConn = (HttpURLConnection) conn;\r
+ httpConn.setAllowUserInteraction(false);\r
+ httpConn.setConnectTimeout(CONNECT_TIMEOUT);\r
+ httpConn.setReadTimeout(SOCKET_TIMEOUT);\r
+ httpConn.setInstanceFollowRedirects(true);\r
+ httpConn.setRequestMethod("GET");\r
+ httpConn.connect();\r
+ response = httpConn.getResponseCode();\r
+ if (response == HttpURLConnection.HTTP_OK) {\r
+ in = httpConn.getInputStream();\r
+ bitmap = BitmapFactory.decodeStream(in);\r
+ }\r
+ } finally {\r
+ if (in != null) try {\r
+ in.close();\r
+ } catch (IOException e) {\r
+ /* ignore */\r
+ }\r
+ }\r
+ \r
+ if (bitmap == null) throw new IOException("Response Code: " + response);\r
+\r
+ //render it to canvas, scaling if necessary\r
+ if (\r
+ bounds.right == bitmap.width() &&\r
+ bounds.bottom == bitmap.height()) {\r
+ canvas.drawBitmap(bitmap, 0, 0, null);\r
+ } else {\r
+ Rect dest;\r
+ if (preserveAspectRatio) {\r
+ dest = new Rect(bounds);\r
+ dest.bottom = bitmap.height() * bounds.right / bitmap.width();\r
+ dest.offset(0, (bounds.bottom - dest.bottom)/2);\r
+ } else {\r
+ dest = bounds;\r
+ }\r
+ canvas.drawBitmap(bitmap, null, dest, paint);\r
+ }\r
+\r
+ } catch (RuntimeException e) {\r
+ Log.i(LOG_TAG, "Failed to obtain image over network", e);\r
+ return false;\r
+ } catch (IOException e) {\r
+ Log.i(LOG_TAG, "Failed to obtain image over network", e);\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public void close() {\r
+ /* nothing to do */\r
+ }\r
+\r
+}\r
--- /dev/null
+package com.tomgibara.android.camera;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.net.InetSocketAddress;\r
+import java.net.Socket;\r
+import java.nio.ByteBuffer;\r
+import java.nio.ByteOrder;\r
+import java.nio.FloatBuffer;\r
+import java.nio.IntBuffer;\r
+\r
+import javax.microedition.khronos.opengles.GL10;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARRaster_RGB;\r
+import jp.nyatla.nyartoolkit.jogl.utils.GLNyARParam;\r
+import jp.nyatla.nyartoolkit.jogl.utils.GLNyARSingleDetectMarker;\r
+import android.graphics.Bitmap;\r
+import android.graphics.BitmapFactory;\r
+import android.graphics.Canvas;\r
+import android.graphics.OpenGLContext;\r
+import android.graphics.Paint;\r
+import android.graphics.Rect;\r
+import android.util.Log;\r
+import android.view.SurfaceHolder;\r
+\r
+/**\r
+ * A CameraSource implementation that obtains its bitmaps via a TCP connection\r
+ * to a remote host on a specified address/port.\r
+ * \r
+ * Originally wrote by Tom Gibara\r
+ * \r
+ * \r
+ * Modified for detecting ARMarker and drawing 3D cube.\r
+ * \r
+ * @author Shiva\r
+ * \r
+ */\r
+\r
+public class SocketCamera implements CameraSource {\r
+\r
+ private static final int SOCKET_TIMEOUT = 5000;\r
+\r
+ private final String address;\r
+ private final int port;\r
+ private final Rect bounds;\r
+ private final boolean preserveAspectRatio;\r
+ private final Paint paint = new Paint();\r
+ private final Paint paintBlue = new Paint();\r
+\r
+ private GLNyARSingleDetectMarker nya;\r
+ private NyARRaster_RGB raster;\r
+ private GLNyARParam ar_param;\r
+ // private NyARCode ar_code;\r
+\r
+ private SurfaceHolder mHolder;\r
+\r
+ private final Bitmap fixedBitmap;\r
+ private final Cube mCube = new Cube();\r
+\r
+ private int w = -1;\r
+ private int h = -1;\r
+ private int[] pixels;\r
+ private byte[] buf;\r
+ private float[] resultf;\r
+\r
+ private static final boolean LOCAL = false;\r
+ private static final boolean TEXT = false;\r
+ private static final boolean DETECT = true;\r
+\r
+ public SocketCamera(String address, int port, int width, int height,\r
+ boolean preserveAspectRatio, GLNyARParam ar_param,\r
+ NyARCode ar_code, SurfaceHolder holder, Bitmap fixedBitmap) {\r
+ this.address = address;\r
+ this.port = port;\r
+ bounds = new Rect(0, 0, width, height);\r
+ this.preserveAspectRatio = preserveAspectRatio;\r
+\r
+ paint.setColor(0xFFFF0000);\r
+ paint.setFilterBitmap(true);\r
+ paint.setAntiAlias(true);\r
+\r
+ paintBlue.setColor(0xFF0000FF);\r
+ paintBlue.setFilterBitmap(true);\r
+ paintBlue.setAntiAlias(true);\r
+\r
+ this.ar_param = ar_param;\r
+ // this.ar_code = ar_code;\r
+ try {\r
+ nya = new GLNyARSingleDetectMarker(ar_param, ar_code, 80.0);\r
+ nya.setContinueMode(true);\r
+ } catch (NyARException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ mHolder = holder;\r
+\r
+ this.fixedBitmap = fixedBitmap;\r
+\r
+ }\r
+\r
+ @Override\r
+ public int getWidth() {\r
+ return bounds.right;\r
+ }\r
+\r
+ @Override\r
+ public int getHeight() {\r
+ return bounds.bottom;\r
+ }\r
+\r
+ @Override\r
+ public boolean open() {\r
+ /* nothing to do */\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public boolean capture(Canvas canvas) {\r
+ if (canvas == null) {\r
+ throw new IllegalArgumentException("null canvas");\r
+ }\r
+\r
+ int[] pixels = this.pixels;\r
+ byte[] buf = this.buf;\r
+ float[] resultf = this.resultf;\r
+\r
+ int width = 320;\r
+ int height = 240;\r
+ if (this.w != width || this.h != height || buf == null) {\r
+ this.w = width;\r
+ this.h = height;\r
+ pixels = new int[w * h];\r
+ buf = new byte[pixels.length * 3];\r
+ resultf = new float[16];\r
+ }\r
+ int w = this.w;\r
+ int h = this.h;\r
+\r
+ Socket socket = null;\r
+ try {\r
+ Bitmap bitmap = null;\r
+ if (!LOCAL) {\r
+ socket = new Socket();\r
+ socket.setSoTimeout(SOCKET_TIMEOUT);\r
+ socket.connect(new InetSocketAddress(address, port),\r
+ SOCKET_TIMEOUT);\r
+ // obtain the bitmap\r
+ InputStream in = socket.getInputStream();\r
+ // DataInputStream dis = new DataInputStream(\r
+ // new BufferedInputStream(in, buf.length));\r
+ // dis.readFully(buf);\r
+\r
+ bitmap = BitmapFactory.decodeStream(in);\r
+ // bitmap = BitmapFactory.decodeByteArray(buf, 0, buf.length);\r
+ } else {\r
+ bitmap = fixedBitmap;\r
+ }\r
+\r
+ // GL init\r
+ OpenGLContext glc = new OpenGLContext(OpenGLContext.DEPTH_BUFFER);\r
+ glc.makeCurrent(mHolder);\r
+ GL10 gl = (GL10) (glc.getGL());\r
+ gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);\r
+\r
+ gl.glViewport(0, 0, w, h);\r
+ float ratio = (float) h / w;\r
+ gl.glMatrixMode(GL10.GL_PROJECTION);\r
+ gl.glLoadIdentity();\r
+ gl.glFrustumf(-1.0f, 1.0f, -ratio, ratio, 5.0f, 40.0f);\r
+ // 見る位置\r
+ gl.glMatrixMode(GL10.GL_MODELVIEW);\r
+ gl.glLoadIdentity();\r
+ gl.glTranslatef(0.0f, 0.0f, -10.0f);\r
+\r
+ gl.glDisable(GL10.GL_DITHER);\r
+ gl.glActiveTexture(GL10.GL_TEXTURE0);\r
+ gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);\r
+ gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,\r
+ GL10.GL_CLAMP_TO_EDGE);\r
+ gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,\r
+ GL10.GL_CLAMP_TO_EDGE);\r
+ gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,\r
+ GL10.GL_NEAREST);\r
+ gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,\r
+ GL10.GL_NEAREST);\r
+ gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,\r
+ GL10.GL_REPLACE);\r
+\r
+ gl.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);\r
+ gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);\r
+ gl.glEnableClientState(GL10.GL_COLOR_ARRAY);\r
+ gl.glEnable(GL10.GL_CULL_FACE);\r
+ gl.glShadeModel(GL10.GL_SMOOTH);\r
+ gl.glEnable(GL10.GL_DEPTH_TEST);\r
+\r
+ boolean is_marker_exist = false;\r
+ // long time = 0;\r
+ // double[][] atm = null;\r
+\r
+ if (DETECT) {\r
+ // time = System.currentTimeMillis();\r
+ // ここで処理\r
+\r
+ bitmap.getPixels(pixels, 0, w, 0, 0, w, h);\r
+\r
+ for (int i = 0; i < pixels.length; i++) {\r
+ int argb = pixels[i];\r
+ // byte a = (byte) (argb & 0xFF000000 >> 24);\r
+ byte r = (byte) (argb & 0x00FF0000 >> 16);\r
+ byte g = (byte) (argb & 0x0000FF00 >> 8);\r
+ byte b = (byte) (argb & 0x000000FF);\r
+ buf[i * 3] = r;\r
+ buf[i * 3 + 1] = g;\r
+ buf[i * 3 + 2] = b;\r
+ }\r
+ // Log.d("nyar", "Time to copy image : "\r
+ // + (System.currentTimeMillis() - time) + " ms");\r
+\r
+ if (raster == null) {\r
+ raster = new NyARRaster_RGB();\r
+ }\r
+ // time = System.currentTimeMillis();\r
+ NyARRaster_RGB.wrap(raster, buf, w, h);\r
+ // マーカー検出\r
+ try {\r
+ // Log.d("nyar", "detecting marker");\r
+ is_marker_exist = nya.detectMarkerLite(raster, 100);\r
+ // Log.d("nyar", "marker detected");\r
+\r
+ // if (is_marker_exist) {\r
+ // 変換行列を取得\r
+ // atm = nya.getTransmationMatrix().getArray();\r
+ // }\r
+ } catch (NyARException e) {\r
+ Log.e("nyar", "marker detection failed", e);\r
+ return false;\r
+ }\r
+ // Log.d("nyar", "Time to detect marker : "\r
+ // + (System.currentTimeMillis() - time) + " ms");\r
+ } else {\r
+ gl.glMatrixMode(GL10.GL_MODELVIEW);\r
+ gl.glLoadIdentity();\r
+ // int num = (int) (System.currentTimeMillis() % 3) - 1;\r
+ int num = 0;\r
+ gl.glTranslatef(0.0f, 0.0f, -10.0f);\r
+ gl.glRotatef(20.0f * num, 0, 0, 1);\r
+ }\r
+ if (is_marker_exist) {\r
+ // Log.d("nyar", "marker exist");\r
+ // // Projection transformation.\r
+ gl.glMatrixMode(GL10.GL_PROJECTION);\r
+ gl.glLoadIdentity();\r
+ gl.glLoadMatrixf(ar_param.getCameraFrustumRHf(), 0);\r
+ gl.glMatrixMode(GL10.GL_MODELVIEW);\r
+ // Viewing transformation.\r
+ gl.glLoadIdentity();\r
+ nya.getCameraViewRH(resultf);\r
+ // int num = (int) (System.currentTimeMillis() % 3) - 1;\r
+ // gl.glTranslatef(0.0f, 2.5f, -20.0f);\r
+ gl.glLoadMatrixf(resultf, 0);\r
+ // gl.glTranslatef(0.0f, 0.0f, -10.0f);\r
+ // gl.glRotatef(20.0f, 1, 0, 0);\r
+ // gl.glScalef(0.5f, 0.5f, 1.0f);\r
+ // gl.glRotatef(20.0f * num, 0, 0, 1);\r
+\r
+ gl.glFinish();\r
+ } else {\r
+ // Log.d("nyar", "marker does not exist");\r
+ }\r
+\r
+ // time = System.currentTimeMillis();\r
+ gl.glClearColor(1, 1, 1, 1);\r
+ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);\r
+ gl.glFinish();\r
+ // render it to canvas, scaling if necessary\r
+ if (bounds.right == bitmap.width()\r
+ && bounds.bottom == bitmap.height()) {\r
+ canvas.drawBitmap(bitmap, 0, 0, null);\r
+ } else {\r
+ // Log.d("nyar", "preserveAspectRation = " +\r
+ // preserveAspectRatio);\r
+ Rect dest;\r
+ if (preserveAspectRatio) {\r
+ dest = new Rect(bounds);\r
+ dest.bottom = bitmap.height() * bounds.right\r
+ / bitmap.width();\r
+ dest.offset(0, (bounds.bottom - dest.bottom) / 2);\r
+ } else {\r
+ dest = bounds;\r
+ }\r
+ canvas.drawBitmap(bitmap, null, dest, paint);\r
+ }\r
+\r
+ if (is_marker_exist) {\r
+ // Log.d("nyar", "drawing a cube.");\r
+ mCube.draw(gl);\r
+ // gl.glRotatef(20.0f, 0, 0, 1.0f);\r
+ // mCube.draw(gl);\r
+ } else if (!DETECT) {\r
+ // Log.d("nyar", "drawing a cube without detection.");\r
+ mCube.draw(gl);\r
+ // Thread.sleep(1000);\r
+ }\r
+ gl.glFinish();\r
+ // Log.d("nyar", "" + (System.currentTimeMillis() - time) + "ms");\r
+\r
+ if (TEXT) {\r
+ String str = null;\r
+ // 情報を画面に書く\r
+ // g.drawImage(img, 32, 32, this);\r
+ if (is_marker_exist) {\r
+ // Log.d("nyar", "marker exist and drawing text");\r
+ // str = "マーカー検出 [" + nya.getConfidence() + "]";\r
+ // canvas.drawText(str, 32, 100, paint);\r
+ // for (int i = 0; i < 3; i++) {\r
+ // for (int i2 = 0; i2 < 4; i2++) {\r
+ // str = "[" + i + "][" + i2 + "]" + atm[i][i2];\r
+ // canvas.drawText(str, 32, 0 + (1 + i2 * 3 + i) * 16,\r
+ // paint);\r
+ // }\r
+ // }\r
+\r
+ for (int i = 0; i < 4; i++) {\r
+ for (int i2 = 0; i2 < 4; i2++) {\r
+ str = "[" + i + "][" + i2 + "]"\r
+ + resultf[i * 4 + i2];\r
+ canvas.drawText(str, 32, 0 + (1 + i * 4 + i2) * 16,\r
+ paint);\r
+ }\r
+ }\r
+ float[] arp = ar_param.getCameraFrustumRHf();\r
+ for (int i = 0; i < 4; i++) {\r
+ for (int i2 = 0; i2 < 4; i2++) {\r
+ str = "[" + i + "][" + i2 + "]" + arp[i * 4 + i2];\r
+ canvas.drawText(str, 152,\r
+ 0 + (1 + i * 4 + i2) * 16, paintBlue);\r
+ }\r
+ }\r
+ } else {\r
+ // Log.d("nyar", "marker does not exist");\r
+ // g.drawString("マーカー未検出:", 32, 100);\r
+ str = "マーカー未検出";\r
+ canvas.drawText(str, 32, 100, paint);\r
+ }\r
+ } // end if\r
+ } catch (Exception e) {\r
+ Log.i(LOG_TAG, "Failed to obtain image over network", e);\r
+ return false;\r
+ } finally {\r
+ try {\r
+ if (socket != null) {\r
+ socket.close();\r
+ }\r
+ } catch (IOException e) {\r
+ /* ignore */\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public void close() {\r
+ /* nothing to do */\r
+ }\r
+\r
+ class Cube {\r
+\r
+ private FloatBuffer mVertexBuffer;\r
+ private IntBuffer mColorBuffer;\r
+ private ByteBuffer mIndexBuffer;\r
+\r
+ public Cube() {\r
+ float fone = 0.5f;\r
+ float[] vertices = { fone, fone, fone, fone, -fone, fone, -fone,\r
+ -fone, fone, -fone, fone, fone, fone, fone, -fone, fone,\r
+ -fone, -fone, -fone, -fone, -fone, -fone, fone, -fone };\r
+\r
+ int one = 0x00010000;\r
+ int[] colors = { 0, 0, 0, one, one, 0, 0, one, one, one, 0, one, 0,\r
+ one, 0, one, 0, 0, one, one, one, 0, one, one, one, one,\r
+ one, one, 0, one, one, one };\r
+\r
+ byte[] indices = new byte[] { 0, 4, 5, 0, 5, 1, 1, 5, 6, 1, 6, 2,\r
+ 2, 6, 7, 2, 7, 3, 3, 7, 4, 3, 4, 0, 4, 7, 6, 4, 6, 5, 3, 0,\r
+ 1, 3, 1, 2 };\r
+ // indices = new byte[] { 3, 2, 1, 0, 2, 3, 7, 6, 0, 1, 5, 4, 3, 0,\r
+ // 4,\r
+ // 7, 1, 2, 6, 5, 4, 5, 6, 7 };\r
+\r
+ // Buffers to be passed to gl*Pointer() functions\r
+ // must be direct, i.e., they must be placed on the\r
+ // native heap where the garbage collector cannot\r
+ // move them.\r
+ //\r
+ // Buffers with multi-byte datatypes (e.g., short, int, float)\r
+ // must have their byte order set to native order\r
+\r
+ ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);\r
+ vbb.order(ByteOrder.nativeOrder());\r
+ mVertexBuffer = vbb.asFloatBuffer();\r
+ mVertexBuffer.put(vertices);\r
+ mVertexBuffer.position(0);\r
+\r
+ ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);\r
+ cbb.order(ByteOrder.nativeOrder());\r
+ mColorBuffer = cbb.asIntBuffer();\r
+ mColorBuffer.put(colors);\r
+ mColorBuffer.position(0);\r
+\r
+ mIndexBuffer = ByteBuffer.allocateDirect(indices.length);\r
+ mIndexBuffer.put(indices);\r
+ mIndexBuffer.position(0);\r
+ }\r
+\r
+ public void draw(GL10 gl) {\r
+\r
+ gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker\r
+\r
+ gl.glFrontFace(GL10.GL_CW);\r
+ gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);\r
+ gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);\r
+ gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE,\r
+ mIndexBuffer);\r
+\r
+ gl.glTranslatef(0.0f, 0.0f, -0.5f); // Place base of cube on marker\r
+ }\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+package jp.ac.kyutech.ai.ylab.shiva;\r
+\r
+import java.io.InputStream;\r
+\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+import jp.nyatla.nyartoolkit.jogl.utils.GLNyARParam;\r
+import android.app.Activity;\r
+import android.content.Context;\r
+import android.graphics.Bitmap;\r
+import android.graphics.BitmapFactory;\r
+import android.graphics.Canvas;\r
+import android.os.Bundle;\r
+import android.util.Log;\r
+import android.view.SurfaceHolder;\r
+import android.view.SurfaceView;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.view.Window;\r
+import android.view.View.OnClickListener;\r
+import android.widget.Button;\r
+import android.widget.EditText;\r
+import android.widget.LinearLayout;\r
+import android.widget.TableLayout;\r
+import android.widget.TableRow;\r
+import android.widget.TextView;\r
+\r
+import com.tomgibara.android.camera.CameraSource;\r
+import com.tomgibara.android.camera.SocketCamera;\r
+\r
+public class NyARToolkitAndroidActivity extends Activity {\r
+\r
+ private final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;\r
+ private final int FP = ViewGroup.LayoutParams.FILL_PARENT;\r
+\r
+ private Preview mPreview;\r
+\r
+ private Button button;\r
+\r
+ private boolean connected;\r
+\r
+ private TextView infoText;\r
+\r
+ @Override\r
+ protected void onCreate(Bundle icicle) {\r
+ super.onCreate(icicle);\r
+\r
+ Log.d("trace", "onCreate");\r
+\r
+ // Hide the window title.\r
+ requestWindowFeature(Window.FEATURE_NO_TITLE);\r
+\r
+ LinearLayout linearLayout = new LinearLayout(this);\r
+ linearLayout.setOrientation(LinearLayout.VERTICAL);\r
+ setContentView(linearLayout);\r
+\r
+ // Create our Preview view and set it as the content of our\r
+ // Activity\r
+ mPreview = new Preview(this);\r
+ linearLayout.addView(mPreview, new LinearLayout.LayoutParams(WC, WC));\r
+\r
+ infoText = new TextView(this);\r
+ infoText.setText("Information will be shown in here.");\r
+ linearLayout.addView(infoText, new LinearLayout.LayoutParams(FP, WC));\r
+\r
+ TableLayout tableLayout = new TableLayout(this);\r
+ tableLayout.setColumnStretchable(1, true);\r
+ linearLayout\r
+ .addView(tableLayout, new LinearLayout.LayoutParams(WC, WC));\r
+\r
+ TextView hostLabel = new TextView(this);\r
+ hostLabel.setText("Host : ");\r
+\r
+ final EditText host = new EditText(this);\r
+ host.setText("192.168.11.5");\r
+\r
+ TableRow tableRow1 = new TableRow(this);\r
+ tableRow1.addView(hostLabel);\r
+ tableRow1.addView(host, new TableRow.LayoutParams(FP, WC));\r
+\r
+ TextView portLabel = new TextView(this);\r
+ portLabel.setText("Port : ");\r
+\r
+ final EditText port = new EditText(this);\r
+ port.setText("9889");\r
+\r
+ TableRow tableRow2 = new TableRow(this);\r
+ tableRow2.addView(portLabel);\r
+ tableRow2.addView(port, new TableRow.LayoutParams(FP, WC));\r
+\r
+ button = new Button(this);\r
+ button.setOnClickListener(new OnClickListener() {\r
+ @Override\r
+ public void onClick(View v) {\r
+ if (connected) {\r
+ infoText.setText("Disconnected");\r
+ mPreview.pause();\r
+ button.setText("Connect");\r
+ } else {\r
+ String hostStr = host.getText().toString();\r
+ String portStr = port.getText().toString();\r
+ try {\r
+ int p = Integer.parseInt(portStr);\r
+\r
+ mPreview.set(hostStr, p);\r
+ } catch (Exception e) {\r
+ infoText.setText("Illegal Argument");\r
+ return;\r
+ }\r
+\r
+ infoText.setText("Connecting to " + hostStr + " on port "\r
+ + portStr);\r
+ mPreview.resume();\r
+\r
+ button.setText("Disconnect");\r
+ }\r
+ }\r
+ });\r
+ button.setText("Connect");\r
+\r
+ TableRow tableRow3 = new TableRow(this);\r
+ TableRow.LayoutParams trl2 = new TableRow.LayoutParams(FP, WC);\r
+ trl2.span = 2;\r
+ tableRow3.addView(button, trl2);\r
+\r
+ tableLayout.addView(tableRow1, new TableLayout.LayoutParams(FP, WC));\r
+ tableLayout.addView(tableRow2, new TableLayout.LayoutParams(FP, WC));\r
+ tableLayout.addView(tableRow3, new TableLayout.LayoutParams(FP, WC));\r
+\r
+ }\r
+\r
+ @Override\r
+ protected void onResume() {\r
+ Log.d("trace", "onRegume");\r
+ // Because the CameraDevice object is not a shared resource,\r
+ // it's very important to release it when the activity is paused.\r
+ super.onResume();\r
+\r
+ button.setText("Connect");\r
+ connected = false;\r
+\r
+ }\r
+\r
+ @Override\r
+ protected void onPause() {\r
+ Log.d("trace", "onPause");\r
+ // Start Preview again when we resume.\r
+ super.onPause();\r
+\r
+ mPreview.pause();\r
+ connected = false;\r
+ }\r
+\r
+ class Preview extends SurfaceView implements SurfaceHolder.Callback {\r
+ SurfaceHolder mHolder;\r
+ private PreviewThread mPreviewThread;\r
+ private boolean mHasSurface;\r
+\r
+ private GLNyARParam ar_param = new GLNyARParam();\r
+ private NyARCode ar_code = new NyARCode(16, 16);\r
+\r
+ // String host = "133.17.159.104";\r
+ String host = "192.168.11.5";\r
+\r
+ int port = 9889;\r
+\r
+ private Bitmap fixedBitmap;\r
+\r
+ public void set(String host, int port) {\r
+ this.host = host;\r
+ this.port = port;\r
+ }\r
+\r
+ Preview(Context context) {\r
+ super(context);\r
+\r
+ // Install a SurfaceHolder.Callback so we get notified when the\r
+ // underlying surface is created and destroyed.\r
+ mHolder = getHolder();\r
+ mHolder.addCallback(this);\r
+ mHasSurface = false;\r
+\r
+ // In this example, we hardcode the size of the preview. In a real\r
+ // application this should be more dynamic. This guarantees that\r
+ // the uderlying surface will never change size.\r
+ mHolder.setFixedSize(320, 240);\r
+\r
+ InputStream in = getResources().openRawResource(R.raw.marker);\r
+ fixedBitmap = BitmapFactory.decodeStream(in);\r
+\r
+ // NyARToolkitの準備\r
+ try {\r
+ ar_param.loadFromARFile(getResources().openRawResource(\r
+ R.raw.camera_para));\r
+ ar_param.changeSize(320, 240);\r
+ ar_code.loadFromARFile(getResources().openRawResource(\r
+ R.raw.patt));\r
+ Log.i("nyar", "resources have been loaded");\r
+ } catch (Exception e) {\r
+ Log.e("nyar", "resource loading failed", e);\r
+ }\r
+ }\r
+\r
+ public void resume() {\r
+ // We do the actual acquisition in a separate thread. Create it now.\r
+ if (mPreviewThread == null) {\r
+ mPreviewThread = new PreviewThread();\r
+ // If we already have a surface, just start the thread now too.\r
+ if (mHasSurface == true) {\r
+ mPreviewThread.start();\r
+ }\r
+ connected = true;\r
+ }\r
+\r
+ }\r
+\r
+ public void pause() {\r
+ // Stop Preview.\r
+ if (mPreviewThread != null) {\r
+ mPreviewThread.requestExitAndWait();\r
+ mPreviewThread = null;\r
+\r
+ connected = false;\r
+ }\r
+ }\r
+\r
+ public void surfaceCreated(SurfaceHolder holder) {\r
+ // The Surface has been created, start our main acquisition thread.\r
+ mHasSurface = true;\r
+ if (mPreviewThread != null) {\r
+ mPreviewThread.start();\r
+ }\r
+ }\r
+\r
+ public void surfaceDestroyed(SurfaceHolder holder) {\r
+ // Surface will be destroyed when we return. Stop the preview.\r
+ mHasSurface = false;\r
+ pause();\r
+ }\r
+\r
+ public void surfaceChanged(SurfaceHolder holder, int format, int w,\r
+ int h) {\r
+ // Surface size or format has changed. This should not happen in\r
+ // this\r
+ // example.\r
+ }\r
+\r
+ // ----------------------------------------------------------------------\r
+\r
+ class PreviewThread extends Thread {\r
+ private boolean mDone;\r
+\r
+ PreviewThread() {\r
+ super();\r
+ mDone = false;\r
+ }\r
+\r
+ @Override\r
+ public void run() {\r
+ // We first open the CameraDevice and configure it.\r
+ // CameraDevice camera = CameraDevice.open();\r
+ // if (camera != null) {\r
+ // CameraDevice.CaptureParams param = new\r
+ // CameraDevice.CaptureParams();\r
+ // param.type = 1; // preview\r
+ // param.srcWidth = 1280;\r
+ // param.srcHeight = 960;\r
+ // param.leftPixel = 0;\r
+ // param.topPixel = 0;\r
+ // param.outputWidth = 320;\r
+ // param.outputHeight = 240;\r
+ // param.dataFormat = 2; // RGB_565\r
+ // camera.setCaptureParams(param);\r
+ // }\r
+\r
+ Log.d("trace", "connecting to host " + host + " port" + +port);\r
+ CameraSource cs = new SocketCamera(host, port, 320, 240, true,\r
+ ar_param, ar_code, mHolder, fixedBitmap);\r
+ if (!cs.open()) {\r
+ /* deal with failure to obtain camera */\r
+ Log.d("trace", "couldn'd open camera source");\r
+ return;\r
+ }\r
+ // This is our main acquisition thread's loop, we go until\r
+ // asked to quit.\r
+ SurfaceHolder holder = mHolder;\r
+ while (!mDone) {\r
+ // Lock the surface, this returns a Canvas that can\r
+ // be used to render into.\r
+ Canvas canvas = holder.lockCanvas();\r
+\r
+ // // Capture directly into the Surface\r
+ // if (camera != null) {\r
+ // camera.capture(canvas);\r
+ // }\r
+\r
+ if (cs != null) {\r
+ cs.capture(canvas); // capture the frame onto the canvas\r
+ }\r
+\r
+ // And finally unlock and post the surface.\r
+ holder.unlockCanvasAndPost(canvas);\r
+ }\r
+\r
+ // Make sure to release the CameraDevice\r
+ if (cs != null) {\r
+ cs.close();\r
+ }\r
+ }\r
+\r
+ public void requestExitAndWait() {\r
+ // don't call this from PreviewThread thread or it a guaranteed\r
+ // deadlock!\r
+ mDone = true;\r
+ try {\r
+ join();\r
+ } catch (InterruptedException ex) {\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit;\r
+\r
+public class NyARException extends Exception {\r
+ private static final long serialVersionUID = 1L;\r
+ public NyARException(){\r
+ super();\r
+ }\r
+ public NyARException(Exception e){\r
+ super(e);\r
+ }\r
+ public NyARException(String m){\r
+ super(m);\r
+ }\r
+ public static void trap(String m) throws NyARException\r
+ {\r
+ throw new NyARException("トラップ:"+m);\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.base;\r
+\r
+public class Config {\r
+ //Version系情報\r
+// public static final int AR_HEADER_VERSION_MAJOR=2; //#define AR_HEADER_VERSION_MAJOR 2\r
+// public static final int AR_HEADER_VERSION_MINOR=72;//#define AR_HEADER_VERSION_MINOR 72\r
+//\r
+// public static final int AR_HEADER_VERSION_TINY=0;//#define AR_HEADER_VERSION_TINY 0\r
+//\r
+// public static final int AR_HEADER_VERSION_BUILD=0;//#define AR_HEADER_VERSION_BUILD 0\r
+// \r
+// public static final String AR_HEADER_VERSION_STRING="2.72.0";//#define AR_HEADER_VERSION_STRING "2.72.0"\r
+//\r
+// public static final boolean AR_HAVE_HEADER_VERSION_2=true;//#define AR_HAVE_HEADER_VERSION_2\r
+// public static final boolean AR_HAVE_HEADER_VERSION_2_72=true;//#define AR_HAVE_HEADER_VERSION_2_72\r
+\r
+\r
+ /*ビデオ入力系?*/\r
+ /*------------------------------------------------------------*/\r
+\r
+// public static final int AR_DRAW_BY_GL_DRAW_PIXELS =0;//#define AR_DRAW_BY_GL_DRAW_PIXELS 0\r
+// public static final int AR_DRAW_BY_TEXTURE_MAPPING=1;//#define AR_DRAW_BY_TEXTURE_MAPPING 1\r
+// public static final int AR_DRAW_TEXTURE_FULL_IMAGE=0;//#define AR_DRAW_TEXTURE_FULL_IMAGE 0\r
+// public static final int AR_DRAW_TEXTURE_HALF_IMAGE=1;//#define AR_DRAW_TEXTURE_HALF_IMAGE 1\r
+// public static final int AR_IMAGE_PROC_IN_FULL=0;//#define AR_IMAGE_PROC_IN_FULL 0\r
+// public static final int AR_IMAGE_PROC_IN_HALF=1;//#define AR_IMAGE_PROC_IN_HALF 1\r
+// public static final int AR_FITTING_TO_IDEAL=0;//#define AR_FITTING_TO_IDEAL 0\r
+// public static final int AR_FITTING_TO_INPUT=1;//#define AR_FITTING_TO_INPUT 1\r
+\r
+// public static final int AR_TEMPLATE_MATCHING_COLOR=0;//#define AR_TEMPLATE_MATCHING_COLOR 0\r
+// public static final int AR_TEMPLATE_MATCHING_BW=1;//#define AR_TEMPLATE_MATCHING_BW 1\r
+// public static final int AR_MATCHING_WITHOUT_PCA=0;//#define AR_MATCHING_WITHOUT_PCA 0\r
+// public static final int AR_MATCHING_WITH_PCA=1;//#define AR_MATCHING_WITH_PCA 1\r
+ \r
+// public static final int DEFAULT_TEMPLATE_MATCHING_MODE=AR_TEMPLATE_MATCHING_BW;//#define DEFAULT_TEMPLATE_MATCHING_MODE AR_TEMPLATE_MATCHING_COLOR\r
+// public static final int DEFAULT_MATCHING_PCA_MODE=AR_MATCHING_WITH_PCA;//#define DEFAULT_MATCHING_PCA_MODE AR_MATCHING_WITHOUT_PCA\r
+\r
+\r
+ //#ifdef _WIN32\r
+// public static final int DEFAULT_IMAGE_PROC_MODE =AR_IMAGE_PROC_IN_FULL;//# define DEFAULT_IMAGE_PROC_MODE AR_IMAGE_PROC_IN_FULL\r
+// public static final int DEFAULT_FITTING_MODE =AR_FITTING_TO_INPUT;//# define DEFAULT_FITTING_MODE AR_FITTING_TO_INPUT\r
+// public static final int DEFAULT_DRAW_MODE =AR_DRAW_BY_TEXTURE_MAPPING;//# define DEFAULT_DRAW_MODE AR_DRAW_BY_TEXTURE_MAPPING\r
+// public static final int DEFAULT_DRAW_TEXTURE_IMAGE =AR_DRAW_TEXTURE_FULL_IMAGE;//# define DEFAULT_DRAW_TEXTURE_IMAGE AR_DRAW_TEXTURE_FULL_IMAGE\r
+ //#endif\r
+\r
+// public static final int AR_PIX_SIZE_DEFAULT=\r
+// (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_ABGR) || (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGRA) || (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_RGBA) || (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_ARGB)?4:\r
+// ((AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGR) || (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_RGB)?3:\r
+// ((AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_2vuy) || (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_yuvs)?2:\r
+// ((AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_MONO)?1:-1)));\r
+// public static final int AR_GET_TRANS_MAT_MAX_LOOP_COUNT=5;//#define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5\r
+// public static final double AR_GET_TRANS_MAT_MAX_FIT_ERROR=1.0;//#define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0\r
+// public static final double AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR=1.0;//#define AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR 1.0\r
+\r
+// public static final int AR_AREA_MAX=100000;//#define AR_AREA_MAX 100000\r
+// public static final int AR_AREA_MIN=70;//#define AR_AREA_MIN 70\r
+\r
+\r
+// public static final int AR_SQUARE_MAX=30;//#define AR_SQUARE_MAX 30\r
+// public static final int AR_CHAIN_MAX=10000;//#define AR_CHAIN_MAX 10000\r
+// public static final int AR_PATT_NUM_MAX=50;//#define AR_PATT_NUM_MAX 50 \r
+// public static final int AR_PATT_SIZE_X=16;//#define AR_PATT_SIZE_X 16 \r
+// public static final int AR_PATT_SIZE_Y=16;//#define AR_PATT_SIZE_Y 16 \r
+// public static final int AR_PATT_SAMPLE_NUM=64;//#define AR_PATT_SAMPLE_NUM 64\r
+\r
+// public static final double AR_GL_CLIP_NEAR=50.0;//#define AR_GL_CLIP_NEAR 50.0\r
+// public static final double AR_GL_CLIP_FAR=5000.0;//#define AR_GL_CLIP_FAR 5000.0\r
+\r
+// public static final int AR_HMD_XSIZE=640;//#define AR_HMD_XSIZE 640\r
+// public static final int AR_HMD_YSIZE=480;//#define AR_HMD_YSIZE 480\r
+\r
+// public static final int AR_PARAM_NMIN=6;//#define AR_PARAM_NMIN 6\r
+// public static final int AR_PARAM_NMAX=1000;//#define AR_PARAM_NMAX 1000\r
+// public static final double AR_PARAM_C34=100.0;//#define AR_PARAM_C34 100.0\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.base;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+\r
+\r
+\r
+\r
+public class Param {\r
+ private static final int AR_PARAM_NMIN=6;//#define AR_PARAM_NMIN 6\r
+ private static final int AR_PARAM_NMAX=1000;//#define AR_PARAM_NMAX 1000\r
+ private static final double AR_PARAM_C34=100.0;//#define AR_PARAM_C34 100.0\r
+\r
+ /*\r
+ typedef struct {\r
+ int xsize, ysize;\r
+ double matL[3][4];\r
+ double matR[3][4];\r
+ double matL2R[3][4];\r
+ double dist_factorL[4];\r
+ double dist_factorR[4];\r
+ } ARSParam;*/\r
+/* static class ARSParam{\r
+ int xsize, ysize;\r
+ Double2dArray matL=new Double2dArray(3,4);\r
+ Double2dArray matR=new Double2dArray(3,4);\r
+ Double2dArray matL2R=new Double2dArray(3,4);\r
+ double[] dist_factorL=new double[4];\r
+ double[] dist_factorR=new double[4];\r
+ }*/\r
+ private static final int arParamGet_AR_PARAM_CDMIN = 12;\r
+ /*int arParamGet( double global[][3], double screen[][2], int data_num,double mat[3][4] );*/\r
+ public static int arParamGet( double global[][], double[][] screen, int num,double[][] mat) throws NyARException\r
+ {\r
+ NyARMat mat_a, mat_at, mat_r;//ARMat *mat_a, *mat_at, *mat_r, mat_cpara;\r
+ NyARMat mat_wm1,mat_wm2;//ARMat *mat_wm1, *mat_wm2;\r
+ int i;\r
+ \r
+ if(num < AR_PARAM_NMIN){\r
+ return( -1 );\r
+ }\r
+ if(num > AR_PARAM_NMAX){\r
+ return( -1 );\r
+ }\r
+ NyARException.trap("未チェックのパス");{\r
+ mat_a = new NyARMat(2*num,arParamGet_AR_PARAM_CDMIN-1 );//mat_a = arMatrixAlloc( 2*num, AR_PARAM_CDMIN-1 );\r
+ mat_at =new NyARMat(arParamGet_AR_PARAM_CDMIN-1, 2*num );//mat_at = arMatrixAlloc( AR_PARAM_CDMIN-1, 2*num );\r
+ mat_r = new NyARMat(2*num,1);//mat_r = arMatrixAlloc( 2*num, 1 );\r
+ mat_wm1 =new NyARMat(arParamGet_AR_PARAM_CDMIN-1, arParamGet_AR_PARAM_CDMIN-1 );//mat_wm1 = arMatrixAlloc( AR_PARAM_CDMIN-1, AR_PARAM_CDMIN-1 );\r
+ mat_wm2 =new NyARMat(arParamGet_AR_PARAM_CDMIN-1, 2*num );//mat_wm2 = arMatrixAlloc( AR_PARAM_CDMIN-1, 2*num );\r
+ }\r
+/*\r
+ mat_a = Matrix.arMatrixAlloc( 2*num, arParamGet_AR_PARAM_CDMIN-1 );//mat_a = arMatrixAlloc( 2*num, AR_PARAM_CDMIN-1 );\r
+ if( mat_a == null){\r
+ return -1;\r
+ }\r
+ mat_at =Matrix.arMatrixAlloc(arParamGet_AR_PARAM_CDMIN-1, 2*num );//mat_at = arMatrixAlloc( AR_PARAM_CDMIN-1, 2*num );\r
+ if(mat_at == null){\r
+ return -1;\r
+ }\r
+ mat_r = Matrix.arMatrixAlloc( 2*num, 1 );//mat_r = arMatrixAlloc( 2*num, 1 );\r
+ if(mat_r ==null){\r
+ return -1;\r
+ }\r
+ mat_wm1 = Matrix.arMatrixAlloc(arParamGet_AR_PARAM_CDMIN-1, arParamGet_AR_PARAM_CDMIN-1 );//mat_wm1 = arMatrixAlloc( AR_PARAM_CDMIN-1, AR_PARAM_CDMIN-1 );\r
+ if( mat_wm1 == null) {\r
+ return -1;\r
+ }\r
+ mat_wm2 = Matrix.arMatrixAlloc(arParamGet_AR_PARAM_CDMIN-1, 2*num );//mat_wm2 = arMatrixAlloc( AR_PARAM_CDMIN-1, 2*num );\r
+ if( mat_wm2 == null ) {\r
+ return -1;\r
+ }\r
+*/\r
+ /* Initializing array */\r
+ mat_a.zeroClear();//Javaではゼロクリアされるので不要\r
+// pa1=mat_a.getPointer();//pa1 = mat_a->m;\r
+// for(i = 0; i < 2 * num * (arParamGet_AR_PARAM_CDMIN-1); i++){\r
+// {//*pa1++ = 0.0;\r
+// pa1.set(0.0);\r
+// pa1.incPtr();}\r
+// }\r
+ double[][] pa1 =mat_a.getArray();\r
+ double[][] pa2 =mat_a.getArray();\r
+ /* Calculate A,R matrix */\r
+ double[][] pr=mat_r.getArray();\r
+ int pr_ptr_col=0;\r
+ for(i = 0; i < num; i++) {//for(i = 0, pr = mat_r->m; i < num; i++) {\r
+ int pa1_ptr_row =2*i; //pa1 = &(mat_a->m[ (2*i) * (AR_PARAM_CDMIN-1)\r
+ int pa2_ptr_row =2*i+1;//pa2 = &(mat_a->m[ (2*i+1) * (AR_PARAM_CDMIN-1) + 4]);\r
+\r
+\r
+// pa1=mat_a.getPointer((2*i)*(arParamGet_AR_PARAM_CDMIN-1)); ]);\r
+// pa2=mat_a.getPointer((2*i+1)*(arParamGet_AR_PARAM_CDMIN-1) + 4);\r
+ //*pa1++ = global[i][0]; *pa1++ = global[i][1];\r
+ pa1[pa1_ptr_row][ 0]=global[i][0];\r
+ pa1[pa1_ptr_row][ 1]=global[i][1];\r
+ //*pa1++ = global[i][2]; *pa1++ = 1.0;\r
+ pa1[pa1_ptr_row][ 2]=global[i][2];\r
+ pa1[pa1_ptr_row][ 3]=1.0;\r
+ //*pa2++ = global[i][0]; *pa2++ = global[i][1];\r
+ pa2[pa2_ptr_row][ 4]=global[i][0];\r
+ pa2[pa2_ptr_row][ 5]=global[i][1];\r
+ //*pa2++ = global[i][2]; *pa2++ = 1.0;\r
+ pa2[pa2_ptr_row][ 6]=global[i][2];\r
+ pa2[pa2_ptr_row][ 7]=1.0;\r
+ //pa1 += 4;\r
+ //*pa1++ = -global[i][0] * screen[i][0];\r
+ pa1[pa1_ptr_row][ 8]=-global[i][0] * screen[i][0];\r
+ //*pa1++ = -global[i][1] * screen[i][0];\r
+ pa1[pa1_ptr_row][ 9]=-global[i][1] * screen[i][0];\r
+ //*pa1 = -global[i][2] * screen[i][0];\r
+ pa1[pa1_ptr_row][10]=-global[i][2]* screen[i][0];\r
+ //*pa2++ = -global[i][0] * screen[i][1];\r
+ pa2[pa2_ptr_row][ 8]=-global[i][0] * screen[i][1];\r
+ //*pa2++ = -global[i][1] * screen[i][1];\r
+ pa2[pa2_ptr_row][ 9]=-global[i][1] * screen[i][1];\r
+ //*pa2 = -global[i][2] * screen[i][1];\r
+ pa2[pa2_ptr_row][10]=-global[i][2] * screen[i][1];\r
+ //*pr++ = screen[i][0] * AR_PARAM_C34;\r
+ pr[0][pr_ptr_col]=screen[i][0] * AR_PARAM_C34;pr_ptr_col++;\r
+ //*pr++ = screen[i][1] * AR_PARAM_C34;\r
+ pr[0][pr_ptr_col]=screen[i][1] * AR_PARAM_C34;pr_ptr_col++;\r
+ }\r
+\r
+ NyARException.trap("未チェックのパス");\r
+ NyARMat.matrixTrans(mat_at, mat_a );//if( arMatrixTrans( mat_at, mat_a ) < 0 ){\r
+\r
+ NyARException.trap("未チェックのパス");\r
+ mat_wm1.matrixMul(mat_at, mat_a );//if( arMatrixMul( mat_wm1, mat_at, mat_a ) < 0 ) {\r
+ NyARException.trap("未チェックのパス");\r
+ mat_wm1.matrixSelfInv();//if( arMatrixSelfInv( mat_wm1 ) < 0 ) {\r
+\r
+ NyARException.trap("未チェックのパス");\r
+ mat_wm2.matrixMul(mat_wm1, mat_at );//if( arMatrixMul( mat_wm2, mat_wm1, mat_at ) < 0 ) {\r
+\r
+ //mat_cpara.row = AR_PARAM_CDMIN-1;//mat_cpara.row = AR_PARAM_CDMIN-1;\r
+ //mat_cpara.clm = 1;\r
+ //mat_cpara.m = &(mat[0][0]);\r
+ /*1次元行列から3x4行列に転写。高負荷なところじゃないから地道に転写でOK*/\r
+ NyARMat mat_cpara=new NyARMat(arParamGet_AR_PARAM_CDMIN-1,1);\r
+ double[][] mat_cpara_array=mat_cpara.getArray();\r
+ NyARException.trap("未チェックのパス");\r
+ mat_cpara.matrixMul(mat_wm2, mat_r );//if( arMatrixMul( &mat_cpara, mat_wm2, mat_r ) < 0 ) {\r
+\r
+ for(int i2=0;i<3;i++){\r
+ for(int i3=0;i3<4;i3++){\r
+ mat[i2][i3]=mat_cpara_array[i2*4+i3][0];\r
+ }\r
+ }\r
+ //ARMat.wrap(mat.array(),arParamGet_AR_PARAM_CDMIN-1,1);}\r
+\r
+ mat[2][3]=AR_PARAM_C34;//mat[2][3] = AR_PARAM_C34;\r
+\r
+ return 0;\r
+ }\r
+\r
+/* //int arsParamChangeSize( ARSParam *source, int xsize, int ysize, ARSParam *newparam );\r
+ public static int arsParamChangeSize( ARSParam source, int xsize, int ysize, ARSParam newparam)\r
+ {\r
+ double scale;\r
+\r
+ newparam.xsize=xsize;//newparam->xsize = xsize;\r
+ newparam.ysize=ysize;//newparam->ysize = ysize;\r
+\r
+ scale=(double)xsize/ (double)(source.xsize);//scale = (double)xsize / (double)(source->xsize);\r
+ for(int i = 0; i < 4; i++ ){\r
+ newparam.matL.set(0,i,source.matL.get(0,i)*scale);//newparam->matL[0][i] = source->matL[0][i] * scale;\r
+ newparam.matL.set(1,i,source.matL.get(1,i)*scale);//newparam->matL[1][i] = source->matL[1][i] * scale;\r
+ newparam.matL.set(2,i,source.matL.get(2,i));//newparam->matL[2][i] = source->matL[2][i];\r
+ }\r
+ for(int i = 0; i < 4; i++ ) {\r
+ newparam.matR.set(0,i,source.matR.get(0,i)*scale);//newparam->matR[0][i] = source->matR[0][i] * scale;\r
+ newparam.matR.set(1,i,source.matR.get(1,i)*scale);//newparam->matR[1][i] = source->matR[1][i] * scale;\r
+ newparam.matR.set(2,i,source.matR.get(2,i));//newparam->matR[2][i] = source->matR[2][i];\r
+ }\r
+ for(int i = 0; i < 4; i++ ) {\r
+ newparam.matL2R.set(0,i,source.matL2R.get(0,i));//newparam->matL2R[0][i] = source->matL2R[0][i];\r
+ newparam.matL2R.set(1,i,source.matL2R.get(1,i));//newparam->matL2R[1][i] = source->matL2R[1][i];\r
+ newparam.matL2R.set(2,i,source.matL2R.get(2,i));//newparam->matL2R[2][i] = source->matL2R[2][i];\r
+ }\r
+\r
+ newparam.dist_factorL[0] = source.dist_factorL[0] * scale;//newparam->dist_factorL[0] = source->dist_factorL[0] * scale;\r
+ newparam.dist_factorL[1] = source.dist_factorL[1] * scale;//newparam->dist_factorL[1] = source->dist_factorL[1] * scale;\r
+ newparam.dist_factorL[2] = source.dist_factorL[2] / (scale*scale);//newparam->dist_factorL[2] = source->dist_factorL[2] / (scale*scale);\r
+ newparam.dist_factorL[3] = source.dist_factorL[3];//newparam->dist_factorL[3] = source->dist_factorL[3];\r
+\r
+ newparam.dist_factorR[0] = source.dist_factorR[0] * scale;//newparam->dist_factorR[0] = source->dist_factorR[0] * scale;\r
+ newparam.dist_factorR[1] = source.dist_factorR[1] * scale;//newparam->dist_factorR[1] = source->dist_factorR[1] * scale;\r
+ newparam.dist_factorR[2] = source.dist_factorR[2] / (scale*scale);//newparam->dist_factorR[2] = source->dist_factorR[2] / (scale*scale);\r
+ newparam.dist_factorR[3] = source.dist_factorR[3];//newparam->dist_factorR[3] = source->dist_factorR[3];\r
+\r
+ return 0;\r
+ }*/\r
+/* //int arsParamSave( char *filename, ARSParam *sparam );\r
+ public static int arsParamSave(String filename, ARSParam sparam) throws Exception\r
+ { \r
+ //int xsize, ysize;\r
+ //Double2dArray matL=new Double2dArray(3,4);\r
+ //Double2dArray matR=new Double2dArray(3,4);\r
+ //Double2dArray matL2R=new Double2dArray(3,4);\r
+ //double dist_factorL[]=new double[4];\r
+ //double dist_factorR[]=new double[4];\r
+\r
+ byte[] buf=new byte[(4+4+(3*4*8)*3+(4*8)*2)];\r
+ \r
+ //バッファをラップ\r
+ ByteBuffer bb = ByteBuffer.wrap(buf);\r
+ bb.order(ByteOrder.BIG_ENDIAN);\r
+\r
+ //書き込み\r
+ bb.putInt(sparam.xsize);\r
+ bb.putInt(sparam.ysize);\r
+ for(int i=0;i<3;i++){\r
+ for(int i2=0;i2<4;i2++){\r
+ bb.putDouble(sparam.matL.get(i, i2));\r
+ }\r
+ }\r
+ for(int i=0;i<3;i++){\r
+ for(int i2=0;i2<4;i2++){\r
+ bb.putDouble(sparam.matR.get(i, i2));\r
+ }\r
+ }\r
+ for(int i=0;i<3;i++){\r
+ for(int i2=0;i2<4;i2++){\r
+ bb.putDouble(sparam.matL2R.get(i, i2));\r
+ }\r
+ }\r
+ for(int i=0;i<4;i++){\r
+ bb.putDouble(sparam.dist_factorL[i]);\r
+ }\r
+ for(int i=0;i<4;i++){\r
+ bb.putDouble(sparam.dist_factorR[i]);\r
+ }\r
+ //ファイルに保存\r
+ FileOutputStream fs=new FileOutputStream(filename);\r
+ fs.write(buf);\r
+ fs.close();\r
+ \r
+ return 0;\r
+ }*/\r
+/* //int arsParamLoad( char *filename, ARSParam *sparam );\r
+ public static int arsParamLoad(String filename, ARSParam sparam ) throws Exception\r
+ {\r
+ //ファイルを読んどく\r
+ FileInputStream fs=new FileInputStream(filename);\r
+ File f=new File(filename);\r
+ int file_size=(int)f.length();\r
+ byte[] buf=new byte[file_size];\r
+ fs.read(buf);\r
+ fs.close();\r
+ \r
+ //バッファを加工\r
+ ByteBuffer bb = ByteBuffer.wrap(buf);\r
+ bb.order(ByteOrder.BIG_ENDIAN);\r
+ \r
+ //固定回数パースして配列に格納 \r
+ sparam.xsize=bb.getInt();\r
+ sparam.ysize=bb.getInt();\r
+ for(int i=0;i<3;i++){\r
+ for(int i2=0;i2<4;i2++){\r
+ sparam.matL.set(i,i2,bb.getDouble());\r
+ }\r
+ }\r
+ for(int i=0;i<3;i++){\r
+ for(int i2=0;i2<4;i2++){\r
+ sparam.matR.set(i,i2,bb.getDouble());\r
+ }\r
+ }\r
+ for(int i=0;i<3;i++){\r
+ for(int i2=0;i2<4;i2++){\r
+ sparam.matL2R.set(i,i2,bb.getDouble());\r
+ }\r
+ }\r
+ for(int i=0;i<3;i++){\r
+ sparam.dist_factorL[i]=bb.getDouble();\r
+ }\r
+ for(int i=0;i<3;i++){\r
+ sparam.dist_factorR[i]=bb.getDouble();\r
+ }\r
+ return 0;\r
+ }*/\r
+/*\r
+ // int arsParamGetMat( double matL[3][4], double matR[3][4],double cparaL[3][4], double cparaR[3][4], double matL2R[3][4] );\r
+ public static int arsParamGetMat(double[][] matL, double[][] matR,double[][] cparaL, double[][] cparaR, double[][] matL2R) throws JartkException\r
+ {\r
+ ARMat t1,t2,t3;//ARMat *t1, *t2, *t3;\r
+ //double transL[3][4], transR[3][4];\r
+ Double2dArray transL=new Double2dArray(3,4);\r
+ Double2dArray transR=new Double2dArray(3,4);\r
+ \r
+ arParamDecompMat( matL,cparaL,transL);\r
+ arParamDecompMat( matR,cparaR,transR);\r
+ JartkException.trap("未チェックパス");{\r
+ t1=new ARMat(4,4);//t1 = arMatrixAlloc( 4, 4 );\r
+ t2=new ARMat(4,4);//t2 = arMatrixAlloc( 4, 4 );\r
+ }\r
+ double[][] t1_array=t1.getArray();\r
+ double[][] t2_array=t2.getArray();\r
+ for(int j = 0; j < 3; j++ ){\r
+ for(int i = 0; i < 4; i++ ) {\r
+ JartkException.trap("未チェックパス");{\r
+ t1_array[j][i]=transL.get(j,i);//t1->m[j*4+i] = transL[j][i];\r
+ t2_array[j][i]=transL.get(j,i);//t2->m[j*4+i] = transR[j][i];\r
+ }\r
+ }\r
+ }\r
+ JartkException.trap("未チェックパス");{\r
+ t1_array[3][0]=t1_array[3][1]=t1_array[3][2]=0.0;//t1->m[12] = t1->m[13] = t1->m[14] = 0.0;\r
+ t1_array[3][3]=1.0;//t1->m[15] = 1.0;\r
+ t2_array[3][0]=t2_array[3][1]=t2_array[3][2]=0.0;//t2->m[12] = t2->m[13] = t2->m[14] = 0.0;\r
+ t2_array[3][3]=1.0;//t2->m[15] = 1.0;\r
+ }\r
+ JartkException.trap("未チェックのパス");\r
+ t1.matrixSelfInv();//if( arMatrixSelfInv(t1) != 0 ) {\r
+\r
+ JartkException.trap("未チェックのパス"); \r
+ t3 =ARMat.matrixAllocMul(t2, t1);//t3 = arMatrixAllocMul(t2, t1);\r
+ double[][] t3_array=t3.getArray();\r
+ if(t3==null){\r
+ return -1;\r
+ }\r
+ \r
+ for(int j = 0; j < 3; j++ ) {\r
+ for(int i = 0; i < 4; i++ ) {\r
+ JartkException.trap("未チェックパス");\r
+ matL2R[j][i]=t3_array[j][i];//matL2R[j][i] = t3->m[j*4+i];\r
+ }\r
+ }\r
+ return 0;\r
+ }\r
+*/ //int arsParamDisp( ARSParam *sparam )\r
+/* public static int arsParamDisp( ARSParam sparam)\r
+ {\r
+ System.out.println("--------------------------------------");//printf("--------------------------------------\n");\r
+ System.out.println("SIZE = "+sparam.xsize+", "+sparam.ysize);// printf("SIZE = %d, %d\n", sparam->xsize, sparam->ysize);\r
+ System.out.println("-- Left --");//printf("-- Left --\n");\r
+ System.out.println("Distotion factor = "+sparam.dist_factorL[0]+" "+sparam.dist_factorL[1]+" "+sparam.dist_factorL[2]+" "+sparam.dist_factorL[3]);//printf("Distotion factor = %f %f %f %f\n", sparam->dist_factorL[0],sparam->dist_factorL[1], sparam->dist_factorL[2], sparam->dist_factorL[3] );\r
+ for(int j = 0; j < 3; j++ ) {\r
+ for(int i = 0; i < 4; i++ ){\r
+ System.out.print(sparam.matL.get(j,i)+" ");//printf("%7.5f ", sparam->matL[j][i]);\r
+ }\r
+ System.out.println();//printf("\n");\r
+ }\r
+ \r
+ System.out.println("-- Right --");//printf("-- Right --\n");\r
+ System.out.println("Distotion factor = "+sparam.dist_factorR[0]+" "+sparam.dist_factorR[1]+" "+sparam.dist_factorR[2]+" "+sparam.dist_factorR[3]);//printf("Distotion factor = %f %f %f %f\n", sparam->dist_factorR[0],sparam->dist_factorR[1], sparam->dist_factorR[2], sparam->dist_factorR[3]);\r
+ for(int j = 0; j < 3; j++ ){\r
+ for(int i = 0; i < 4; i++ ){\r
+ System.out.println(sparam.matR.get(j,i)+" ");//printf("%7.5f ", sparam->matR[j][i]);\r
+ }\r
+ System.out.println();//printf("\n");\r
+ }\r
+ \r
+ System.out.println("-- Left => Right --");//printf("-- Left => Right --\n");\r
+ for(int j = 0; j < 3; j++ ) {\r
+ for(int i = 0; i < 4; i++ ){\r
+ //printf("%7.5f ", sparam->matL2R[j][i]);\r
+ }\r
+ System.out.println();//printf("\n");\r
+ }\r
+ \r
+ System.out.println("--------------------------------------");//printf("--------------------------------------\n");\r
+ \r
+ return 0; \r
+ }*/\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import java.io.FileInputStream;\r
+import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
+import java.io.StreamTokenizer;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * ARToolKitのマーカーコードを1個保持します。\r
+ *\r
+ */\r
+public class NyARCode{\r
+ private int[][][][] pat;//static int pat[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ private double[] patpow=new double[4];//static double patpow[AR_PATT_NUM_MAX][4];\r
+ private short[][][] patBW;//static int patBW[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ private double[] patpowBW=new double[4];//static double patpowBW[AR_PATT_NUM_MAX][4]; \r
+ private int width,height;\r
+ public int[][][][] getPat()\r
+ {\r
+ return pat;\r
+ }\r
+ public double [] getPatPow()\r
+ {\r
+ return patpow;\r
+ }\r
+ public short[][][] getPatBW()\r
+ {\r
+ return patBW;\r
+ }\r
+ public double[] getPatPowBW()\r
+ {\r
+ return patpowBW;\r
+ }\r
+ public int getWidth()\r
+ {\r
+ return width;\r
+ }\r
+ public int getHeight()\r
+ {\r
+ return height;\r
+ }\r
+ \r
+ public NyARCode(int i_width,int i_height)\r
+ {\r
+ width=i_width;\r
+ height=i_height;\r
+ pat=new int[4][height][width][3];//static int pat[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ patBW=new short[4][height][width];//static int patBW[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ }\r
+ /**\r
+ * int arLoadPatt( const char *filename );\r
+ * ARToolKitのパターンファイルをロードする。\r
+ * ファイル形式はBGR形式で記録されたパターンファイルであること。\r
+ * @param filename\r
+ * @return\r
+ * @throws Exception\r
+ */\r
+ public void loadFromARFile(String filename) throws NyARException\r
+ {\r
+ try {\r
+ loadFromARFile(new FileInputStream(filename));\r
+\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ }\r
+ /**\r
+ * \r
+ * @param i_stream\r
+ * @throws NyARException\r
+ */\r
+ public void loadFromARFile(InputStream i_stream) throws NyARException\r
+ {\r
+ try{\r
+ StreamTokenizer st=new StreamTokenizer(new InputStreamReader(i_stream));\r
+ //パターンデータはGBRAで並んでる。\r
+ for(int h=0; h<4; h++ ) {\r
+ int l = 0;\r
+ for(int i3 = 0; i3 < 3; i3++ ) {\r
+ for(int i2 = 0; i2 < height; i2++ ) {\r
+ for(int i1 = 0; i1 < width; i1++ ){\r
+ //数値のみ読み出す\r
+ switch(st.nextToken()){//if( fscanf(fp, "%d", &j) != 1 ) {\r
+ case StreamTokenizer.TT_NUMBER:\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ short j=(short)(255-st.nval);//j = 255-j;\r
+ //標準ファイルのパターンはBGRでならんでるからRGBに並べなおす\r
+ switch(i3){\r
+ case 0:pat[h][i2][i1][2] = j;break;//pat[patno][h][(i2*Config.AR_PATT_SIZE_X+i1)*3+2] = j;break;\r
+ case 1:pat[h][i2][i1][1] = j;break;//pat[patno][h][(i2*Config.AR_PATT_SIZE_X+i1)*3+1] = j;break;\r
+ case 2:pat[h][i2][i1][0] = j;break;//pat[patno][h][(i2*Config.AR_PATT_SIZE_X+i1)*3+0] = j;break;\r
+ }\r
+ //pat[patno][h][(i2*Config.AR_PATT_SIZE_X+i1)*3+i3] = j;\r
+ if( i3 == 0 ){\r
+ patBW[h][i2][i1] = j;//patBW[patno][h][i2*Config.AR_PATT_SIZE_X+i1] = j;\r
+ }else{\r
+ patBW[h][i2][i1] += j;//patBW[patno][h][i2*Config.AR_PATT_SIZE_X+i1] += j;\r
+ }\r
+ if( i3 == 2 ){\r
+ patBW[h][i2][i1] /= 3;//patBW[patno][h][i2*Config.AR_PATT_SIZE_X+i1] /= 3;\r
+ }\r
+ l += j;\r
+ }\r
+ }\r
+ }\r
+ \r
+ l /= (height*width*3);\r
+ \r
+ int m = 0;\r
+ for(int i = 0; i < height; i++ ) {//for( i = 0; i < AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3; i++ ) {\r
+ for(int i2 = 0; i2 < width; i2++ ) {\r
+ for(int i3 = 0; i3 < 3; i3++ ) {\r
+ pat[h][i][i2][i3] -= l;\r
+ m += (pat[h][i][i2][i3]*pat[h][i][i2][i3]);\r
+ }\r
+ }\r
+ }\r
+ patpow[h] = Math.sqrt((double)m);\r
+ if( patpow[h] == 0.0 ){\r
+ patpow[h] = 0.0000001;\r
+ }\r
+ \r
+ m = 0;\r
+ for(int i = 0; i < height; i++ ) {\r
+ for(int i2 = 0; i2 < width; i2++ ) {\r
+ patBW[h][i][i2] -= l;\r
+ m += (patBW[h][i][i2]*patBW[h][i][i2]);\r
+ }\r
+ }\r
+ patpowBW[h] = Math.sqrt((double)m);\r
+ if(patpowBW[h] == 0.0 ){\r
+ patpowBW[h] = 0.0000001;\r
+ }\r
+ }\r
+ }catch(Exception e){\r
+ throw new NyARException(e);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+public interface NyARColorPatt\r
+{\r
+// 消すかも。\r
+// /**\r
+// * カラーパターンのサイズを変更します。\r
+// * 変更を行うと、既にgetPatArrayで参照中の配列内容は不定になり、インスタンスのパラメータは初期状態に戻ります。\r
+// * @param i_new_width\r
+// * 新しいパターン幅\r
+// * @param i_new_height\r
+// * 新しいパターン高\r
+// */\r
+// public void setSize(int i_new_width,int i_new_height);\r
+ /**\r
+ * カラーパターンの幅をピクセル値で返します。\r
+ * @return\r
+ */\r
+ public int getWidth();\r
+ /**\r
+ * カラーパターンの高さをピクセル値で返します。\r
+ * @return\r
+ */\r
+ public int getHeight();\r
+ /**\r
+ * カメラパターンを格納した配列への参照値を返します。\r
+ * 配列は最低でも[height][wight][3]のサイズを持ちますが、\r
+ * 配列のlengthとwidth,heightの数は一致しないことがあります。\r
+ * setSize関数を実行すると、以前に呼び出されたgetPatArrayが返した値は不定になります。\r
+ * @return\r
+ */\r
+ public int[][][] getPatArray();\r
+ /**\r
+ * ラスタイメージからi_marker部分のカラーパターンを抽出して、保持します。\r
+ * @param image\r
+ * @param i_marker\r
+ * @return\r
+ * ラスターの取得に成功するとTRUE/失敗するとFALSE\r
+ * @throws NyARException\r
+ */\r
+ public boolean pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException;\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARRaster;\r
+\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。\r
+ * このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序以外の最適化をしたもの\r
+ *\r
+ */\r
+public class NyARColorPatt_O1 implements NyARColorPatt\r
+{\r
+ private static final int AR_PATT_SAMPLE_NUM=64;//#define AR_PATT_SAMPLE_NUM 64\r
+ private int extpat[][][];\r
+ private int width;\r
+ private int height;\r
+ public NyARColorPatt_O1(int i_width,int i_height)\r
+ {\r
+ this.width =i_width;\r
+ this.height=i_height;\r
+ this.extpat=new int[i_height][i_width][3];\r
+ this.wk_pickFromRaster_ext_pat2=new int[i_height][i_width][3];\r
+ }\r
+// public void setSize(int i_new_width,int i_new_height)\r
+// {\r
+// int array_w=this.extpat[0].length;\r
+// int array_h=this.extpat.length;\r
+// //十分なサイズのバッファがあるか確認\r
+// if(array_w>=i_new_width && array_h>=i_new_height){\r
+// //OK 十分だ→サイズ調整のみ\r
+// }else{\r
+// //足りないよ→取り直し\r
+// this.wk_pickFromRaster_ext_pat2=new int[i_new_height][i_new_width][3];\r
+// this.extpat=new int[i_new_height][i_new_width][3];\r
+// }\r
+// this.width =i_new_width;\r
+// this.height=i_new_height;\r
+// return; \r
+// }\r
+ \r
+ public int[][][] getPatArray()\r
+ {\r
+ return extpat;\r
+ }\r
+ public int getWidth()\r
+ {\r
+ return width;\r
+ }\r
+ public int getHeight()\r
+ {\r
+ return height;\r
+ }\r
+ private final NyARMat wk_get_cpara_a=new NyARMat(8,8);\r
+ private final NyARMat wk_get_cpara_b=new NyARMat(8,1);\r
+ private final NyARMat wk_get_cpara_c=new NyARMat(8,1);\r
+ /**\r
+ * \r
+ * @param world\r
+ * @param vertex\r
+ * @param para\r
+ * [3x3]\r
+ * @throws NyARException\r
+ */\r
+ private boolean get_cpara( double world[][], double vertex[][],double[] para) throws NyARException\r
+ {\r
+ NyARMat a =wk_get_cpara_a;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
+ double[][] a_array=a.getArray();\r
+ NyARMat b =wk_get_cpara_b;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
+ double[][] b_array=b.getArray();\r
+ double[] a_pt0,a_pt1,world_pti;\r
+\r
+ for(int i = 0; i < 4; i++ ) {\r
+ a_pt0=a_array[i*2];\r
+ a_pt1=a_array[i*2+1];\r
+ world_pti=world[i];\r
+ \r
+ a_pt0[0]=world_pti[0];//a->m[i*16+0] = world[i][0];\r
+ a_pt0[1]=world_pti[1];//a->m[i*16+1] = world[i][1];\r
+ a_pt0[2]=1.0;//a->m[i*16+2] = 1.0;\r
+ a_pt0[3]=0.0;//a->m[i*16+3] = 0.0;\r
+ a_pt0[4]=0.0;//a->m[i*16+4] = 0.0;\r
+ a_pt0[5]=0.0;//a->m[i*16+5] = 0.0;\r
+ a_pt0[6]=-world_pti[0] * vertex[i][0];//a->m[i*16+6] = -world[i][0] * vertex[i][0];\r
+ a_pt0[7]=-world_pti[1] * vertex[i][0];//a->m[i*16+7] = -world[i][1] * vertex[i][0];\r
+ a_pt1[0]=0.0;//a->m[i*16+8] = 0.0;\r
+ a_pt1[1]=0.0;//a->m[i*16+9] = 0.0;\r
+ a_pt1[2]=0.0;//a->m[i*16+10] = 0.0;\r
+ a_pt1[3]=world_pti[0];//a->m[i*16+11] = world[i][0];\r
+ a_pt1[4]=world_pti[1];//a->m[i*16+12] = world[i][1];\r
+ a_pt1[5]=1.0;//a->m[i*16+13] = 1.0;\r
+ a_pt1[6]=-world_pti[0] * vertex[i][1];//a->m[i*16+14] = -world[i][0] * vertex[i][1];\r
+ a_pt1[7]=-world_pti[1] * vertex[i][1];//a->m[i*16+15] = -world[i][1] * vertex[i][1];\r
+ b_array[i*2+0][0]=vertex[i][0];//b->m[i*2+0] = vertex[i][0];\r
+ b_array[i*2+1][0]=vertex[i][1];//b->m[i*2+1] = vertex[i][1];\r
+ }\r
+// JartkException.trap("未チェックのパス");\r
+ if(!a.matrixSelfInv()){\r
+ return false;//逆行列を求められないので失敗\r
+ }\r
+ \r
+// JartkException.trap("未チェックのパス");\r
+ NyARMat c = wk_get_cpara_c;//次処理で結果を受け取るので、初期化不要//new NyARMat( 8, 1 );\r
+ double[][] c_array=c.getArray();\r
+\r
+ c.matrixMul(a, b);\r
+ for(int i = 0; i < 2; i++ ) {\r
+ para[i*3+0] = c_array[i*3+0][0];//para[i][0] = c->m[i*3+0];\r
+ para[i*3+1] = c_array[i*3+1][0];//para[i][1] = c->m[i*3+1];\r
+ para[i*3+2] = c_array[i*3+2][0];//para[i][2] = c->m[i*3+2];\r
+ }\r
+ para[2*3+0] = c_array[2*3+0][0];//para[2][0] = c->m[2*3+0];\r
+ para[2*3+1] = c_array[2*3+1][0];//para[2][1] = c->m[2*3+1];\r
+ para[2*3+2] = 1.0;//para[2][2] = 1.0;\r
+ return true;\r
+ }\r
+\r
+ private final double[][] wk_pickFromRaster_local=new double[4][2];\r
+ private final double[] wk_pickFromRaster_para=new double[9];//[3][3];\r
+ private int[][][] wk_pickFromRaster_ext_pat2=null;//コンストラクタでint[height][width][3]を作る\r
+ private final double[][] wk_pickFromRaster_world={//double world[4][2];\r
+ {100.0, 100.0},\r
+ {100.0+10.0,100.0},\r
+ {100.0+10.0,100.0 + 10.0},\r
+ {100.0, 100.0 + 10.0}\r
+ };\r
+ /**\r
+ * pickFromRaster関数から使う変数です。\r
+ *\r
+ */\r
+ private static void initValue_wk_pickFromRaster_ext_pat2(int[][][] i_ext_pat2,int i_width,int i_height)\r
+ {\r
+ int i,i2;\r
+ int[][] pt2;\r
+ int[] pt1;\r
+ for(i=i_height-1;i>=0;i--){\r
+ pt2=i_ext_pat2[i];\r
+ for(i2=i_width-1;i2>=0;i2--){\r
+ pt1=pt2[i2];\r
+ pt1[0]=0;\r
+ pt1[1]=0;\r
+ pt1[2]=0;\r
+ }\r
+ }\r
+ }\r
+ private final int[] wk_pickFromRaster_rgb_tmp=new int[3];\r
+ /**\r
+ * imageから、i_markerの位置にあるパターンを切り出して、保持します。\r
+ * Optimize:STEP[769->]\r
+ * @param image\r
+ * @param i_marker\r
+ * @return\r
+ * 切り出しに失敗した\r
+ * @throws Exception\r
+ */\r
+ public boolean pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException\r
+ {\r
+ double d, xw, yw;\r
+ int xc, yc;\r
+ int xdiv, ydiv;\r
+ int xdiv2, ydiv2;\r
+ int lx1, lx2, ly1, ly2;\r
+\r
+ int img_x=image.getWidth();\r
+ int img_y=image.getHeight();\r
+\r
+ double xdiv2_reciprocal; // [tp]\r
+ double ydiv2_reciprocal; // [tp]\r
+\r
+\r
+ int[] x_coord=i_marker.x_coord;\r
+ int[] y_coord=i_marker.y_coord;\r
+ double[][] local=wk_pickFromRaster_local;//double local[4][2]; \r
+ int[] vertex=i_marker.mkvertex;\r
+ for(int i = 0; i < 4; i++ ) {\r
+ local[i][0] = x_coord[vertex[i]];\r
+ local[i][1] = y_coord[vertex[i]];\r
+ }\r
+ double[][] world=wk_pickFromRaster_world;\r
+/* world[0][0] = 100.0;\r
+ world[0][1] = 100.0;\r
+ world[1][0] = 100.0 + 10.0;\r
+ world[1][1] = 100.0;\r
+ world[2][0] = 100.0 + 10.0;\r
+ world[2][1] = 100.0 + 10.0;\r
+ world[3][0] = 100.0;\r
+ world[3][1] = 100.0 + 10.0;*/\r
+ double[] para =wk_pickFromRaster_para; //double para[3][3];\r
+ //パターンの切り出しに失敗することもある。\r
+ if(!get_cpara( world, local, para )){\r
+ return false;\r
+ }\r
+ lx1 = (int)((local[0][0] - local[1][0])*(local[0][0] - local[1][0])+ (local[0][1] - local[1][1])*(local[0][1] - local[1][1]));\r
+ lx2 = (int)((local[2][0] - local[3][0])*(local[2][0] - local[3][0])+ (local[2][1] - local[3][1])*(local[2][1] - local[3][1]));\r
+ ly1 = (int)((local[1][0] - local[2][0])*(local[1][0] - local[2][0])+ (local[1][1] - local[2][1])*(local[1][1] - local[2][1]));\r
+ ly2 = (int)((local[3][0] - local[0][0])*(local[3][0] - local[0][0])+ (local[3][1] - local[0][1])*(local[3][1] - local[0][1]));\r
+ if( lx2 > lx1 ){\r
+ lx1 = lx2;\r
+ }\r
+ if( ly2 > ly1 ){\r
+ ly1 = ly2;\r
+ }\r
+ xdiv2 =this.width;\r
+ ydiv2 =this.height;\r
+\r
+ while( xdiv2*xdiv2 < lx1/4 ){\r
+ xdiv2*=2;\r
+ }\r
+ while( ydiv2*ydiv2 < ly1/4 ){\r
+ ydiv2*=2;\r
+ }\r
+\r
+ if( xdiv2 > AR_PATT_SAMPLE_NUM)\r
+ {\r
+ xdiv2 =AR_PATT_SAMPLE_NUM;\r
+ }\r
+ if( ydiv2 >AR_PATT_SAMPLE_NUM)\r
+ {\r
+ ydiv2 = AR_PATT_SAMPLE_NUM;\r
+ }\r
+\r
+ xdiv = xdiv2/width;//xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
+ ydiv = ydiv2/height;//ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+\r
+ /*wk_pickFromRaster_ext_pat2ワーク変数を初期化する。*/\r
+ int[][][] ext_pat2=wk_pickFromRaster_ext_pat2;//ARUint32 ext_pat2[AR_PATT_SIZE_Y][AR_PATT_SIZE_X][3];\r
+ int extpat_j[][],extpat_j_i[];\r
+ int ext_pat2_j[][],ext_pat2_j_i[];\r
+\r
+ initValue_wk_pickFromRaster_ext_pat2(ext_pat2,this.width,this.height);\r
+\r
+ xdiv2_reciprocal = 1.0 / xdiv2;\r
+ ydiv2_reciprocal = 1.0 / ydiv2;\r
+ int i,j;\r
+ int[] rgb_tmp=wk_pickFromRaster_rgb_tmp;\r
+ // arGetCode_put_zero(ext_pat2);//put_zero( (ARUint8 *)ext_pat2, AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3*sizeof(ARUint32) );\r
+ for(j = 0; j < ydiv2; j++ ) {\r
+ yw = 102.5 + 5.0 * (j+0.5) * ydiv2_reciprocal;\r
+ for(i = 0; i < xdiv2; i++ ) {\r
+ xw = 102.5 + 5.0 * (i+0.5) * xdiv2_reciprocal;\r
+ d = para[2*3+0]*xw + para[2*3+1]*yw + para[2*3+2];\r
+ if( d == 0 ){\r
+ throw new NyARException();\r
+ }\r
+ xc = (int)((para[0*3+0]*xw + para[0*3+1]*yw + para[0*3+2])/d);\r
+ yc = (int)((para[1*3+0]*xw + para[1*3+1]*yw + para[1*3+2])/d);\r
+\r
+\r
+ if( xc >= 0 && xc < img_x && yc >= 0 && yc < img_y ) {\r
+ image.getPixel(xc, yc, rgb_tmp);\r
+ ext_pat2_j_i=ext_pat2[j/ydiv][i/xdiv];\r
+\r
+ ext_pat2_j_i[0] += rgb_tmp[0];//R\r
+ ext_pat2_j_i[1] += rgb_tmp[1];//G\r
+ ext_pat2_j_i[2] += rgb_tmp[2];//B\r
+// System.out.println(xc+":"+yc+":"+rgb_tmp[0]+":"+rgb_tmp[1]+":"+rgb_tmp[2]);\r
+ }\r
+ }\r
+ }\r
+// short[][][] ext_pat=new short[Config.AR_PATT_SIZE_Y][Config.AR_PATT_SIZE_X][3];//ARUint32 ext_pat2[AR_PATT_SIZE_Y][AR_PATT_SIZE_X][3];\r
+ /*<Optimize>*/\r
+ int xdiv_x_ydiv=xdiv*ydiv;\r
+ for(j = this.height-1; j>=0; j--){\r
+ extpat_j=extpat[j];\r
+ ext_pat2_j=ext_pat2[j];\r
+ for(i = this.width-1; i>=0; i--){ // PRL 2006-06-08.\r
+ ext_pat2_j_i=ext_pat2_j[i];\r
+ extpat_j_i=extpat_j[i];\r
+ extpat_j_i[0]=(ext_pat2_j_i[0] / xdiv_x_ydiv);//ext_pat[j][i][0] = (byte)(ext_pat2[j][i][0] / (xdiv*ydiv));\r
+ extpat_j_i[1]=(ext_pat2_j_i[1] / xdiv_x_ydiv);//ext_pat[j][i][1] = (byte)(ext_pat2[j][i][1] / (xdiv*ydiv));\r
+ extpat_j_i[2]=(ext_pat2_j_i[2] / xdiv_x_ydiv);//ext_pat[j][i][2] = (byte)(ext_pat2[j][i][2] / (xdiv*ydiv));\r
+ }\r
+ }/*\r
+ int xdiv_mul_ydiv=xdiv*ydiv;\r
+ short [][] extpat_pt_2;\r
+ short[] extpat_pt_1;\r
+ int[][] ext_pat2_pt_2;\r
+ int[] ext_pat2_pt_1;\r
+ for(int j=this.height-1; j>=0; j--){//for(int j = 0; j < this.height; j++ ){\r
+ extpat_pt_2=extpat[j];\r
+ ext_pat2_pt_2=ext_pat2[j];\r
+ for(int i = this.width-1; i>=0; i--){//for(int i = 0; i < this.width; i++ ){ // PRL 2006-06-08.\r
+ extpat_pt_1=extpat_pt_2[i];\r
+ ext_pat2_pt_1=ext_pat2_pt_2[i]; \r
+ extpat_pt_1[0]=(short)(ext_pat2_pt_1[0] / xdiv_mul_ydiv);//ext_pat[j][i][0] = (byte)(ext_pat2[j][i][0] / (xdiv*ydiv));\r
+ extpat_pt_1[1]=(short)(ext_pat2_pt_1[1] / xdiv_mul_ydiv);//ext_pat[j][i][1] = (byte)(ext_pat2[j][i][1] / (xdiv*ydiv));\r
+ extpat_pt_1[2]=(short)(ext_pat2_pt_1[2] / xdiv_mul_ydiv);//ext_pat[j][i][2] = (byte)(ext_pat2[j][i][2] / (xdiv*ydiv));\r
+ }\r
+ }\r
+ /*</Optimize>*/\r
+ return true;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARRaster;\r
+\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。\r
+ * このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序を含む最適化をしたもの\r
+ *\r
+ */\r
+public class NyARColorPatt_O2 implements NyARColorPatt\r
+{\r
+ private static final int AR_PATT_SAMPLE_NUM=64;//#define AR_PATT_SAMPLE_NUM 64\r
+ private int extpat[][][];\r
+ private int width;\r
+ private int height;\r
+ public NyARColorPatt_O2(int i_width,int i_height)\r
+ {\r
+ this.width=i_width;\r
+ this.height=i_height;\r
+ this.extpat=new int[i_height][i_width][3];\r
+ this.wk_pickFromRaster_ext_pat2=new int[i_height][i_width][3];\r
+ }\r
+// public void setSize(int i_new_width,int i_new_height)\r
+// {\r
+// int array_w=this.extpat[0].length;\r
+// int array_h=this.extpat.length;\r
+// //十分なサイズのバッファがあるか確認\r
+// if(array_w>=i_new_width && array_h>=i_new_height){\r
+// //OK 十分だ→サイズ調整のみ\r
+// }else{\r
+// //足りないよ→取り直し\r
+// this.wk_pickFromRaster_ext_pat2=new int[i_new_height][i_new_width][3];\r
+// this.extpat=new int[i_new_height][i_new_width][3];\r
+// }\r
+// this.width =i_new_width;\r
+// this.height=i_new_height;\r
+// return;\r
+// }\r
+ public int[][][] getPatArray()\r
+ {\r
+ return extpat;\r
+ }\r
+ public int getWidth()\r
+ {\r
+ return width;\r
+ }\r
+ public int getHeight()\r
+ {\r
+ return height;\r
+ }\r
+ private final NyARMat wk_get_cpara_a=new NyARMat(8,8);\r
+ private final NyARMat wk_get_cpara_b=new NyARMat(8,1);\r
+// private final NyARMat wk_get_cpara_c=new NyARMat(8,1);\r
+ /**\r
+ * @param world\r
+ * @param vertex\r
+ * @param o_para\r
+ * @throws NyARException\r
+ */\r
+ private boolean get_cpara(double vertex_0[], double vertex_1[],NyARMat o_para) throws NyARException\r
+ {\r
+ double world[][]=this.wk_pickFromRaster_world;\r
+ NyARMat a =wk_get_cpara_a;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
+ double[][] a_array=a.getArray();\r
+ NyARMat b =wk_get_cpara_b;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
+ double[][] b_array=b.getArray();\r
+ double[] a_pt0,a_pt1,world_pti;\r
+\r
+ for(int i = 0; i < 4; i++ ) {\r
+ a_pt0=a_array[i*2];\r
+ a_pt1=a_array[i*2+1];\r
+ world_pti=world[i];\r
+\r
+ a_pt0[0]=world_pti[0];//a->m[i*16+0] = world[i][0];\r
+ a_pt0[1]=world_pti[1];//a->m[i*16+1] = world[i][1];\r
+ a_pt0[2]=1.0;//a->m[i*16+2] = 1.0;\r
+ a_pt0[3]=0.0;//a->m[i*16+3] = 0.0;\r
+ a_pt0[4]=0.0;//a->m[i*16+4] = 0.0;\r
+ a_pt0[5]=0.0;//a->m[i*16+5] = 0.0;\r
+ a_pt0[6]=-world_pti[0] * vertex_0[i];//a->m[i*16+6] = -world[i][0] * vertex[i][0];\r
+ a_pt0[7]=-world_pti[1] * vertex_0[i];//a->m[i*16+7] = -world[i][1] * vertex[i][0];\r
+ a_pt1[0]=0.0;//a->m[i*16+8] = 0.0;\r
+ a_pt1[1]=0.0;//a->m[i*16+9] = 0.0;\r
+ a_pt1[2]=0.0;//a->m[i*16+10] = 0.0;\r
+ a_pt1[3]=world_pti[0];//a->m[i*16+11] = world[i][0];\r
+ a_pt1[4]=world_pti[1];//a->m[i*16+12] = world[i][1];\r
+ a_pt1[5]=1.0;//a->m[i*16+13] = 1.0;\r
+ a_pt1[6]=-world_pti[0] * vertex_1[i];//a->m[i*16+14] = -world[i][0] * vertex[i][1];\r
+ a_pt1[7]=-world_pti[1] * vertex_1[i];//a->m[i*16+15] = -world[i][1] * vertex[i][1];\r
+ b_array[i*2+0][0]=vertex_0[i];//b->m[i*2+0] = vertex[i][0];\r
+ b_array[i*2+1][0]=vertex_1[i];//b->m[i*2+1] = vertex[i][1];\r
+ }\r
+// JartkException.trap("未チェックのパス");\r
+ if(!a.matrixSelfInv()){\r
+ return false;\r
+ }\r
+\r
+// JartkException.trap("未チェックのパス");\r
+// NyARMat c = wk_get_cpara_c;//次処理で結果を受け取るので、初期化不要//new NyARMat( 8, 1 );\r
+// double[][] c_array=c.getArray();\r
+\r
+ o_para.matrixMul(a, b);\r
+// para[0*3+0] = c_array[0*3+0][0];//para[i][0] = c->m[i*3+0];\r
+// para[0*3+1] = c_array[0*3+1][0];//para[i][1] = c->m[i*3+1];\r
+// para[0*3+2] = c_array[0*3+2][0];//para[i][2] = c->m[i*3+2];\r
+// para[1*3+0] = c_array[1*3+0][0];//para[i][0] = c->m[i*3+0];\r
+// para[1*3+1] = c_array[1*3+1][0];//para[i][1] = c->m[i*3+1];\r
+// para[i*3+2] = c_array[1*3+2][0];//para[i][2] = c->m[i*3+2];\r
+// para[2*3+0] = c_array[2*3+0][0];//para[2][0] = c->m[2*3+0];\r
+// para[2*3+1] = c_array[2*3+1][0];//para[2][1] = c->m[2*3+1];\r
+// para[2*3+2] = 1.0;//para[2][2] = 1.0;\r
+ return true;\r
+ }\r
+\r
+ // private final double[] wk_pickFromRaster_para=new double[9];//[3][3];\r
+ private int[][][] wk_pickFromRaster_ext_pat2=null;//コンストラクタでint[height][width][3]を作る\r
+ private final double[][] wk_pickFromRaster_world={//double world[4][2];\r
+ {100.0, 100.0},\r
+ {100.0+10.0,100.0},\r
+ {100.0+10.0,100.0 + 10.0},\r
+ {100.0, 100.0 + 10.0}\r
+ };\r
+ /**\r
+ * pickFromRaster関数から使う変数です。\r
+ *\r
+ */\r
+ private static void initValue_wk_pickFromRaster_ext_pat2(int[][][] i_ext_pat2,int i_width,int i_height)\r
+ {\r
+ int i,i2;\r
+ int[][] pt2;\r
+ int[] pt1;\r
+ for(i=i_height-1;i>=0;i--){\r
+ pt2=i_ext_pat2[i];\r
+ for(i2=i_width-1;i2>=0;i2--){\r
+ pt1=pt2[i2];\r
+ pt1[0]=0;\r
+ pt1[1]=0;\r
+ pt1[2]=0;\r
+ }\r
+ }\r
+ }\r
+ private final double[][] wk_pickFromRaster_local=new double[2][4];\r
+ private final int[] wk_pickFromRaster_rgb_tmp=new int[3];\r
+ private final NyARMat wk_pickFromRaster_cpara=new NyARMat(8,1);\r
+ /**\r
+ * imageから、i_markerの位置にあるパターンを切り出して、保持します。\r
+ * Optimize:STEP[769->750]\r
+ * @param image\r
+ * @param i_marker\r
+ * @throws Exception\r
+ */\r
+ public boolean pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException\r
+ {\r
+ NyARMat cpara=this.wk_pickFromRaster_cpara;\r
+ //localの計算\r
+ int[] x_coord=i_marker.x_coord;\r
+ int[] y_coord=i_marker.y_coord;\r
+ int[] vertex=i_marker.mkvertex;\r
+ double[] local_0=wk_pickFromRaster_local[0];//double local[4][2]; \r
+ double[] local_1=wk_pickFromRaster_local[1];//double local[4][2]; \r
+ for(int i = 0; i < 4; i++ ) {\r
+ local_0[i] = x_coord[vertex[i]];\r
+ local_1[i] = y_coord[vertex[i]];\r
+ }\r
+ //xdiv2,ydiv2の計算\r
+ int xdiv2, ydiv2;\r
+ int l1,l2;\r
+ double w1,w2;\r
+\r
+ //x計算\r
+ w1=local_0[0] - local_0[1];\r
+ w2=local_1[0] - local_1[1];\r
+ l1 = (int)(w1*w1+w2*w2);\r
+ w1=local_0[2] - local_0[3];\r
+ w2=local_1[2] - local_1[3];\r
+ l2 = (int)(w1*w1+w2*w2);\r
+ if( l2 > l1 ){\r
+ l1 = l2;\r
+ }\r
+ l1=l1/4;\r
+ xdiv2 =this.width;\r
+ while( xdiv2*xdiv2 < l1 ){\r
+ xdiv2*=2;\r
+ }\r
+ if( xdiv2 > AR_PATT_SAMPLE_NUM)\r
+ {\r
+ xdiv2 =AR_PATT_SAMPLE_NUM;\r
+ }\r
+ \r
+ //y計算\r
+ w1=local_0[1] - local_0[2];\r
+ w2=local_1[1] - local_1[2];\r
+ l1 = (int)(w1*w1+ w2*w2);\r
+ w1=local_0[3] - local_0[0];\r
+ w2=local_1[3] - local_1[0];\r
+ l2 = (int)(w1*w1+ w2*w2);\r
+ if( l2 > l1 ){\r
+ l1 = l2;\r
+ }\r
+ ydiv2 =this.height;\r
+ l1=l1/4;\r
+ while( ydiv2*ydiv2 < l1 ){\r
+ ydiv2*=2;\r
+ }\r
+ if( ydiv2 >AR_PATT_SAMPLE_NUM)\r
+ {\r
+ ydiv2 = AR_PATT_SAMPLE_NUM;\r
+ } \r
+ \r
+ //cparaの計算\r
+ if(!get_cpara(local_0,local_1,cpara)){\r
+ return false;\r
+ }\r
+\r
+ int img_x=image.getWidth();\r
+ int img_y=image.getHeight();\r
+\r
+ /*wk_pickFromRaster_ext_pat2ワーク変数を初期化する。*/\r
+ int[][][] ext_pat2=wk_pickFromRaster_ext_pat2;//ARUint32 ext_pat2[AR_PATT_SIZE_Y][AR_PATT_SIZE_X][3];\r
+ int extpat_j[][],extpat_j_i[];\r
+ int ext_pat2_j[][],ext_pat2_j_i[];\r
+\r
+ initValue_wk_pickFromRaster_ext_pat2(ext_pat2,this.width,this.height);\r
+\r
+ double[][] cpara_array=cpara.getArray();\r
+ double para21_x_yw,para01_x_yw,para11_x_yw;\r
+ double para00,para01,para02,para10,para11,para12,para20,para21;\r
+ para00 = cpara_array[0*3+0][0];//para[i][0] = c->m[i*3+0];\r
+ para01 = cpara_array[0*3+1][0];//para[i][1] = c->m[i*3+1];\r
+ para02 = cpara_array[0*3+2][0];//para[i][2] = c->m[i*3+2];\r
+ para10 = cpara_array[1*3+0][0];//para[i][0] = c->m[i*3+0];\r
+ para11 = cpara_array[1*3+1][0];//para[i][1] = c->m[i*3+1];\r
+ para12 = cpara_array[1*3+2][0];//para[i][2] = c->m[i*3+2];\r
+ para20 = cpara_array[2*3+0][0];//para[2][0] = c->m[2*3+0];\r
+ para21 = cpara_array[2*3+1][0];//para[2][1] = c->m[2*3+1];\r
+ //para22 = 1.0;//para[2][2] = 1.0;\r
+\r
+ \r
+ double d, xw, yw;\r
+ int xc, yc;\r
+ int i,j;\r
+ int[] rgb_tmp=wk_pickFromRaster_rgb_tmp;\r
+ // arGetCode_put_zero(ext_pat2);//put_zero( (ARUint8 *)ext_pat2, AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3*sizeof(ARUint32) );\r
+ int xdiv = xdiv2/width;//xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
+ int ydiv = ydiv2/height;//ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+ double xdiv2_reciprocal = 1.0 / xdiv2;\r
+ double ydiv2_reciprocal = 1.0 / ydiv2;\r
+\r
+ for(j = 0; j < ydiv2; j++ ) {\r
+ yw = 102.5 + 5.0 * ((double)j+0.5) * ydiv2_reciprocal;\r
+ para21_x_yw=para21*yw+1.0;\r
+ para11_x_yw=para11*yw+para12;\r
+ para01_x_yw=para01*yw+para02;\r
+ ext_pat2_j=ext_pat2[j/ydiv];\r
+ for(i = 0; i < xdiv2; i++ ) {\r
+ xw = 102.5 + 5.0 * ((double)i+0.5) * xdiv2_reciprocal;\r
+ d = para20*xw + para21_x_yw;\r
+ if( d == 0 ){\r
+ throw new NyARException();\r
+ }\r
+ xc = (int)((para00*xw + para01_x_yw)/d);\r
+ yc = (int)((para10*xw + para11_x_yw)/d);\r
+\r
+\r
+ if( xc >= 0 && xc < img_x && yc >= 0 && yc < img_y ) {\r
+ image.getPixel(xc, yc, rgb_tmp);\r
+ ext_pat2_j_i=ext_pat2_j[i/xdiv];\r
+\r
+ ext_pat2_j_i[0] += rgb_tmp[0];//R\r
+ ext_pat2_j_i[1] += rgb_tmp[1];//G\r
+ ext_pat2_j_i[2] += rgb_tmp[2];//B\r
+ }\r
+ }\r
+ }\r
+ /*<Optimize>*/\r
+ int xdiv_x_ydiv=xdiv*ydiv;\r
+ for(j =this.height-1; j>=0; j--){\r
+ extpat_j=extpat[j];\r
+ ext_pat2_j=ext_pat2[j];\r
+ for(i = this.width-1; i>=0; i--){ // PRL 2006-06-08.\r
+ ext_pat2_j_i=ext_pat2_j[i];\r
+ extpat_j_i=extpat_j[i];\r
+ extpat_j_i[0]=(ext_pat2_j_i[0] / xdiv_x_ydiv);//ext_pat[j][i][0] = (byte)(ext_pat2[j][i][0] / (xdiv*ydiv));\r
+ extpat_j_i[1]=(ext_pat2_j_i[1] / xdiv_x_ydiv);//ext_pat[j][i][1] = (byte)(ext_pat2[j][i][1] / (xdiv*ydiv));\r
+ extpat_j_i[2]=(ext_pat2_j_i[2] / xdiv_x_ydiv);//ext_pat[j][i][2] = (byte)(ext_pat2[j][i][2] / (xdiv*ydiv));\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARRaster;\r
+\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。\r
+ * このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序を含む最適化をしたもの\r
+ *\r
+ */\r
+public class NyARColorPatt_O3 implements NyARColorPatt\r
+{\r
+ private static final int AR_PATT_SAMPLE_NUM=64;//#define AR_PATT_SAMPLE_NUM 64\r
+ private int extpat[][][];\r
+ private int width;\r
+ private int height;\r
+ public NyARColorPatt_O3(int i_width,int i_height)\r
+ {\r
+ this.width=i_width;\r
+ this.height=i_height;\r
+ this.extpat=new int[i_height][i_width][3];\r
+ }\r
+// public void setSize(int i_new_width,int i_new_height)\r
+// {\r
+// int array_w=this.extpat[0].length;\r
+// int array_h=this.extpat.length;\r
+// //十分なサイズのバッファがあるか確認\r
+// if(array_w>=i_new_width && array_h>=i_new_height){\r
+// //OK 十分だ→サイズ調整のみ\r
+// }else{\r
+// //足りないよ→取り直し\r
+// this.extpat=new int[i_new_height][i_new_width][3];\r
+// }\r
+// this.width =i_new_width;\r
+// this.height=i_new_height;\r
+// return;\r
+// } \r
+ public int[][][] getPatArray()\r
+ {\r
+ return extpat;\r
+ }\r
+ public int getWidth()\r
+ {\r
+ return width;\r
+ }\r
+ public int getHeight()\r
+ {\r
+ return height;\r
+ }\r
+ private final NyARMat wk_get_cpara_a=new NyARMat(8,8);\r
+ private final NyARMat wk_get_cpara_b=new NyARMat(8,1);\r
+\r
+ /**\r
+ * @param world\r
+ * @param vertex\r
+ * @param o_para\r
+ * @throws NyARException\r
+ */\r
+ private boolean get_cpara(double vertex_0[], double vertex_1[],NyARMat o_para) throws NyARException\r
+ {\r
+ double world[][]=this.wk_pickFromRaster_world;\r
+ NyARMat a =wk_get_cpara_a;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
+ double[][] a_array=a.getArray();\r
+ NyARMat b =wk_get_cpara_b;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
+ double[][] b_array=b.getArray();\r
+ double[] a_pt0,a_pt1,world_pti;\r
+\r
+ for(int i = 0; i < 4; i++ ) {\r
+ a_pt0=a_array[i*2];\r
+ a_pt1=a_array[i*2+1];\r
+ world_pti=world[i];\r
+\r
+ a_pt0[0]=world_pti[0];//a->m[i*16+0] = world[i][0];\r
+ a_pt0[1]=world_pti[1];//a->m[i*16+1] = world[i][1];\r
+ a_pt0[2]=1.0;//a->m[i*16+2] = 1.0;\r
+ a_pt0[3]=0.0;//a->m[i*16+3] = 0.0;\r
+ a_pt0[4]=0.0;//a->m[i*16+4] = 0.0;\r
+ a_pt0[5]=0.0;//a->m[i*16+5] = 0.0;\r
+ a_pt0[6]=-world_pti[0] * vertex_0[i];//a->m[i*16+6] = -world[i][0] * vertex[i][0];\r
+ a_pt0[7]=-world_pti[1] * vertex_0[i];//a->m[i*16+7] = -world[i][1] * vertex[i][0];\r
+ a_pt1[0]=0.0;//a->m[i*16+8] = 0.0;\r
+ a_pt1[1]=0.0;//a->m[i*16+9] = 0.0;\r
+ a_pt1[2]=0.0;//a->m[i*16+10] = 0.0;\r
+ a_pt1[3]=world_pti[0];//a->m[i*16+11] = world[i][0];\r
+ a_pt1[4]=world_pti[1];//a->m[i*16+12] = world[i][1];\r
+ a_pt1[5]=1.0;//a->m[i*16+13] = 1.0;\r
+ a_pt1[6]=-world_pti[0] * vertex_1[i];//a->m[i*16+14] = -world[i][0] * vertex[i][1];\r
+ a_pt1[7]=-world_pti[1] * vertex_1[i];//a->m[i*16+15] = -world[i][1] * vertex[i][1];\r
+ b_array[i*2+0][0]=vertex_0[i];//b->m[i*2+0] = vertex[i][0];\r
+ b_array[i*2+1][0]=vertex_1[i];//b->m[i*2+1] = vertex[i][1];\r
+ }\r
+ if(!a.matrixSelfInv()){\r
+ return false;\r
+ } \r
+\r
+ o_para.matrixMul(a, b);\r
+ return true;\r
+ }\r
+\r
+ // private final double[] wk_pickFromRaster_para=new double[9];//[3][3];\r
+ private final double[][] wk_pickFromRaster_world={//double world[4][2];\r
+ {100.0, 100.0},\r
+ {100.0+10.0,100.0},\r
+ {100.0+10.0,100.0 + 10.0},\r
+ {100.0, 100.0 + 10.0}\r
+ };\r
+ /**\r
+ * pickFromRaster関数から使う変数です。\r
+ *\r
+ */\r
+ private static void initValue_wk_pickFromRaster_ext_pat2(int[][][] i_ext_pat2,int i_width,int i_height)\r
+ {\r
+ int i,i2;\r
+ int[][] pt2;\r
+ int[] pt1;\r
+ for(i=i_height-1;i>=0;i--){\r
+ pt2=i_ext_pat2[i];\r
+ for(i2=i_width-1;i2>=0;i2--){\r
+ pt1=pt2[i2];\r
+ pt1[0]=0;\r
+ pt1[1]=0;\r
+ pt1[2]=0;\r
+ }\r
+ }\r
+ }\r
+ private final double[][] wk_pickFromRaster_local=new double[2][4];\r
+ private final NyARMat wk_pickFromRaster_cpara=new NyARMat(8,1);\r
+ /**\r
+ * imageから、i_markerの位置にあるパターンを切り出して、保持します。\r
+ * Optimize:STEP[769->750]\r
+ * @param image\r
+ * @param i_marker\r
+ * @throws Exception\r
+ */\r
+ public boolean pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException\r
+ {\r
+ NyARMat cpara=this.wk_pickFromRaster_cpara;\r
+ //localの計算\r
+ int[] x_coord=i_marker.x_coord;\r
+ int[] y_coord=i_marker.y_coord;\r
+ int[] vertex=i_marker.mkvertex;\r
+ double[] local_0=wk_pickFromRaster_local[0];//double local[4][2]; \r
+ double[] local_1=wk_pickFromRaster_local[1];//double local[4][2]; \r
+ for(int i = 0; i < 4; i++ ) {\r
+ local_0[i] = x_coord[vertex[i]];\r
+ local_1[i] = y_coord[vertex[i]];\r
+ }\r
+ //xdiv2,ydiv2の計算\r
+ int xdiv2, ydiv2;\r
+ int l1,l2;\r
+ double w1,w2;\r
+\r
+ //x計算\r
+ w1=local_0[0] - local_0[1];\r
+ w2=local_1[0] - local_1[1];\r
+ l1 = (int)(w1*w1+w2*w2);\r
+ w1=local_0[2] - local_0[3];\r
+ w2=local_1[2] - local_1[3];\r
+ l2 = (int)(w1*w1+w2*w2);\r
+ if( l2 > l1 ){\r
+ l1 = l2;\r
+ }\r
+ l1=l1/4;\r
+ xdiv2 =this.width;\r
+ while( xdiv2*xdiv2 < l1 ){\r
+ xdiv2*=2;\r
+ }\r
+ if( xdiv2 > AR_PATT_SAMPLE_NUM)\r
+ {\r
+ xdiv2 =AR_PATT_SAMPLE_NUM;\r
+ }\r
+ \r
+ //y計算\r
+ w1=local_0[1] - local_0[2];\r
+ w2=local_1[1] - local_1[2];\r
+ l1 = (int)(w1*w1+ w2*w2);\r
+ w1=local_0[3] - local_0[0];\r
+ w2=local_1[3] - local_1[0];\r
+ l2 = (int)(w1*w1+ w2*w2);\r
+ if( l2 > l1 ){\r
+ l1 = l2;\r
+ }\r
+ ydiv2 =this.height;\r
+ l1=l1/4;\r
+ while( ydiv2*ydiv2 < l1 ){\r
+ ydiv2*=2;\r
+ }\r
+ if( ydiv2 >AR_PATT_SAMPLE_NUM)\r
+ {\r
+ ydiv2 = AR_PATT_SAMPLE_NUM;\r
+ } \r
+ \r
+ //cparaの計算\r
+ if(!get_cpara(local_0,local_1,cpara)){\r
+ return false;\r
+ }\r
+ updateExtpat(image,cpara,xdiv2,ydiv2);\r
+\r
+ return true;\r
+ }\r
+ //かなり大きいワークバッファを取るな…。\r
+ private double[] wk_updateExtpat_para00_xw;\r
+ private double[] wk_updateExtpat_para10_xw;\r
+ private double[] wk_updateExtpat_para20_xw;\r
+ private int[] wk_updateExtpat_rgb_buf;\r
+ private int[] wk_updateExtpat_x_rgb_index;\r
+ private int[] wk_updateExtpat_y_rgb_index;\r
+ private int[] wk_updateExtpat_i_rgb_index;\r
+ private int wk_updateExtpat_buffer_size=0;\r
+\r
+ /**\r
+ * ワークバッファを予約する\r
+ * @param i_xdiv2\r
+ */\r
+ private void reservWorkBuffers(int i_xdiv2)\r
+ {\r
+ if(this.wk_updateExtpat_buffer_size<i_xdiv2){\r
+ wk_updateExtpat_para00_xw=new double[i_xdiv2];\r
+ wk_updateExtpat_para10_xw=new double[i_xdiv2];\r
+ wk_updateExtpat_para20_xw=new double[i_xdiv2];\r
+ wk_updateExtpat_rgb_buf=new int[i_xdiv2*3];\r
+ wk_updateExtpat_x_rgb_index=new int[i_xdiv2];\r
+ wk_updateExtpat_y_rgb_index=new int[i_xdiv2];\r
+ wk_updateExtpat_i_rgb_index=new int[i_xdiv2];\r
+ this.wk_updateExtpat_buffer_size=i_xdiv2;\r
+ }\r
+ //十分なら何もしない。\r
+ return;\r
+ }\r
+ \r
+ private void updateExtpat(NyARRaster image,NyARMat i_cpara,int i_xdiv2,int i_ydiv2) throws NyARException\r
+ {\r
+ int img_x=image.getWidth();\r
+ int img_y=image.getHeight();\r
+ final int[][][] L_extpat=this.extpat;\r
+ final int L_WIDTH=this.width;\r
+ final int L_HEIGHT=this.height;\r
+ /*wk_pickFromRaster_ext_pat2ワーク変数を初期化する。*/\r
+ //int[][][] ext_pat2=wk_pickFromRaster_ext_pat2;//ARUint32 ext_pat2[AR_PATT_SIZE_Y][AR_PATT_SIZE_X][3];\r
+ int extpat_j[][],extpat_j_i[];\r
+ //int ext_pat2_j[][],ext_pat2_j_i[];\r
+\r
+ initValue_wk_pickFromRaster_ext_pat2(L_extpat,L_WIDTH,L_HEIGHT);\r
+\r
+ double[][] cpara_array=i_cpara.getArray();\r
+ double para21_x_yw,para01_x_yw,para11_x_yw;\r
+ double para00,para01,para02,para10,para11,para12,para20,para21;\r
+ para00 = cpara_array[0*3+0][0];//para[i][0] = c->m[i*3+0];\r
+ para01 = cpara_array[0*3+1][0];//para[i][1] = c->m[i*3+1];\r
+ para02 = cpara_array[0*3+2][0];//para[i][2] = c->m[i*3+2];\r
+ para10 = cpara_array[1*3+0][0];//para[i][0] = c->m[i*3+0];\r
+ para11 = cpara_array[1*3+1][0];//para[i][1] = c->m[i*3+1];\r
+ para12 = cpara_array[1*3+2][0];//para[i][2] = c->m[i*3+2];\r
+ para20 = cpara_array[2*3+0][0];//para[2][0] = c->m[2*3+0];\r
+ para21 = cpara_array[2*3+1][0];//para[2][1] = c->m[2*3+1];\r
+\r
+ \r
+ double d,yw;\r
+ int xc, yc;\r
+ int i,j;\r
+ // arGetCode_put_zero(ext_pat2);//put_zero( (ARUint8 *)ext_pat2, AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3*sizeof(ARUint32) );\r
+ int xdiv = i_xdiv2/L_WIDTH;//xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
+ int ydiv = i_ydiv2/L_HEIGHT;//ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+ \r
+ //計算バッファを予約する\r
+ this.reservWorkBuffers(i_xdiv2); \r
+ double[] para00_xw=this.wk_updateExtpat_para00_xw;\r
+ double[] para10_xw=this.wk_updateExtpat_para10_xw;\r
+ double[] para20_xw=this.wk_updateExtpat_para20_xw;\r
+ int[] x_rgb_index=this.wk_updateExtpat_x_rgb_index;\r
+ int[] y_rgb_index=this.wk_updateExtpat_y_rgb_index;\r
+ int[] i_rgb_index=this.wk_updateExtpat_i_rgb_index;\r
+ int[] rgb_buf=this.wk_updateExtpat_rgb_buf;\r
+ double xw;\r
+ for(i=0;i<i_xdiv2;i++){\r
+ xw= 102.5 + 5.0 * ((double)i+0.5) /i_xdiv2;\r
+ para20_xw[i]=para20*xw;\r
+ para00_xw[i]=para00*xw;\r
+ para10_xw[i]=para10*xw;\r
+ }\r
+\r
+ int index_num;\r
+\r
+ \r
+ for(j = 0; j < i_ydiv2; j++ ) {\r
+ yw = 102.5 + 5.0 * ((double)j+0.5) /i_ydiv2;\r
+ para21_x_yw=para21*yw+1.0;\r
+ para11_x_yw=para11*yw+para12;\r
+ para01_x_yw=para01*yw+para02;\r
+ extpat_j=L_extpat[j/ydiv];\r
+ index_num=0;\r
+ //ステップ1.RGB取得用のマップを作成\r
+ for(i = 0; i < i_xdiv2; i++ ) {\r
+ d = para20_xw[i] + para21_x_yw;\r
+ if( d == 0 ){\r
+ throw new NyARException();\r
+ }\r
+ xc = (int)((para00_xw[i] + para01_x_yw)/d);\r
+ yc = (int)((para10_xw[i] + para11_x_yw)/d);\r
+ //範囲外は無視\r
+ if(xc<0 || xc >=img_x || yc<0 || yc >=img_y){\r
+ continue;\r
+ }\r
+// ピクセル値の計算\r
+// image.getPixel(xc,yc,rgb_buf);\r
+// ext_pat2_j_i=ext_pat2_j[i/xdiv];\r
+// ext_pat2_j_i[0] += rgb_buf[0];//R\r
+// ext_pat2_j_i[1] += rgb_buf[1];//G\r
+// ext_pat2_j_i[2] += rgb_buf[2];//B\r
+\r
+ x_rgb_index[index_num]=xc;\r
+ y_rgb_index[index_num]=yc;\r
+ i_rgb_index[index_num]=i/xdiv;\r
+ index_num++;\r
+ }\r
+// //ステップ2.ピクセル配列を取得\r
+ image.getPixelSet(x_rgb_index,y_rgb_index,index_num,rgb_buf);\r
+// //ピクセル値の計算\r
+ for(i=index_num-1;i>=0;i--){\r
+ extpat_j_i=extpat_j[i_rgb_index[i]];\r
+ extpat_j_i[0] += rgb_buf[i*3+0];//R\r
+ extpat_j_i[1] += rgb_buf[i*3+1];//G\r
+ extpat_j_i[2] += rgb_buf[i*3+2];//B\r
+ }\r
+ }\r
+ /*<Optimize>*/\r
+ int xdiv_x_ydiv=xdiv*ydiv;\r
+ for(j =L_HEIGHT-1; j>=0; j--){\r
+ extpat_j=L_extpat[j];\r
+ for(i = L_WIDTH-1; i>=0; i--){ // PRL 2006-06-08.\r
+ extpat_j_i=extpat_j[i];\r
+ extpat_j_i[0]/=(xdiv_x_ydiv);//ext_pat[j][i][0] = (byte)(ext_pat2[j][i][0] / (xdiv*ydiv));\r
+ extpat_j_i[1]/=(xdiv_x_ydiv);//ext_pat[j][i][1] = (byte)(ext_pat2[j][i][1] / (xdiv*ydiv));\r
+ extpat_j_i[2]/=(xdiv_x_ydiv);//ext_pat[j][i][2] = (byte)(ext_pat2[j][i][2] / (xdiv*ydiv));\r
+ }\r
+ }\r
+ return; \r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+\r
+/**\r
+ * イメージからマーカー情報を検出するクラス。\r
+ * このクラスは、arDetectMarker2.cとの置き換えになります。\r
+ * ラベリング済みのラスタデータからマーカー位置を検出して、結果を保持します。\r
+ *\r
+ */\r
+public class NyARDetectMarker {\r
+ private static final int AR_AREA_MAX=100000;//#define AR_AREA_MAX 100000\r
+ private static final int AR_AREA_MIN=70;//#define AR_AREA_MIN 70\r
+\r
+// private final NyARMarker[] marker_holder; //マーカーデータの保持配列\r
+// private final NyARMarker[] marker_info2_array;//マーカーデータのインデックス配列\r
+// private int marker_num;\r
+ private int width,height;\r
+ /**\r
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+ * @param i_width\r
+ * @param i_height\r
+ */\r
+ public NyARDetectMarker(int i_width,int i_height)\r
+ {\r
+ this.width =i_width;\r
+ this.height=i_height;\r
+ \r
+// this.marker_holder=new NyARMarker[i_squre_max];\r
+// this.marker_info2_array=new NyARMarker[i_squre_max];\r
+// //先にマーカーホルダにオブジェクトを作っておく\r
+// for(int i=0;i<i_squre_max;i++){\r
+// this.marker_holder[i]=new NyARMarker();\r
+// }\r
+ }\r
+ private static final int AR_CHAIN_MAX=10000;\r
+ private final int[] wk_arGetContour_xdir={0, 1, 1, 1, 0,-1,-1,-1};\r
+ private final int[] wk_arGetContour_ydir={-1,-1, 0, 1, 1, 1, 0,-1};\r
+ private final int[] wk_arGetContour_xcoord=new int[AR_CHAIN_MAX];\r
+ private final int[] wk_arGetContour_ycoord=new int[AR_CHAIN_MAX];\r
+ /**\r
+ * int arGetContour( ARInt16 *limage, int *label_ref,int label, int clip[4], ARMarkerInfo2 *marker_info2 )\r
+ * 関数の代替品\r
+ * detectMarker関数から使う関数です。o_markerにlabelとclipで示される1個のマーカーを格納します。\r
+ * marker_holder[i_holder_num]にオブジェクトが無ければまず新規に作成し、もし\r
+ * 既に存在すればそこにマーカー情報を上書きして記録します。\r
+ * Optimize:STEP[369->336]\r
+ * @param o_marker\r
+ * @param limage\r
+ * @param label_ref\r
+ * @param label\r
+ * @param clip\r
+ * @throws NyARException\r
+ */\r
+ private final void arGetContour(NyARMarker o_marker,int[][] limage, int[] label_ref,int i_labelnum, NyARLabel i_label) throws NyARException\r
+ {\r
+ final int[] xcoord=wk_arGetContour_xcoord;\r
+ final int[] ycoord=wk_arGetContour_ycoord;\r
+ final int[] xdir=wk_arGetContour_xdir; //static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};\r
+ final int[] ydir=wk_arGetContour_ydir;//static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};\r
+ //ShortPointer p1;//ARInt16 *p1;\r
+ int coord_num;\r
+ int sx=0, sy=0, dir;\r
+ int dmax, d, v1=0;\r
+ int i, j,w;\r
+\r
+ int[] limage_j;\r
+ j = i_label.clip2;\r
+ limage_j=limage[j];\r
+ final int clip1=i_label.clip1;\r
+ //p1=ShortPointer.wrap(limage,j*xsize+clip.get());//p1 = &(limage[j*xsize+clip[0]]);\r
+ for( i = i_label.clip0; i <= clip1; i++){//for( i = clip[0]; i <= clip[1]; i++, p1++ ) {\r
+ w=limage_j[i];\r
+ if(w > 0 && label_ref[w-1] == i_labelnum ) {//if( *p1 > 0 && label_ref[(*p1)-1] == label ) {\r
+ sx = i;\r
+ sy = j;\r
+ break;\r
+ }\r
+ }\r
+ if(i>clip1){//if( i > clip[1] ) {\r
+ System.out.println("??? 1");//printf();\r
+ throw new NyARException();//return(-1);\r
+ }\r
+\r
+// //マーカーホルダが既に確保済みかを調べる\r
+// if(marker_holder[i_holder_num]==null){\r
+// //確保していなければ確保\r
+// marker_holder[i_holder_num]=new NyARMarker();\r
+// }\r
+\r
+\r
+ coord_num=1;//marker_info2->coord_num = 1;\r
+ xcoord[0]=sx;//marker_info2->x_coord[0] = sx;\r
+ ycoord[0]=sy;//marker_info2->y_coord[0] = sy;\r
+ dir = 5;\r
+ \r
+ int r,c;\r
+ c=xcoord[0];\r
+ r=ycoord[0];\r
+ dmax=0;\r
+ //本家はdmaxの作成とxcoordの作成を別のループでやってるけど、非効率なので統合\r
+ for(;;){\r
+ //xcoord[1]-xcoord[n]までのデータを作る。\r
+ \r
+// 1個前のxcoordとycoordはループ後半で格納される。\r
+// c=xcoord[coord_num-1];\r
+// r=ycoord[coord_num-1];\r
+ //p1 = &(limage[marker_info2->y_coord[marker_info2->coord_num-1] * xsize+ marker_info2->x_coord[marker_info2->coord_num-1]]);\r
+ dir = (dir+5)%8;\r
+ for(i=0;i<8;i++) {\r
+ if(limage[r+ydir[dir]][c+xdir[dir]]>0){//if( p1[ydir[dir]*xsize+xdir[dir]] > 0 ){\r
+ break;\r
+ }\r
+ dir = (dir+1)%8; \r
+ }\r
+ if( i == 8 ){\r
+ System.out.println("??? 2");//printf("??? 2\n");\r
+ throw new NyARException();//return(-1);\r
+ }\r
+// xcoordとycoordをc,rにも保存\r
+ c= c + xdir[dir];//marker_info2->x_coord[marker_info2->coord_num]= marker_info2->x_coord[marker_info2->coord_num-1] + xdir[dir];\r
+ r= r + ydir[dir];//marker_info2->y_coord[marker_info2->coord_num]= marker_info2->y_coord[marker_info2->coord_num-1] + ydir[dir];\r
+ xcoord[coord_num]=c;//marker_info2->x_coord[marker_info2->coord_num]= marker_info2->x_coord[marker_info2->coord_num-1] + xdir[dir];\r
+ ycoord[coord_num]=r;//marker_info2->y_coord[marker_info2->coord_num]= marker_info2->y_coord[marker_info2->coord_num-1] + ydir[dir];\r
+ if(c == sx && r == sy ){\r
+ break;\r
+ }\r
+ //dmaxの計算\r
+ d=(c-sx)*(c-sx)+(r-sy)*(r-sy);\r
+ if( d > dmax ) {\r
+ dmax = d;\r
+ v1 = coord_num;\r
+ }\r
+ //終了条件判定\r
+ coord_num++;\r
+ if(coord_num == AR_CHAIN_MAX-1){//if( marker_info2.coord_num == Config.AR_CHAIN_MAX-1 ){\r
+ System.out.println("??? 3");//printf("??? 3\n");\r
+ throw new NyARException();//return(-1);\r
+ }\r
+ }\r
+//\r
+// dmax = 0;\r
+// for(i=1;i<coord_num;i++) {// for(i=1;i<marker_info2->coord_num;i++) {\r
+// d = (xcoord[i]-sx)*(xcoord[i]-sx)+ (ycoord[i]-sy)*(ycoord[i]-sy);// d = (marker_info2->x_coord[i]-sx)*(marker_info2->x_coord[i]-sx)+ (marker_info2->y_coord[i]-sy)*(marker_info2->y_coord[i]-sy);\r
+// if( d > dmax ) {\r
+// dmax = d;\r
+// v1 = i;\r
+// }\r
+// }\r
+ //NyARMarkerへcoord情報をセット\r
+ //coordの並び替えと保存はNyARMarkerへ移動\r
+ o_marker.setCoordXY(v1,coord_num,xcoord,ycoord);\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double factor, int *marker_num )\r
+ * 関数の代替品\r
+ * ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。\r
+ * 関数はo_marker_listに重なりを除外したマーカーリストを作成します。\r
+ * \r
+ * @param i_labeling\r
+ * ラベリング済みの情報を持つラベリングオブジェクト\r
+ * @param i_factor\r
+ * 何かの閾値?\r
+ * @param o_marker_list\r
+ * 抽出したマーカーを格納するリスト\r
+ * @throws NyARException\r
+ */\r
+ public final void detectMarker(NyARLabeling i_labeling,double i_factor,NyARMarkerList o_marker_list) throws NyARException\r
+ {\r
+ int label_area;\r
+ int i;\r
+ int xsize, ysize;\r
+ NyARLabel[] labels=i_labeling.getLabel();\r
+// int[] warea =i_labeling.getArea();\r
+ int label_num =i_labeling.getLabelNum();\r
+// int[][] wclip =i_labeling.getClip();\r
+// double[] wpos =i_labeling.getPos();\r
+ int[][] limage=i_labeling.getLabelImg();\r
+ int[] label_ref =i_labeling.getLabelRef();\r
+\r
+ //マーカーホルダをリセット\r
+ o_marker_list.reset();\r
+// marker_num=0;\r
+ xsize =width;\r
+ ysize =height;\r
+// マーカーをmarker_holderに蓄積する。\r
+ NyARMarker current_marker=o_marker_list.getCurrentHolder();\r
+ NyARLabel label_pt;\r
+ for(i=0; i<label_num; i++ ){\r
+ label_pt=labels[i];\r
+ label_area=label_pt.area;\r
+ if(label_area < AR_AREA_MIN || label_area > AR_AREA_MAX ){\r
+ continue;\r
+ }\r
+ if( label_pt.clip0 == 1 || label_pt.clip1 == xsize-2 ){//if( wclip[i*4+0] == 1 || wclip[i*4+1] == xsize-2 ){\r
+ continue;\r
+ }\r
+ if( label_pt.clip2 == 1 || label_pt.clip3 == ysize-2 ){//if( wclip[i*4+2] == 1 || wclip[i*4+3] == ysize-2 ){\r
+ continue;\r
+ }\r
+ //ret = arGetContour( limage, label_ref, i+1,&(wclip[i*4]), &(marker_info2[marker_num2]));\r
+ arGetContour(current_marker,limage, label_ref, i+1,label_pt);\r
+\r
+ if(!current_marker.checkSquare(label_area,i_factor,label_pt.pos_x,label_pt.pos_y)){\r
+ //後半で整理するからここはいらない。// marker_holder[marker_num2]=null;\r
+ continue;\r
+ }\r
+// この3行はcheckSquareの最終段に含める。\r
+// marker_holder[marker_num2].area = warea[i];\r
+// marker_holder[marker_num2].pos[0] = wpos[i*2+0];\r
+// marker_holder[marker_num2].pos[1] = wpos[i*2+1];\r
+ //マーカー検出→次のホルダを取得\r
+ current_marker=o_marker_list.getNextHolder();\r
+ //マーカーリストが上限に達したか確認\r
+ if(current_marker==null){\r
+ break;\r
+ }\r
+ }\r
+ //マーカーリストを整理(重なり処理とかはマーカーリストに責務押し付け)\r
+ o_marker_list.updateMarkerArray();\r
+// 重なり処理かな?\r
+// double[] pos_j,pos_i;\r
+// for(i=0; i < marker_num2; i++ ){\r
+// pos_i=marker_holder[i].pos;\r
+// for(j=i+1; j < marker_num2; j++ ) {\r
+// pos_j=marker_holder[j].pos;\r
+// d = (pos_i[0] - pos_j[0])*(pos_i[0] - pos_j[0])+\r
+// (pos_i[1] - pos_j[1])*(pos_i[1] - pos_j[1]);\r
+// if(marker_holder[i].area >marker_holder[j].area ) {\r
+// if( d <marker_holder[i].area / 4 ) {\r
+// marker_holder[j].area = 0;\r
+// }\r
+// }else{\r
+// if( d < marker_holder[j].area / 4 ) {\r
+// marker_holder[i].area = 0;\r
+// }\r
+// }\r
+// }\r
+// }\r
+// みつかったマーカーを整理する。\r
+// エリアが0のマーカーを外した配列を作って、その数もついでに計算\r
+// for(i=0;i<marker_num2;i++){\r
+// if(marker_holder[i].area==0.0){\r
+// continue;\r
+// }\r
+// marker_info2_array[marker_num]=marker_holder[i];\r
+// marker_num++;\r
+// } \r
+// for( i=0; i < marker_num2; i++ ) {\r
+// if( marker_info2_array[i].area == 0.0 ) {\r
+// for( j=i+1; j < marker_num2; j++ ){\r
+// marker_info2_array[j-1] = marker_info2_array[j];\r
+// }\r
+// marker_num2--;\r
+// }\r
+// }\r
+// 発見したマーカー数をセット\r
+// marker_num=marker_num2;//*marker_num = marker_num2;\r
+// return( &(marker_info2[0]) );\r
+ return;\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+\r
+\r
+public class NyARDetectSquare\r
+{\r
+ private final NyARLabeling labeling;\r
+ private final NyARDetectMarker detect;\r
+ private NyARParam param;\r
+\r
+ /**\r
+ * マーカー抽出インスタンスを作ります。\r
+ * @param i_param\r
+ */\r
+ public NyARDetectSquare(NyARParam i_param)\r
+ {\r
+ param=i_param;\r
+ //解析オブジェクトを作る\r
+ int width=i_param.getX();\r
+ int height=i_param.getY();\r
+\r
+ labeling=new NyARLabeling_O2(width,height);\r
+ detect=new NyARDetectMarker(width,height);\r
+ }\r
+ /**\r
+ * ラスタイメージから矩形を検出して、結果o_square_holderへ格納します。\r
+ * @param i_marker\r
+ * @param i_number_of_marker\r
+ * @param i_square_holder\r
+ * @throws NyARException\r
+ */\r
+ public void detectSquare(NyARRaster i_image,int i_thresh,NyARSquareList o_square_holder) throws NyARException\r
+ {\r
+// number_of_square=0;\r
+ \r
+ labeling.labeling(i_image, i_thresh);\r
+ if(labeling.getLabelNum()<1){\r
+ return;\r
+ }\r
+ //ここでマーカー配列を作成する。\r
+ detect.detectMarker(labeling,1.0,o_square_holder);\r
+ \r
+ //マーカー情報をフィルタして、スクエア配列を更新する。\r
+ o_square_holder.updateSquareArray(param);\r
+\r
+// NyARSquare square;\r
+// int j=0;\r
+// for (int i = 0; i <number_of_marker; i++){\r
+// double[][] line =new double[4][3];\r
+// double[][] vertex =new double[4][2];\r
+// //NyARMarker marker=detect.getMarker(i);\r
+// square=square_holder.getSquare(i);\r
+// //・・・線の検出??\r
+// if (!square.getLine(param))\r
+// {\r
+// continue;\r
+// }\r
+// ここで計算するのは良くないと思うんだ \r
+// marker_infoL[j].id = id.get();\r
+// marker_infoL[j].dir = dir.get();\r
+// marker_infoL[j].cf = cf.get(); \r
+// j++;\r
+// //配列数こえたらドゴォォォンしないようにループを抜ける\r
+// if(j>=marker_info.length){\r
+// break;\r
+// }\r
+// }\r
+// number_of_square=j;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+\r
+interface NyARLabeling{\r
+ /**\r
+ * 検出したラベルの数を返す\r
+ * @return\r
+ */\r
+ public int getLabelNum();\r
+ /**\r
+ * \r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int[] getLabelRef() throws NyARException;\r
+ /**\r
+ * 検出したラベル配列\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public NyARLabel[] getLabel() throws NyARException;\r
+ /**\r
+ * ラベリング済みイメージを返す\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int[][] getLabelImg() throws NyARException;\r
+ /**\r
+ * static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR )\r
+ * 関数の代替品\r
+ * ラスタimageをラベリングして、結果を保存します。\r
+ * Optimize:STEP[1514->1493]\r
+ * @param image\r
+ * @param thresh\r
+ * @throws NyARException\r
+ */\r
+ public void labeling(NyARRaster image,int thresh) throws NyARException;\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * NyARLabeling_O2のworkとwork2を可変長にするためのクラス\r
+ * \r
+ *\r
+ */\r
+class NyARWorkHolder\r
+{\r
+ private final static int ARRAY_APPEND_STEP=256;\r
+ public final int[] work;\r
+ public final int[][] work2;\r
+ private int allocate_size;\r
+ /**\r
+ * 最大i_holder_size個の動的割り当てバッファを準備する。\r
+ * @param i_holder_size\r
+ */\r
+ public NyARWorkHolder(int i_holder_size)\r
+ {\r
+ //ポインタだけははじめに確保しておく\r
+ this.work=new int[i_holder_size];\r
+ this.work2=new int[i_holder_size][];\r
+ this.allocate_size=0;\r
+ }\r
+ /**\r
+ * i_indexで指定した番号までのバッファを準備する。\r
+ * @param i_index\r
+ */\r
+ public final void reserv(int i_index) throws NyARException\r
+ {\r
+ //アロケート済みなら即リターン\r
+ if(this.allocate_size>i_index){\r
+ return;\r
+ }\r
+ //要求されたインデクスは範囲外\r
+ if(i_index>=this.work.length){\r
+ throw new NyARException();\r
+ } \r
+ //追加アロケート範囲を計算\r
+ int range=i_index+ARRAY_APPEND_STEP;\r
+ if(range>=this.work.length){\r
+ range=this.work.length;\r
+ }\r
+ //アロケート\r
+ for(int i=this.allocate_size;i<range;i++)\r
+ {\r
+ this.work2[i]=new int[7];\r
+ }\r
+ this.allocate_size=range;\r
+ }\r
+}\r
+\r
+class NyARLabel\r
+{\r
+ public int area;\r
+ public int clip0;\r
+ public int clip1;\r
+ public int clip2;\r
+ public int clip3;\r
+ public double pos_x;\r
+ public double pos_y;\r
+}\r
+\r
+\r
+class NyARLabelHolder\r
+{\r
+ private final static int ARRAY_APPEND_STEP=128;\r
+ public final NyARLabel[] labels;\r
+ private int allocate_size;\r
+ /**\r
+ * 最大i_holder_size個の動的割り当てバッファを準備する。\r
+ * @param i_holder_size\r
+ */\r
+ public NyARLabelHolder(int i_holder_size)\r
+ {\r
+ //ポインタだけははじめに確保しておく\r
+ this.labels=new NyARLabel[i_holder_size];\r
+ this.allocate_size=0;\r
+ }\r
+ /**\r
+ * i_indexで指定した番号までのバッファを準備する。\r
+ * @param i_index\r
+ */\r
+ private final void reserv(int i_index) throws NyARException\r
+ {\r
+ //アロケート済みなら即リターン\r
+ if(this.allocate_size>i_index){\r
+ return;\r
+ }\r
+ //要求されたインデクスは範囲外\r
+ if(i_index>=this.labels.length){\r
+ throw new NyARException();\r
+ } \r
+ //追加アロケート範囲を計算\r
+ int range=i_index+ARRAY_APPEND_STEP;\r
+ if(range>=this.labels.length){\r
+ range=this.labels.length;\r
+ }\r
+ //アロケート\r
+ for(int i=this.allocate_size;i<range;i++)\r
+ {\r
+ this.labels[i]=new NyARLabel();\r
+ }\r
+ this.allocate_size=range;\r
+ }\r
+ /**\r
+ * i_reserv_sizeまでのバッファを、初期条件i_lxsizeとi_lysizeで初期化する。\r
+ * @param i_reserv_size\r
+ * @param i_lxsize\r
+ * @param i_lysize\r
+ * @throws NyARException\r
+ */\r
+ public final void init(int i_reserv_size,int i_lxsize,int i_lysize) throws NyARException\r
+ {\r
+ reserv(i_reserv_size);\r
+ NyARLabel l;\r
+ for(int i=0;i<i_reserv_size;i++){\r
+ l=this.labels[i];\r
+ l.area=0;\r
+ l.pos_x=0;\r
+ l.pos_y=0;\r
+ l.clip0= i_lxsize;//wclip[i*4+0] = lxsize;\r
+ l.clip1= 0;//wclip[i*4+0] = lxsize;\r
+ l.clip2= i_lysize;//wclip[i*4+2] = lysize;\r
+ l.clip3= 0;//wclip[i*4+3] = 0;\r
+ } \r
+ }\r
+}\r
+\r
+\r
+/**\r
+ * ラベリングクラス。NyARRasterをラベリングして、結果値を保持します。\r
+ * 構造を維持して最適化をしたバージョン\r
+ *\r
+ */\r
+class NyARLabeling_O2 implements NyARLabeling\r
+{\r
+ private static final int WORK_SIZE=1024*32;//#define WORK_SIZE 1024*32\r
+ private final int[][] glabel_img;//static ARInt16 l_imageL[HARDCODED_BUFFER_WIDTH*HARDCODED_BUFFER_HEIGHT];\r
+\r
+ private final NyARWorkHolder work_holder=new NyARWorkHolder(WORK_SIZE);\r
+ private final NyARLabelHolder label_holder=new NyARLabelHolder(WORK_SIZE);\r
+\r
+ private int label_num;\r
+ //\r
+ private final int width;\r
+ private final int height;\r
+ /**\r
+ * @param i_width\r
+ * ラベリング画像の幅。解析するラスタの幅より大きいこと。\r
+ * @param i_height\r
+ * ラベリング画像の高さ。解析するラスタの高さより大きいこと。\r
+ */\r
+ public NyARLabeling_O2(int i_width,int i_height)\r
+ {\r
+ width =i_width;\r
+ height=i_height;\r
+ glabel_img=new int[height][width];\r
+ this.wk_reservLineBuffer_buf=new int[width];\r
+ label_num=0;\r
+\r
+\r
+ //ワークイメージに枠を書く\r
+ int[][] label_img=this.glabel_img;\r
+ for(int i = 0; i < i_width; i++){\r
+ label_img[0][i]=0;\r
+ label_img[i_height-1][i]=0;\r
+ }\r
+ //</Optimize>\r
+ for(int i = 0; i < i_height; i++) {\r
+ label_img[i][0]=0;\r
+ label_img[i][i_width-1]=0; \r
+ }\r
+ \r
+ \r
+ \r
+ \r
+ }\r
+ /**\r
+ * 検出したラベルの数を返す\r
+ * @return\r
+ */\r
+ public int getLabelNum()\r
+ {\r
+ return label_num;\r
+ }\r
+ /**\r
+ * 検出したエリア配列?\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public NyARLabel[] getLabel() throws NyARException\r
+ {\r
+ if(label_num<1){\r
+ throw new NyARException();\r
+ }\r
+ return this.label_holder.labels;\r
+ } \r
+ /**\r
+ * \r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int[] getLabelRef() throws NyARException\r
+ {\r
+ if(label_num<1){\r
+ throw new NyARException();\r
+ }\r
+ return work_holder.work;\r
+ }\r
+ /**\r
+ * ラベリング済みイメージを返す\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int[][] getLabelImg() throws NyARException\r
+ {\r
+ return glabel_img;\r
+ }\r
+ //コンストラクタで作ること\r
+ private int[] wk_reservLineBuffer_buf=null;\r
+\r
+ /**\r
+ * static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR )\r
+ * 関数の代替品\r
+ * ラスタimageをラベリングして、結果を保存します。\r
+ * Optimize:STEP[1514->1493]\r
+ * @param image\r
+ * @param thresh\r
+ * @throws NyARException\r
+ */\r
+ public void labeling(NyARRaster image,int thresh) throws NyARException\r
+ {\r
+ int wk_max; /* work */\r
+ int m,n; /* work */\r
+ int lxsize, lysize;\r
+ int thresht3 = thresh * 3;\r
+ int i,j,k;\r
+ lxsize=image.getWidth();//lxsize = arUtil_c.arImXsize;\r
+ lysize=image.getHeight();//lysize = arUtil_c.arImYsize;\r
+ //画素数の一致チェック\r
+ if(lxsize!=this.width || lysize!=this.height){\r
+ throw new NyARException();\r
+ } \r
+ //ラベル数を0に初期化\r
+ this.label_num=0;\r
+\r
+\r
+\r
+ int[][] label_img=this.glabel_img;\r
+ \r
+\r
+ //枠作成はインスタンスを作った直後にやってしまう。\r
+ \r
+ int[] work2_pt;\r
+ wk_max = 0;\r
+\r
+ int label_pixel;\r
+ \r
+ int[] work=this.work_holder.work;\r
+ int[][] work2=this.work_holder.work2;\r
+ int[] line_bufferr=this.wk_reservLineBuffer_buf;\r
+ \r
+ int[] label_img_pt0,label_img_pt1;\r
+ for(j = 1; j < lysize - 1; j++) {//for (int j = 1; j < lysize - 1; j++, pnt += poff*2, pnt2 += 2) {\r
+ label_img_pt0=label_img[j];\r
+ label_img_pt1=label_img[j-1];\r
+ image.getPixelTotalRowLine(j,line_bufferr);\r
+\r
+ for(i = 1; i < lxsize-1; i++) {//for(int i = 1; i < lxsize-1; i++, pnt+=poff, pnt2++) {\r
+ //RGBの合計値が閾値より大きいかな?\r
+ if(line_bufferr[i]<=thresht3){\r
+ //pnt1 = ShortPointer.wrap(pnt2, -lxsize);//pnt1 = &(pnt2[-lxsize]);\r
+ if(label_img_pt1[i]>0){//if( *pnt1 > 0 ) {\r
+ label_pixel=label_img_pt1[i];//*pnt2 = *pnt1;\r
+\r
+\r
+ work2_pt=work2[label_pixel-1];\r
+ work2_pt[0]++;//work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1]+=i;//work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2]+=j;//work2[((*pnt2)-1)*7+2] += j;\r
+ work2_pt[6]=j;//work2[((*pnt2)-1)*7+6] = j;\r
+ }else if(label_img_pt1[i+1]> 0 ) {//}else if( *(pnt1+1) > 0 ) {\r
+ if(label_img_pt1[i-1] > 0 ) {//if( *(pnt1-1) > 0 ) {\r
+ m = work[label_img_pt1[i+1]-1];//m = work[*(pnt1+1)-1];\r
+ n = work[label_img_pt1[i-1]-1];//n = work[*(pnt1-1)-1];\r
+ if( m > n ){\r
+ label_pixel=n;//*pnt2 = n;\r
+ //wk=IntPointer.wrap(work, 0);//wk = &(work[0]);\r
+ for(k = 0; k < wk_max; k++) {\r
+ if(work[k] == m ){//if( *wk == m ) \r
+ work[k]=n;//*wk = n;\r
+ }\r
+ }\r
+ }else if( m < n ) {\r
+ label_pixel=m;//*pnt2 = m;\r
+ //wk=IntPointer.wrap(work,0);//wk = &(work[0]);\r
+ for(k = 0; k < wk_max; k++){\r
+ if(work[k]==n){//if( *wk == n ){\r
+ work[k]=m;//*wk = m;\r
+ }\r
+ }\r
+ }else{\r
+ label_pixel=m;//*pnt2 = m;\r
+ }\r
+ work2_pt=work2[label_pixel-1];\r
+ work2_pt[0] ++;\r
+ work2_pt[1] += i;\r
+ work2_pt[2] += j;\r
+ work2_pt[6] = j;\r
+ }else if( (label_img_pt0[i-1]) > 0 ) {//}else if( *(pnt2-1) > 0 ) {\r
+ m = work[(label_img_pt1[i+1])-1];//m = work[*(pnt1+1)-1];\r
+ n = work[label_img_pt0[i-1]-1];//n = work[*(pnt2-1)-1];\r
+ if( m > n ) {\r
+\r
+ label_pixel=n;//*pnt2 = n;\r
+ for(k = 0; k < wk_max; k++) {\r
+ if(work[k]==m){//if( *wk == m ){\r
+ work[k]=n;//*wk = n;\r
+ }\r
+ }\r
+ }else if( m < n ) {\r
+ label_pixel=m;//*pnt2 = m;\r
+ for(k = 0; k < wk_max; k++) {\r
+ if(work[k]==n){//if( *wk == n ){\r
+ work[k]=m;//*wk = m;\r
+ }\r
+ }\r
+ }else{\r
+ label_pixel=m;//*pnt2 = m;\r
+ }\r
+ work2_pt=work2[label_pixel-1];\r
+ work2_pt[0] ++;//work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1] += i;//work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2] += j;//work2[((*pnt2)-1)*7+2] += j;\r
+ }else{\r
+\r
+ label_pixel=label_img_pt1[i+1];//*pnt2 = *(pnt1+1);\r
+\r
+ work2_pt=work2[label_pixel-1];\r
+ work2_pt[0] ++;//work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1] += i;//work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2] += j;//work2[((*pnt2)-1)*7+2] += j;\r
+ if( work2_pt[3] > i ){//if( work2[((*pnt2)-1)*7+3] > i ){ \r
+ work2_pt[3] = i;// work2[((*pnt2)-1)*7+3] = i;\r
+ }\r
+ work2_pt[6] = j;//work2[((*pnt2)-1)*7+6] = j;\r
+ }\r
+ }else if( (label_img_pt1[i-1]) > 0 ) {//}else if( *(pnt1-1) > 0 ) {\r
+ label_pixel=label_img_pt1[i-1];//*pnt2 = *(pnt1-1);\r
+\r
+ work2_pt=work2[label_pixel-1];\r
+ work2_pt[0] ++;//work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1] += i;//work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2] += j;//work2[((*pnt2)-1)*7+2] += j;\r
+ if( work2_pt[4] < i ){//if( work2[((*pnt2)-1)*7+4] < i ){\r
+ work2_pt[4] = i;// work2[((*pnt2)-1)*7+4] = i;\r
+ }\r
+ work2_pt[6] = j;//work2[((*pnt2)-1)*7+6] = j;\r
+ }else if(label_img_pt0[i-1] > 0) {//}else if( *(pnt2-1) > 0) {\r
+ label_pixel=label_img_pt0[i-1];//*pnt2 = *(pnt2-1);\r
+\r
+ work2_pt=work2[label_pixel-1];\r
+ work2_pt[0] ++;//work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1] += i;//work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2] += j;//work2[((*pnt2)-1)*7+2] += j;\r
+ if(work2_pt[4] < i ){//if( work2[((*pnt2)-1)*7+4] < i ){\r
+ work2_pt[4] = i;// work2[((*pnt2)-1)*7+4] = i;\r
+ }\r
+ }else{\r
+ //現在地までの領域を予約\r
+ this.work_holder.reserv(wk_max);\r
+ wk_max++;\r
+ work[wk_max-1] = wk_max;\r
+ label_pixel=wk_max;//work[wk_max-1] = *pnt2 = wk_max;\r
+ work2_pt=work2[wk_max-1];\r
+ work2_pt[0] = 1;\r
+ work2_pt[1] = i;\r
+ work2_pt[2] = j;\r
+ work2_pt[3] = i;\r
+ work2_pt[4] = i;\r
+ work2_pt[5] = j;\r
+ work2_pt[6] = j;\r
+ }\r
+ label_img_pt0[i]=label_pixel;\r
+ }else {\r
+ label_img_pt0[i]=0;//*pnt2 = 0;\r
+ }\r
+ \r
+ }\r
+ }\r
+ j = 1;\r
+ for(i = 0; i < wk_max; i++){//for(int i = 1; i <= wk_max; i++, wk++) {\r
+ work[i]=(work[i]==i+1)? j++: work[work[i]-1];//*wk = (*wk==i)? j++: work[(*wk)-1];\r
+ }\r
+\r
+ int wlabel_num=j - 1;//*label_num = *wlabel_num = j - 1;\r
+\r
+ if(wlabel_num==0){//if( *label_num == 0 ) {\r
+ //発見数0\r
+ return;\r
+ }\r
+\r
+ \r
+ \r
+ //ラベルバッファを予約&初期化\r
+ this.label_holder.init(wlabel_num, lxsize, lysize);\r
+// \r
+// putZero(warea,wlabel_num);//put_zero( (ARUint8 *)warea, *label_num * sizeof(int) );\r
+// for(i=0;i<wlabel_num;i++){\r
+// wpos[i*2+0]=0;\r
+// wpos[i*2+1]=0;\r
+// }\r
+// for(i = 0; i < wlabel_num; i++) {//for(i = 0; i < *label_num; i++) {\r
+// wclip[i][0] = lxsize;//wclip[i*4+0] = lxsize;\r
+// wclip[i][1] = 0;//wclip[i*4+1] = 0;\r
+// wclip[i][2] = lysize;//wclip[i*4+2] = lysize;\r
+// wclip[i][3] = 0;//wclip[i*4+3] = 0;\r
+// }\r
+ NyARLabel label_pt;\r
+ NyARLabel[] labels=this.label_holder.labels;\r
+ \r
+ for(i = 0; i < wk_max; i++){\r
+ label_pt=labels[work[i] - 1];\r
+ work2_pt=work2[i];\r
+ label_pt.area += work2_pt[0];\r
+ label_pt.pos_x += work2_pt[1];\r
+ label_pt.pos_y += work2_pt[2];\r
+ if( label_pt.clip0 > work2_pt[3] ){\r
+ label_pt.clip0 = work2_pt[3];\r
+ }\r
+ if( label_pt.clip1 < work2_pt[4] ){\r
+ label_pt.clip1 = work2_pt[4];\r
+ }\r
+ if(label_pt.clip2 > work2_pt[5] ){\r
+ label_pt.clip2 = work2_pt[5];\r
+ }\r
+ if( label_pt.clip3 < work2_pt[6] ){\r
+ label_pt.clip3 = work2_pt[6];\r
+ }\r
+ }\r
+\r
+ for(i = 0; i < wlabel_num; i++ ) {//for(int i = 0; i < *label_num; i++ ) {\r
+ label_pt=labels[i];\r
+ label_pt.pos_x /= label_pt.area;\r
+ label_pt.pos_y /= label_pt.area;\r
+ }\r
+\r
+ label_num=wlabel_num;\r
+ return;\r
+ }\r
+}\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * typedef struct {\r
+ * int area;\r
+ * double pos[2];\r
+ * int coord_num;\r
+ * int x_coord[AR_CHAIN_MAX];\r
+ * int y_coord[AR_CHAIN_MAX];\r
+ * int vertex[5];\r
+ * } ARMarkerInfo2;\r
+ * \r
+ */\r
+class NyARMarker\r
+{\r
+ /**\r
+ * メモリブロックのサイズ(32*4=128kb)\r
+ */\r
+ private static final int ALLOCATE_PAGE_SIZE=256;\r
+ /**\r
+ * メモリブロックの初期サイズ\r
+ */\r
+ private static final int INITIAL_SIZE=1;\r
+ int[] x_coord=new int[INITIAL_SIZE];\r
+ int[] y_coord=new int[INITIAL_SIZE];\r
+ int coord_num;\r
+ int area;\r
+ final double[] pos=new double[2];\r
+ final int[] mkvertex=new int[5];\r
+ /**\r
+ * coordバッファをi_chain_num以上のサイズに再アロケートする。\r
+ * 内容の引継ぎは行われない。\r
+ * @param i_chain_num\r
+ */\r
+ private void reallocCoordArray(int i_chain_num)\r
+ {\r
+ if(x_coord.length<i_chain_num){\r
+ //ALLOCATE_PAGE_SIZE単位で確保する。\r
+ int new_size=((i_chain_num+ALLOCATE_PAGE_SIZE-1)/ALLOCATE_PAGE_SIZE)*ALLOCATE_PAGE_SIZE;\r
+ x_coord=new int[new_size];\r
+ y_coord=new int[new_size];\r
+ coord_num=0;\r
+ }\r
+ }\r
+ public void setCoordXY(int i_v1,int i_coord_num,int[] i_xcoord,int[] i_ycoord)\r
+ {\r
+ //メモリの割り当て保障\r
+ reallocCoordArray(i_coord_num+1);\r
+ //[A B C]を[B C A]に並べなおす。\r
+ System.arraycopy(i_xcoord,i_v1,x_coord,0,i_coord_num-i_v1);\r
+ System.arraycopy(i_xcoord,0,x_coord,i_coord_num-i_v1, i_v1);\r
+ x_coord[i_coord_num]=x_coord[0];\r
+ System.arraycopy(i_ycoord,i_v1,y_coord,0,i_coord_num-i_v1);\r
+ System.arraycopy(i_ycoord,0,y_coord,i_coord_num-i_v1, i_v1);\r
+ y_coord[i_coord_num]=y_coord[0];\r
+ coord_num=i_coord_num+1;\r
+ return;\r
+//arGetContour関数から取り外した部分 \r
+// int[] wx=new int[v1];//new int[Config.AR_CHAIN_MAX];\r
+// int[] wy=new int[v1]; //new int[Config.AR_CHAIN_MAX]; \r
+// for(i=0;i<v1;i++) {\r
+// wx[i] = marker_ref.x_coord[i];//wx[i] = marker_info2->x_coord[i];\r
+// wy[i] = marker_ref.y_coord[i];//wy[i] = marker_info2->y_coord[i];\r
+// }\r
+// for(i=0;i<marker_ref.coord_num-v1;i++) {//for(i=v1;i<marker_info2->coord_num;i++) {\r
+// marker_ref.x_coord[i] = marker_ref.x_coord[i+v1];//marker_info2->x_coord[i-v1] = marker_info2->x_coord[i];\r
+// marker_ref.y_coord[i] = marker_ref.y_coord[i+v1];//marker_info2->y_coord[i-v1] = marker_info2->y_coord[i];\r
+// }\r
+// for(i=0;i<v1;i++) {\r
+// marker_ref.x_coord[i-v1+marker_ref.coord_num] = wx[i];//marker_info2->x_coord[i-v1+marker_info2->coord_num] = wx[i];\r
+// marker_ref.y_coord[i-v1+marker_ref.coord_num] = wy[i];//marker_info2->y_coord[i-v1+marker_info2->coord_num] = wy[i];\r
+// }\r
+// marker_ref.x_coord[marker_ref.coord_num] = marker_ref.x_coord[0];//marker_info2->x_coord[marker_info2->coord_num] = marker_info2->x_coord[0];\r
+// marker_ref.y_coord[marker_ref.coord_num] = marker_ref.y_coord[0];//marker_info2->y_coord[marker_info2->coord_num] = marker_info2->y_coord[0];\r
+// marker_ref.coord_num++;//marker_info2->coord_num++;\r
+ }\r
+ private final NyARVertexCounter wk_checkSquare_wv1=new NyARVertexCounter();\r
+ private final NyARVertexCounter wk_checkSquare_wv2=new NyARVertexCounter();\r
+ /**\r
+ * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor )\r
+ * 関数の代替関数\r
+ * OPTIMIZED STEP [450->415]\r
+ * @param i_area\r
+ * @param i_factor\r
+ * @return\r
+ */\r
+ public boolean checkSquare(int i_area,double i_factor,double i_pos_x,double i_pos_y)\r
+ {\r
+ final int[] l_vertex=mkvertex;\r
+ final int[] l_x_coord=x_coord;\r
+ final int[] l_y_coord=y_coord;\r
+ final NyARVertexCounter wv1=wk_checkSquare_wv1;\r
+ final NyARVertexCounter wv2=wk_checkSquare_wv2;\r
+ int sx,sy;\r
+ int dmax,d,v1;\r
+ \r
+ int v2;// int wvnum1,wvnum2,v2;\r
+ int i;\r
+ \r
+ final int L_coord_num_m1=this.coord_num-1;\r
+ dmax = 0;\r
+ v1 = 0;\r
+ sx = l_x_coord[0];//sx = marker_info2->x_coord[0];\r
+ sy = l_y_coord[0];//sy = marker_info2->y_coord[0];\r
+ for(i=1;i<L_coord_num_m1;i++){//for(i=1;i<marker_info2->coord_num-1;i++) {\r
+ d = (l_x_coord[i]-sx)*(l_x_coord[i]-sx)+ (l_y_coord[i]-sy)*(l_y_coord[i]-sy);\r
+ if( d > dmax ) {\r
+ dmax = d;\r
+ v1 = i;\r
+ }\r
+ }\r
+\r
+ final double thresh = (i_area/0.75) * 0.01 * i_factor;\r
+\r
+ l_vertex[0] = 0;\r
+\r
+ if(!wv1.getVertex(l_x_coord,l_y_coord, 0, v1,thresh)){ //if( get_vertex(marker_info2->x_coord, marker_info2->y_coord, 0, v1,thresh, wv1, &wvnum1) < 0 ) {\r
+ return false;\r
+ }\r
+ if(!wv2.getVertex(l_x_coord,l_y_coord,v1,L_coord_num_m1, thresh)) {//if(get_vertex(marker_info2->x_coord, marker_info2->y_coord,v1, marker_info2->coord_num-1, thresh, wv2, &wvnum2) < 0 ) {\r
+ return false;\r
+ }\r
+\r
+ if(wv1.number_of_vertex==1 && wv2.number_of_vertex==1) {//if( wvnum1 == 1 && wvnum2 == 1 ) {\r
+ l_vertex[1] = wv1.vertex[0];\r
+ l_vertex[2] = v1;\r
+ l_vertex[3] = wv2.vertex[0];\r
+ }else if( wv1.number_of_vertex>1 && wv2.number_of_vertex==0 ) {//}else if( wvnum1 > 1 && wvnum2 == 0 ) {\r
+ v2 = v1 / 2;\r
+ if(!wv1.getVertex(l_x_coord,l_y_coord,0, v2, thresh)) {\r
+ return false;\r
+ }\r
+ if(!wv2.getVertex(l_x_coord,l_y_coord,v2, v1, thresh)) {\r
+ return false;\r
+ }\r
+ if(wv1.number_of_vertex==1 && wv2.number_of_vertex==1 ) {\r
+ l_vertex[1] = wv1.vertex[0];\r
+ l_vertex[2] = wv2.vertex[0];\r
+ l_vertex[3] = v1;\r
+ }else{\r
+ return false;\r
+ }\r
+ }else if(wv1.number_of_vertex==0 && wv2.number_of_vertex> 1 ) {\r
+ v2 = (v1 + this.coord_num-1) / 2;\r
+\r
+ if(!wv1.getVertex(l_x_coord,l_y_coord,v1, v2, thresh)) {\r
+ return false;\r
+ }\r
+ if(!wv2.getVertex(l_x_coord,l_y_coord,v2,L_coord_num_m1, thresh)) {\r
+ return false;\r
+ }\r
+ if( wv1.number_of_vertex==1 && wv2.number_of_vertex==1 ) {\r
+ l_vertex[1] = v1;\r
+ l_vertex[2] = wv1.vertex[0];\r
+ l_vertex[3] = wv2.vertex[0];\r
+ }\r
+ else {\r
+ return false;\r
+ }\r
+ }\r
+ else {\r
+ return false;\r
+ }\r
+ l_vertex[4] =L_coord_num_m1;//この値使ってるの?\r
+ //\r
+ area = i_area;\r
+ pos[0] = i_pos_x;\r
+ pos[1] = i_pos_y;\r
+// marker_holder[marker_num2].pos[1] = wpos[i*2+1]; \r
+ return true;\r
+ } \r
+}\r
+\r
+\r
+\r
+/**\r
+ * get_vertex関数を切り離すためのクラス\r
+ *\r
+ */\r
+final class NyARVertexCounter\r
+{\r
+ public final int[] vertex=new int[10];//5まで削れる\r
+ public int number_of_vertex;\r
+ private double thresh;\r
+ private int[] x_coord;\r
+ private int[] y_coord;\r
+\r
+ public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed,double i_thresh)\r
+ {\r
+ this.number_of_vertex=0;\r
+ this.thresh=i_thresh;\r
+ this.x_coord=i_x_coord;\r
+ this.y_coord=i_y_coord;\r
+ return get_vertex(st,ed);\r
+ }\r
+ /**\r
+ * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum)\r
+ * 関数の代替関数\r
+ * @param x_coord\r
+ * @param y_coord\r
+ * @param st\r
+ * @param ed\r
+ * @param thresh\r
+ * @return\r
+ */\r
+ private boolean get_vertex(int st, int ed)\r
+ {\r
+ double d, dmax;\r
+ double a, b, c;\r
+ int i, v1=0;\r
+ final int[] lx_coord=this.x_coord;\r
+ final int[] ly_coord=this.y_coord; \r
+ a = ly_coord[ed] - ly_coord[st];\r
+ b = lx_coord[st] - lx_coord[ed];\r
+ c = lx_coord[ed]*ly_coord[st] - ly_coord[ed]*lx_coord[st];\r
+ dmax = 0;\r
+ for(i=st+1;i<ed;i++) {\r
+ d = a*lx_coord[i] + b*ly_coord[i] + c;\r
+ if( d*d > dmax ) {\r
+ dmax = d*d;\r
+ v1 = i;\r
+ }\r
+ }\r
+ if( dmax/(a*a+b*b) > thresh ) {\r
+ if(!get_vertex(st, v1)){\r
+ return false;\r
+ }\r
+ if(number_of_vertex > 5 ){\r
+ return false;\r
+ }\r
+ vertex[number_of_vertex] = v1;//vertex[(*vnum)] = v1;\r
+ number_of_vertex++;//(*vnum)++;\r
+ \r
+ if(!get_vertex(v1, ed)){\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+}\r
+\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * このクラスは、detectMarkerがマーカーオブジェクトの蓄積に使うクラスです。\r
+ * 実体を伴うマーカーホルダと、これを参照するマーカーアレイを持ちます。\r
+ * \r
+ * マーカーアレイはマーカーホルダに存在するマーカーリストを特定の条件でフィルタした\r
+ * 結果を格納します。\r
+ * \r
+ * 一度作られたマーカーホルダは繰り返し使用されます。\r
+ * \r
+ *\r
+ */\r
+public class NyARMarkerList\r
+{\r
+ private int marker_holder_num;//marker_holderの使用中の数\r
+ protected int marker_array_num;//marker_arrayの有効な数\r
+ protected final NyARMarker[] marker_holder;//マーカーデータの保持配列\r
+ protected final NyARMarker[] marker_array; //マーカーデータのインデックス配列\r
+ /**\r
+ * 派生データ型をラップするときに使う\r
+ * @param i_holder\r
+ * 値の保持配列。全要素に実体を割り当てる必要がある。\r
+ */\r
+ protected NyARMarkerList(NyARMarker[] i_holder)\r
+ {\r
+ this.marker_holder=i_holder;\r
+ this.marker_array =new NyARMarker[i_holder.length];\r
+ this.marker_array_num =0;\r
+ this.marker_holder_num =0;\r
+ }\r
+ public NyARMarkerList(int i_number_of_holder)\r
+ {\r
+ this.marker_holder=new NyARMarker[i_number_of_holder];\r
+ //先にマーカーホルダにオブジェクトを作っておく\r
+ for(int i=0;i<i_number_of_holder;i++){\r
+ this.marker_holder[i]=new NyARMarker();\r
+ }\r
+ this.marker_array =new NyARMarker[this.marker_holder.length];\r
+ this.marker_array_num =0;\r
+ this.marker_holder_num =0;\r
+ }\r
+ /**\r
+ * 現在位置のマーカーホルダを返す。\r
+ * 現在位置が終端の場合関数は失敗する。\r
+ * @return\r
+ */\r
+ public final NyARMarker getCurrentHolder() throws NyARException\r
+ {\r
+ if(this.marker_holder_num>=this.marker_holder.length){\r
+ throw new NyARException();\r
+ } \r
+ return this.marker_holder[this.marker_holder_num];\r
+ }\r
+ /**\r
+ * マーカーホルダの現在位置を1つ進めて、そのホルダを返す。\r
+ * この関数を実行すると、使用中のマーカーホルダの数が1個増える。\r
+ * @return\r
+ * 空いているマーカーホルダが無ければnullを返します。\r
+ *\r
+ */\r
+ public final NyARMarker getNextHolder()\r
+ {\r
+ //現在位置が終端位置ならnullを返す。\r
+ if(this.marker_holder_num+1>=this.marker_holder.length){\r
+ this.marker_holder_num=this.marker_holder.length;\r
+ return null;\r
+ }\r
+ this.marker_holder_num++;\r
+ return this.marker_holder[this.marker_holder_num];\r
+ }\r
+ /**\r
+ * マーカーアレイのi_indexの要素を返す。\r
+ * @param i_index\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public final NyARMarker getMarker(int i_index) throws NyARException\r
+ {\r
+ if(i_index>=marker_array_num){\r
+ throw new NyARException();\r
+ }\r
+ return this.marker_array[i_index];\r
+ }\r
+ /**\r
+ * マーカーアレイの要素数を返す。\r
+ * @return\r
+ */\r
+ public final int getMarkerNum()\r
+ {\r
+ return marker_array_num;\r
+ }\r
+ /**\r
+ * マーカーアレイの要素数と、マーカーホルダの現在位置をリセットする。\r
+ * @return\r
+ */\r
+ public final void reset()\r
+ {\r
+ this.marker_array_num=0;\r
+ this.marker_holder_num=0;\r
+ }\r
+ /**\r
+ * マーカーホルダに格納済みのマーカーから重なっているのものを除外して、\r
+ * マーカーアレイにフィルタ結果を格納します。\r
+ * [[この関数はマーカー検出処理と密接に関係する関数です。\r
+ * NyARDetectMarkerクラス以外から呼び出さないで下さい。]]\r
+ * メモ:この関数はmarker_holderの内容を変化させまするので注意。\r
+ */\r
+ public final void updateMarkerArray()\r
+ {\r
+ //重なり処理かな?\r
+ int i;\r
+ double d;\r
+ double[] pos_j,pos_i;\r
+// NyARMarker[] marker_holder;\r
+ for(i=0; i < this.marker_holder_num; i++ ){\r
+ pos_i=marker_holder[i].pos;\r
+ for(int j=i+1; j < this.marker_holder_num; j++ ) {\r
+ pos_j=marker_holder[j].pos;\r
+ d = (pos_i[0] - pos_j[0])*(pos_i[0] - pos_j[0])+\r
+ (pos_i[1] - pos_j[1])*(pos_i[1] - pos_j[1]);\r
+ if(marker_holder[i].area >marker_holder[j].area ) {\r
+ if( d <marker_holder[i].area / 4 ) {\r
+ marker_holder[j].area = 0;\r
+ }\r
+ }else{\r
+ if( d < marker_holder[j].area / 4 ) {\r
+ marker_holder[i].area = 0;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ //みつかったマーカーを整理する。\r
+ int l_array_num=0;\r
+ //エリアが0のマーカーを外した配列を作って、その数もついでに計算\r
+ for(i=0;i<marker_holder_num;i++){\r
+ if(marker_holder[i].area==0.0){\r
+ continue;\r
+ }\r
+ marker_array[l_array_num]=marker_holder[i];\r
+ l_array_num++;\r
+ }\r
+ //マーカー個数を更新\r
+ this.marker_array_num=l_array_num;\r
+ } \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+ \r
+\r
+/**\r
+ * ARMat構造体に対応するクラス\r
+ * typedef struct {\r
+ * double *m;\r
+ * int row;\r
+ * int clm;\r
+ * }ARMat;\r
+ *\r
+ */\r
+public class NyARMat{\r
+ /**\r
+ * 配列サイズと行列サイズは必ずしも一致しないことに注意\r
+ * 返された配列のサイズを行列の大きさとして使わないこと!\r
+ * \r
+ */\r
+ protected double[][] m;\r
+ private int clm,row;\r
+ /**\r
+ * デフォルトコンストラクタは機能しません。\r
+ * @throws NyARException\r
+ */\r
+ protected NyARMat() throws NyARException\r
+ {\r
+ throw new NyARException();\r
+ }\r
+ public NyARMat(int i_row,int i_clm)\r
+ {\r
+ m=new double[i_row][i_clm];\r
+ clm=i_clm;\r
+ row=i_row;\r
+ }\r
+ /**\r
+ * i_row x i_clmサイズの行列を格納できるように行列サイズを変更します。\r
+ * 実行後、行列の各値は不定になります。\r
+ * @param i_row\r
+ * @param i_clm\r
+ */\r
+ public void realloc(int i_row,int i_clm)\r
+ {\r
+ if(i_row<=this.m.length && i_clm<=this.m[0].length)\r
+ {\r
+ //十分な配列があれば何もしない。\r
+ }else{\r
+ //不十分なら取り直す。\r
+ m=new double[i_row][i_clm];\r
+ }\r
+ this.clm=i_clm;\r
+ this.row=i_row;\r
+ }\r
+ public int getClm()\r
+ {\r
+ return clm;\r
+ }\r
+ public int getRow()\r
+ {\r
+ return row;\r
+ }\r
+ /**\r
+ * 行列をゼロクリアする。\r
+ */\r
+ public void zeroClear()\r
+ {\r
+ int i,i2;\r
+ //For順変更OK\r
+ for(i=row-1;i>=0;i--){\r
+ for(i2=clm-1;i2>=0;i2--){\r
+ m[i][i2]=0.0;\r
+ }\r
+ }\r
+ }\r
+ /**\r
+ * i_copy_fromの内容を自分自身にコピーします。\r
+ * 高さ・幅は同一で無いと失敗します。\r
+ * @param i_copy_from\r
+ */\r
+ public void copyFrom(NyARMat i_copy_from)throws NyARException\r
+ {\r
+ //サイズ確認\r
+ if(this.row!=i_copy_from.row ||this.clm!=i_copy_from.clm)\r
+ {\r
+ throw new NyARException();\r
+ }\r
+ //値コピー\r
+ for(int r=this.row-1;r>=0;r--){\r
+ for(int c=this.clm-1;c>=0;c--){\r
+ this.m[r][c]=i_copy_from.m[r][c];\r
+ }\r
+ }\r
+ }\r
+\r
+ public double[][] getArray()\r
+ {\r
+ return m;\r
+ }\r
+// public void getRowVec(int i_row,NyARVec o_vec)\r
+// {\r
+// o_vec.set(this.m[i_row],this.clm);\r
+// }\r
+ /**\r
+ * aとbの積を自分自身に格納する。arMatrixMul()の代替品\r
+ * @param a\r
+ * @param b\r
+ * @throws NyARException\r
+ */\r
+ public void matrixMul(NyARMat a, NyARMat b) throws NyARException\r
+ {\r
+ if(a.clm != b.row || this.row != a.row || this.clm != b.clm){\r
+ throw new NyARException();\r
+ }\r
+ double w;\r
+ int r,c,i;\r
+ double[][] am=a.m,bm=b.m,dm=this.m;\r
+ //For順変更禁止\r
+ for(r = 0; r < this.row; r++){\r
+ for(c = 0; c < this.clm; c++){\r
+ w=0.0;//dest.setARELEM0(r, c,0.0);\r
+ for(i = 0; i < a.clm; i++){\r
+ w+=am[r][i]*bm[i][c];//ARELEM0(dest, r, c) += ARELEM0(a, r, i) * ARELEM0(b, i, c);\r
+ }\r
+ dm[r][c]=w;\r
+ }\r
+ }\r
+ }\r
+ private int[] wk_nos_matrixSelfInv=new int[50];\r
+// private final static double matrixSelfInv_epsl=1.0e-10;\r
+ /**\r
+ * i_targetを逆行列に変換する。arMatrixSelfInv()と、arMatrixSelfInv_minv()関数を合成してあります。\r
+ * OPTIMIZE STEP[485->422]\r
+ * @param i_target\r
+ * 逆行列にする行列\r
+ * @return\r
+ * 逆行列があればTRUE/無ければFALSE\r
+ * \r
+ * @throws NyARException\r
+ */\r
+ public boolean matrixSelfInv() throws NyARException\r
+ {\r
+ double[][] ap=this.m;\r
+ int dimen=this.row;\r
+ int dimen_1=dimen-1;\r
+ double[] ap_n,ap_ip,ap_i;//wap;\r
+ int j,ip,nwork;\r
+ int[] nos=wk_nos_matrixSelfInv;//この関数で初期化される。\r
+ //double epsl;\r
+ double p,pbuf,work;\r
+\r
+ /* check size */\r
+ switch(dimen){\r
+ case 0:\r
+ throw new NyARException();\r
+ case 1:\r
+ ap[0][0]=1.0/ap[0][0];//*ap = 1.0 / (*ap);\r
+ return true;/* 1 dimension */\r
+ }\r
+\r
+ for(int n = 0; n < dimen ; n++){\r
+ nos[n] = n;\r
+ }\r
+\r
+ /* nyatla memo\r
+ * ipが定まらないで計算が行われる場合があるので挿入。\r
+ * ループ内で0初期化していいかが判らない。\r
+ */\r
+ ip=0;\r
+ //For順変更禁止\r
+ for(int n=0; n<dimen;n++)\r
+ {\r
+ ap_n =ap[n];//wcp = ap + n * rowa;\r
+ p=0.0;\r
+ for(int i = n; i<dimen ; i++){//for(i = n, wap = wcp, p = 0.0; i < dimen ; i++, wap += rowa)\r
+ if( p < ( pbuf = Math.abs(ap[i][0]))) {\r
+ p = pbuf;\r
+ ip = i;\r
+ }\r
+ }\r
+// if (p <= matrixSelfInv_epsl){\r
+ if(p==0.0){\r
+ return false;\r
+// throw new NyARException();\r
+ }\r
+\r
+ nwork = nos[ip];\r
+ nos[ip]= nos[n];\r
+ nos[n] = nwork;\r
+ \r
+ ap_ip=ap[ip];\r
+ for(j=0; j< dimen ; j++){//for(j = 0, wap = ap + ip * rowa, wbp = wcp; j < dimen ; j++) {\r
+ work = ap_ip[j]; //work = *wap;\r
+ ap_ip[j]=ap_n[j];\r
+ ap_n[j]=work;\r
+ }\r
+ \r
+ work=ap_n[0];\r
+ for(j = 0; j < dimen_1 ; j++){//for(j = 1, wap = wcp, work = *wcp; j < dimen ; j++, wap++)\r
+ ap_n[j]=ap_n[j+1]/work;//*wap = *(wap + 1) / work;\r
+ }\r
+ ap_n[j]=1.0/work;//*wap = 1.0 / work;\r
+ for(int i = 0; i < dimen ; i++) {\r
+ if(i != n) {\r
+ ap_i =ap[i];//wap = ap + i * rowa;\r
+\r
+ work=ap_i[0];\r
+ for(j = 0;j < dimen_1 ; j++){//for(j = 1, wbp = wcp, work = *wap;j < dimen ; j++, wap++, wbp++)\r
+ ap_i[j]=ap_i[j+1]-work*ap_n[j];//wap = *(wap + 1) - work * (*wbp);\r
+ }\r
+ ap_i[j]=-work*ap_n[j];//*wap = -work * (*wbp);\r
+ }\r
+ }\r
+ }\r
+\r
+ for(int n = 0; n < dimen ; n++) {\r
+ for(j = n; j < dimen ; j++){\r
+ if( nos[j] == n){\r
+ break;\r
+ }\r
+ }\r
+ nos[j] = nos[n];\r
+ for(int i = 0; i < dimen ;i++){//for(i = 0, wap = ap + j, wbp = ap + n; i < dimen ;i++, wap += rowa, wbp += rowa) {\r
+ ap_i=ap[i];\r
+ work =ap_i[j];//work = *wap;\r
+ ap_i[j]=ap_i[n];//*wap = *wbp;\r
+ ap_i[n]=work;//*wbp = work;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * sourceの転置行列をdestに得る。arMatrixTrans()の代替品\r
+ * @param dest\r
+ * @param source\r
+ * @return\r
+ */\r
+ public static void matrixTrans(NyARMat dest,NyARMat source) throws NyARException\r
+ {\r
+ if(dest.row != source.clm || dest.clm != source.row){\r
+ throw new NyARException();\r
+ }\r
+ NyARException.trap("未チェックのパス");\r
+ //For順変更禁止\r
+ for(int r=0;r< dest.row;r++){\r
+ for(int c=0;c<dest.clm;c++){\r
+ dest.m[r][c]=source.m[c][r];\r
+ }\r
+ }\r
+ }\r
+ /**\r
+ * unitを単位行列に初期化する。arMatrixUnitの代替品\r
+ * @param unit\r
+ */\r
+ public static void matrixUnit(NyARMat unit) throws NyARException\r
+ {\r
+ if(unit.row != unit.clm){\r
+ throw new NyARException();\r
+ }\r
+ NyARException.trap("未チェックのパス");\r
+ //For順変更禁止\r
+ for(int r = 0; r < unit.getRow(); r++) {\r
+ for(int c = 0; c < unit.getClm(); c++) {\r
+ if(r == c) {\r
+ unit.m[r][c]=1.0;\r
+ }else{\r
+ unit.m[r][c]=0.0;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ /**\r
+ * sourceの内容を自身に複製する。\r
+ * Optimized 2008.04.19\r
+ * @param i_source\r
+ * @return\r
+ */\r
+ public void matrixDup(NyARMat i_source) throws NyARException\r
+ {\r
+ //自身の配列サイズを相手のそれより大きいことを保障する。\r
+ this.realloc(i_source.row,i_source.clm);\r
+ //内容を転写\r
+ int r,c;\r
+ double[][] src_m,dest_m;\r
+ src_m=i_source.m;\r
+ dest_m=this.m;\r
+ //コピーはFor順を変えてもOK\r
+ for(r = this.row-1; r>=0; r--){\r
+ for(c =this.clm-1;c>=0; c--)\r
+ {\r
+ dest_m[r][c]=src_m[r][c];\r
+ }\r
+ }\r
+ }\r
+ public NyARMat matrixAllocDup() throws NyARException\r
+ {\r
+ NyARMat result=new NyARMat(this.row,this.clm);\r
+ //コピー\r
+ int r,c;\r
+ double[][] dest_m,src_m;\r
+ dest_m=result.m;\r
+ src_m =this.m;\r
+ //コピーはFor順を変えてもOK\r
+ for(r = this.row-1; r>=0; r--){\r
+ for(c =this.clm-1;c>=0; c--)\r
+ {\r
+ dest_m[r][c]=src_m[r][c];\r
+ }\r
+ }\r
+ return result;\r
+ } \r
+ /**\r
+ * arMatrixInv関数の代替品です。\r
+ * destにsourceの逆行列を返します。\r
+ * @param dest\r
+ * @param source\r
+ * @throws NyARException\r
+ */\r
+ public static void matrixInv(NyARMat dest,NyARMat source) throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ dest.matrixDup(source);\r
+\r
+ NyARException.trap("未チェックのパス");\r
+ dest.matrixSelfInv();\r
+ }\r
+ public NyARMat matrixAllocInv() throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ NyARMat result=matrixAllocDup();\r
+\r
+ NyARException.trap("未チェックのパス");\r
+ result.matrixSelfInv();\r
+ return result;\r
+ }\r
+ /**\r
+ * dim x dim の単位行列を作る。\r
+ * @param dim\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public static NyARMat matrixAllocUnit(int dim) throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ NyARMat result = new NyARMat(dim, dim);\r
+ NyARException.trap("未チェックのパス");\r
+ NyARMat.matrixUnit(result);\r
+ return result;\r
+ }\r
+ /**\r
+ * arMatrixDispの代替品\r
+ * @param m\r
+ * @return\r
+ */\r
+ public int matrixDisp() throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ System.out.println(" === matrix ("+row+","+clm+") ===");//printf(" === matrix (%d,%d) ===\n", m->row, m->clm);\r
+ for(int r = 0; r < row; r++){//for(int r = 0; r < m->row; r++) {\r
+ System.out.print(" |");//printf(" |");\r
+ for(int c = 0; c < clm; c++) {//for(int c = 0; c < m->clm; c++) {\r
+ System.out.print(" "+m[r][c]);//printf(" %10g", ARELEM0(m, r, c));\r
+ }\r
+ System.out.println(" |");//printf(" |\n");\r
+ }\r
+ System.out.println(" ======================");//printf(" ======================\n");\r
+ return 0;\r
+ }\r
+ private final static double PCA_EPS=1e-6; //#define EPS 1e-6\r
+ private final static int PCA_MAX_ITER=100; //#define MAX_ITER 100\r
+ private final static double PCA_VZERO=1e-16; //#define VZERO 1e-16\r
+ /**\r
+ * static int EX( ARMat *input, ARVec *mean )の代替関数\r
+ * Optimize:STEP:[144->110]\r
+ * @param input\r
+ * @param mean\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ private void PCA_EX(NyARVec mean) throws NyARException\r
+ {\r
+ int lrow,lclm;\r
+ int i,i2;\r
+ lrow = this.row;\r
+ lclm = this.clm;\r
+ double lm[][]=this.m;\r
+ \r
+ if(lrow <= 0 || lclm <= 0){\r
+ throw new NyARException();\r
+ }\r
+ if( mean.getClm() != lclm ){\r
+ throw new NyARException();\r
+ }\r
+// double[] mean_array=mean.getArray();\r
+// mean.zeroClear();\r
+ final double[] mean_array=mean.getArray();\r
+ double w;\r
+ //For順変更禁止\r
+ for(i2=0;i2<lclm;i2++){\r
+ w=0.0;\r
+ for(i=0;i<lrow;i++){\r
+ //*(v++) += *(m++);\r
+ w+=lm[i][i2];\r
+ }\r
+ mean_array[i2]=w/lrow;//mean->v[i] /= row;\r
+ }\r
+ }\r
+ /**\r
+ * static int CENTER( ARMat *inout, ARVec *mean )の代替関数\r
+ * @param inout\r
+ * @param mean\r
+ * @return\r
+ */\r
+ private static void PCA_CENTER(NyARMat inout, NyARVec mean) throws NyARException\r
+ {\r
+ double[] v;\r
+ int row, clm;\r
+ \r
+ row = inout.getRow();\r
+ clm = inout.getClm();\r
+ if(mean.getClm()!= clm){\r
+ throw new NyARException();\r
+ }\r
+ double[][] im=inout.m;\r
+ double[] im_i;\r
+ double w0,w1;\r
+ v = mean.getArray();\r
+ //特にパフォーマンスが劣化するclm=1と2ときだけ、別パスで処理します。\r
+ switch(clm){\r
+ case 1:\r
+ w0=v[0];\r
+ for(int i = 0; i < row; i++ ){\r
+ im[i][0]-=w0;\r
+ }\r
+ break;\r
+ case 2:\r
+ w0=v[0];\r
+ w1=v[1];\r
+ for(int i = 0; i < row; i++ ){\r
+ im_i=im[i];\r
+ im_i[0]-=w0;\r
+ im_i[1]-=w1;\r
+ }\r
+ break;\r
+ default:\r
+ for(int i = 0; i < row; i++ ){\r
+ im_i=im[i];\r
+ for(int j = 0; j < clm; j++ ){\r
+ //*(m++) -= *(v++);\r
+ im_i[j]-=v[j];\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * int x_by_xt( ARMat *input, ARMat *output )の代替関数\r
+ * @param input\r
+ * @param output\r
+ * @throws NyARException\r
+ */\r
+ private static void PCA_x_by_xt( NyARMat input, NyARMat output) throws NyARException\r
+ {\r
+ NyARException.trap("動作未チェック/配列化未チェック");\r
+ int row, clm;\r
+// double[][] out;\r
+ double[] in1,in2;\r
+ \r
+ NyARException.trap("未チェックのパス");\r
+ row = input.row;\r
+ clm = input.clm;\r
+ NyARException.trap("未チェックのパス");\r
+ if( output.row != row || output.clm != row ){\r
+ throw new NyARException();\r
+ }\r
+ \r
+// out = output.getArray();\r
+ for(int i = 0; i < row; i++ ) {\r
+ for(int j = 0; j < row; j++ ) {\r
+ if( j < i ) {\r
+ NyARException.trap("未チェックのパス");\r
+ output.m[i][j]=output.m[j][i];//*out = output->m[j*row+i];\r
+ }else{\r
+ NyARException.trap("未チェックのパス");\r
+ in1=input.m[i];//input.getRowArray(i);//in1 = &(input->m[clm*i]);\r
+ in2=input.m[j];//input.getRowArray(j);//in2 = &(input->m[clm*j]);\r
+ output.m[i][j]=0;//*out = 0.0;\r
+ for(int k = 0; k < clm; k++ ){\r
+ output.m[i][j]+=(in1[k]*in2[k]);//*out += *(in1++) * *(in2++);\r
+ }\r
+ }\r
+ // out.incPtr();\r
+ }\r
+ }\r
+ }\r
+ /**\r
+ * static int xt_by_x( ARMat *input, ARMat *output )の代替関数\r
+ * Optimize:2008.04.19\r
+ * @param input\r
+ * @param i_output\r
+ * @throws NyARException\r
+ */\r
+ private static void PCA_xt_by_x(NyARMat input, NyARMat i_output) throws NyARException\r
+ {\r
+ double[] in;\r
+ int row, clm;\r
+ \r
+ row = input.row;\r
+ clm = input.clm;\r
+ if(i_output.row!= clm || i_output.clm != clm ){\r
+ throw new NyARException();\r
+ }\r
+ \r
+ int k,j;\r
+ double[][] out_m=i_output.m;\r
+ double w;\r
+ for(int i = 0; i < clm; i++ ) {\r
+ for(j = 0; j < clm; j++ ) {\r
+ if( j < i ) {\r
+ out_m[i][j]=out_m[j][i];//*out = output->m[j*clm+i];\r
+ }else{\r
+ w=0.0;//*out = 0.0;\r
+ for(k = 0; k < row; k++ ){\r
+ in=input.m[k];//in=input.getRowArray(k);\r
+ w+=(in[i]*in[j]);//*out += *in1 * *in2;\r
+ }\r
+ out_m[i][j]=w;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ private final NyARVec wk_PCA_QRM_ev=new NyARVec(1);\r
+ /**\r
+ * static int QRM( ARMat *a, ARVec *dv )の代替関数\r
+ * @param a\r
+ * @param dv\r
+ * @throws NyARException\r
+ */\r
+ private void PCA_QRM(NyARVec dv) throws NyARException\r
+ {\r
+ double w, t, s, x, y, c;\r
+ int dim, iter;\r
+ double[] dv_array=dv.getArray();\r
+\r
+ dim = this.row;\r
+ if( dim != this.clm || dim < 2 ){\r
+ throw new NyARException();\r
+ }\r
+ if( dv.getClm() != dim ){\r
+ throw new NyARException();\r
+ }\r
+\r
+ NyARVec ev = this.wk_PCA_QRM_ev;\r
+ ev.realloc(dim);\r
+ double[] ev_array=ev.getArray();\r
+ if( ev == null ){\r
+ throw new NyARException();\r
+ }\r
+ final double[][] L_m=this.m;\r
+ this.vecTridiagonalize(dv,ev,1);\r
+\r
+ ev_array[0]=0.0;//ev->v[0] = 0.0;\r
+ for(int h = dim-1; h > 0; h-- ) {\r
+ int j = h;\r
+ while(j>0 && Math.abs(ev_array[j]) > PCA_EPS*(Math.abs(dv_array[j-1])+Math.abs(dv_array[j]))){// while(j>0 && fabs(ev->v[j]) > EPS*(fabs(dv->v[j-1])+fabs(dv->v[j]))) j--;\r
+ j--;\r
+ }\r
+ if( j == h ){\r
+ continue;\r
+ }\r
+ iter = 0;\r
+ do{\r
+ iter++;\r
+ if( iter > PCA_MAX_ITER ){\r
+ break;\r
+ }\r
+ w = (dv_array[h-1] - dv_array[h]) / 2;//w = (dv->v[h-1] - dv->v[h]) / 2;//ここ?\r
+ t = ev_array[h] * ev_array[h];//t = ev->v[h] * ev->v[h];\r
+ s = Math.sqrt(w*w+t);\r
+ if( w < 0 ){\r
+ s = -s;\r
+ }\r
+ x=dv_array[j] - dv_array[h] + t/(w+s);//x = dv->v[j] - dv->v[h] + t/(w+s);\r
+ y=ev_array[j+1];//y = ev->v[j+1];\r
+ for(int k = j; k < h; k++ ){\r
+ if( Math.abs(x) >= Math.abs(y)){\r
+ if( Math.abs(x) > PCA_VZERO ) {\r
+ t = -y / x;\r
+ c = 1 / Math.sqrt(t*t+1);\r
+ s = t * c;\r
+ }else{\r
+ c = 1.0;\r
+ s = 0.0;\r
+ }\r
+ }else{\r
+ t = -x / y;\r
+ s = 1.0 / Math.sqrt(t*t+1);\r
+ c = t * s;\r
+ }\r
+ w = dv_array[k] - dv_array[k+1];//w = dv->v[k] - dv->v[k+1];\r
+ t = (w * s + 2 * c * ev_array[k+1]) * s;//t = (w * s + 2 * c * ev->v[k+1]) * s;\r
+ dv_array[k]-=t;//dv->v[k] -= t;\r
+ dv_array[k+1]+=t;//dv->v[k+1] += t;\r
+ if( k > j){\r
+ NyARException.trap("未チェックパス");{\r
+ ev_array[k]=c * ev_array[k] - s * y;//ev->v[k] = c * ev->v[k] - s * y;\r
+ }\r
+ }\r
+ ev_array[k+1]+=s * (c * w - 2 * s * ev_array[k+1]);//ev->v[k+1] += s * (c * w - 2 * s * ev->v[k+1]);\r
+\r
+ for(int i = 0; i < dim; i++ ){\r
+ x = L_m[k][i];//x = a->m[k*dim+i];\r
+ y = L_m[k+1][i];//y = a->m[(k+1)*dim+i];\r
+ L_m[k][i]=c * x - s * y;//a->m[k*dim+i] = c * x - s * y;\r
+ L_m[k+1][i]=s * x + c * y;//a->m[(k+1)*dim+i] = s * x + c * y;\r
+ }\r
+ if( k < h-1 ) {\r
+ NyARException.trap("未チェックパス");{\r
+ x = ev_array[k+1];//x = ev->v[k+1];\r
+ y =-s*ev_array[k+2];//y = -s * ev->v[k+2];\r
+ ev_array[k+2]*=c;//ev->v[k+2] *= c;\r
+ }\r
+ }\r
+ }\r
+ }while(Math.abs(ev_array[h]) > PCA_EPS*(Math.abs(dv_array[h-1])+Math.abs(dv_array[h])));\r
+ }\r
+ for(int k = 0; k < dim-1; k++ ) {\r
+ int h = k;\r
+ t=dv_array[h];//t = dv->v[h];\r
+ for(int i = k+1; i < dim; i++ ){\r
+ if(dv_array[i] > t ){//if( dv->v[i] > t ) {\r
+ h = i;\r
+ t=dv_array[h];//t = dv->v[h];\r
+ }\r
+ }\r
+ dv_array[h]=dv_array[k];//dv->v[h] = dv->v[k];\r
+ dv_array[k]=t;//dv->v[k] = t;\r
+ this.flipRow(h,k);\r
+ }\r
+ }\r
+ /**\r
+ * i_row_1番目の行と、i_row_2番目の行を入れ替える。\r
+ * @param i_row_1\r
+ * @param i_row_2\r
+ */\r
+ private void flipRow(int i_row_1,int i_row_2)\r
+ {\r
+ int i;\r
+ double w;\r
+ double[] r1=this.m[i_row_1],r2=this.m[i_row_2];\r
+ //For順変更OK\r
+ for(i=clm-1;i>=0;i--){\r
+ w=r1[i];\r
+ r1[i]=r2[i];\r
+ r2[i]=w;\r
+ }\r
+ }\r
+ /**\r
+ * static int EV_create( ARMat *input, ARMat *u, ARMat *output, ARVec *ev )の代替関数\r
+ * @param input\r
+ * @param u\r
+ * @param output\r
+ * @param ev\r
+ * @throws NyARException\r
+ */\r
+ private static void PCA_EV_create(NyARMat input, NyARMat u, NyARMat output, NyARVec ev) throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ int row, clm;\r
+ row = input.row;//row = input->row;\r
+ clm = input.clm;//clm = input->clm;\r
+ if( row <= 0 || clm <= 0 ){\r
+ throw new NyARException();\r
+ }\r
+ if( u.row != row || u.clm != row ){//if( u->row != row || u->clm != row ){\r
+ throw new NyARException();\r
+ }\r
+ if( output.row != row || output.clm != clm ){//if( output->row != row || output->clm != clm ){\r
+ throw new NyARException();\r
+ }\r
+ if( ev.getClm()!= row ){//if( ev->clm != row ){\r
+ throw new NyARException();\r
+ }\r
+ double[][] m,in;\r
+ double[] m1,ev_array;\r
+ double sum, work;\r
+ \r
+ NyARException.trap("未チェックのパス");\r
+ m =output.m;//m = output->m;\r
+ in=input.m;\r
+ int i;\r
+ ev_array=ev.getArray();\r
+ for(i = 0; i < row; i++ ) {\r
+ NyARException.trap("未チェックのパス");\r
+ if( ev_array[i]<PCA_VZERO ){//if( ev->v[i] < VZERO ){\r
+ break;\r
+ }\r
+ NyARException.trap("未チェックのパス");\r
+ work = 1 / Math.sqrt(Math.abs(ev_array[i]));//work = 1 / sqrt(fabs(ev->v[i]));\r
+ for(int j = 0; j < clm; j++ ) {\r
+ sum = 0.0;\r
+ m1=u.m[i];//m1 = &(u->m[i*row]);\r
+ // m2=input.getPointer(j);//m2 = &(input->m[j]);\r
+ for(int k = 0; k < row; k++ ) {\r
+ sum+=m1[k]+in[k][j];//sum += *m1 * *m2;\r
+ // m1.incPtr(); //m1++;\r
+ // m2.addPtr(clm);//m2 += clm;\r
+ }\r
+ m1[j]=sum * work;//*(m++) = sum * work;\r
+ // {//*(m++) = sum * work;\r
+ // m.set(sum * work);\r
+ // m.incPtr();}\r
+ }\r
+ }\r
+ for( ; i < row; i++ ) {\r
+ NyARException.trap("未チェックのパス");\r
+ ev_array[i]=0.0;//ev->v[i] = 0.0;\r
+ for(int j = 0; j < clm; j++ ){\r
+ m[i][j]=0.0;\r
+ // m.set(0.0);//*(m++) = 0.0;\r
+ // m.incPtr();\r
+ }\r
+ }\r
+ }\r
+ private NyARMat wk_PCA_PCA_u=null;\r
+ /**\r
+ * static int PCA( ARMat *input, ARMat *output, ARVec *ev )\r
+ * \r
+ * @param output\r
+ * @param o_ev\r
+ * @throws NyARException\r
+ */\r
+ private void PCA_PCA(NyARMat o_output, NyARVec o_ev) throws NyARException\r
+ {\r
+ \r
+ int l_row, l_clm, min;\r
+ double[] ev_array=o_ev.getArray();\r
+\r
+ l_row =this.row;//row = input->row;\r
+ l_clm =this.clm;//clm = input->clm;\r
+ min =(l_clm < l_row)? l_clm: l_row;\r
+ if( l_row < 2 || l_clm < 2 ){\r
+ throw new NyARException();\r
+ }\r
+ if( o_output.clm != this.clm){//if( output->clm != input->clm ){\r
+ throw new NyARException();\r
+ }\r
+ if( o_output.row!= min ){//if( output->row != min ){\r
+ throw new NyARException();\r
+ }\r
+ if( o_ev.getClm() != min ){//if( ev->clm != min ){\r
+ throw new NyARException();\r
+ }\r
+ \r
+ NyARMat u;// u =new NyARMat( min, min );\r
+ if(this.wk_PCA_PCA_u==null){\r
+ u=new NyARMat( min, min );\r
+ this.wk_PCA_PCA_u=u;\r
+ }else{\r
+ u=this.wk_PCA_PCA_u;\r
+ u.realloc(min,min);\r
+ }\r
+ \r
+ \r
+ if( l_row < l_clm ){\r
+ NyARException.trap("未チェックのパス");\r
+ PCA_x_by_xt( this, u );//if(x_by_xt( input, u ) < 0 ) {\r
+ }else{\r
+ PCA_xt_by_x( this, u );//if(xt_by_x( input, u ) < 0 ) {\r
+ }\r
+ u.PCA_QRM(o_ev);\r
+\r
+ double[][] m1,m2;\r
+ if( l_row < l_clm ) {\r
+ NyARException.trap("未チェックのパス");\r
+ PCA_EV_create( this, u, o_output, o_ev );\r
+ }else{\r
+ m1=u.m;//m1 = u->m;\r
+ m2=o_output.m;//m2 = output->m;\r
+ int i;\r
+ for(i = 0; i < min; i++){\r
+ if( ev_array[i] < PCA_VZERO){//if( ev->v[i] < VZERO ){\r
+ break;\r
+ }\r
+ for(int j = 0; j < min; j++ ){\r
+ m2[i][j]=m1[i][j];//*(m2++) = *(m1++);\r
+ }\r
+ }\r
+ for( ; i < min; i++){//for( ; i < min; i++){\r
+ //コードを見た限りあってそうだからコメントアウト(2008/03/26)NyARException.trap("未チェックのパス");\r
+ ev_array[i]=0.0;//ev->v[i] = 0.0;\r
+ for(int j = 0; j < min; j++ ){\r
+ m2[i][j]=0.0;//*(m2++) = 0.0;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ private NyARMat wk_work_matrixPCA=null;\r
+ /**\r
+ * int arMatrixPCA( ARMat *input, ARMat *evec, ARVec *ev, ARVec *mean );\r
+ * 関数の置き換え。input引数がthisになる。\r
+ * Optimize:2008.04.19\r
+ * @param o_evec\r
+ * @param o_ev\r
+ * \r
+ * @param mean\r
+ * @throws NyARException\r
+ */ \r
+ public void matrixPCA(NyARMat o_evec, NyARVec o_ev, NyARVec mean) throws NyARException\r
+ {\r
+ double srow, sum;\r
+ int l_row, l_clm;\r
+ int check;\r
+ \r
+\r
+ l_row=this.row;//row = input->row;\r
+ l_clm=this.clm;//clm = input->clm;\r
+ check = (l_row < l_clm)? l_row: l_clm;\r
+ if( l_row < 2 || l_clm < 2 ){\r
+ throw new NyARException();\r
+ }\r
+ if( o_evec.clm != l_clm || o_evec.row != check ){//if( evec->clm != input->clm || evec->row != check ){\r
+ throw new NyARException();\r
+ }\r
+ if( o_ev.getClm() != check ){//if( ev->clm != check ){\r
+ throw new NyARException();\r
+ }\r
+ if( mean.getClm() != l_clm){//if( mean->clm != input->clm ){\r
+ throw new NyARException();\r
+ }\r
+\r
+ //自分の内容をワークにコピー(高速化の為に、1度作ったインスタンスは使いまわす)\r
+ NyARMat work;\r
+ if(this.wk_work_matrixPCA==null){\r
+ work=this.matrixAllocDup();\r
+ this.wk_work_matrixPCA=work;\r
+ }else{\r
+ work=this.wk_work_matrixPCA;\r
+ work.matrixDup(this);//arMatrixAllocDup( input );work = arMatrixAllocDup( input );\r
+ }\r
+ \r
+ \r
+ srow = Math.sqrt((double)l_row);\r
+ work.PCA_EX(mean );\r
+\r
+ PCA_CENTER(work,mean);\r
+\r
+\r
+ int i,j;\r
+ //For順変更OK\r
+ for(i=0; i<l_row; i++){\r
+ for(j=0;j<l_clm;j++){\r
+ work.m[i][j]/=srow;//work->m[i] /= srow;\r
+ }\r
+ }\r
+ \r
+ work.PCA_PCA(o_evec, o_ev);\r
+ \r
+ sum = 0.0;\r
+ double[] ev_array=o_ev.getArray();\r
+ int ev_clm=o_ev.getClm();\r
+ //For順変更禁止\r
+ for(i=0;i<ev_clm;i++){//for(int i = 0; i < ev->clm; i++ ){\r
+ sum+=ev_array[i];//sum += ev->v[i];\r
+ }\r
+ //For順変更禁止\r
+ for(i=0;i<ev_clm;i++){//for(int i = 0; i < ev->clm; i++ ){\r
+ ev_array[i]/=sum;//ev->v[i] /= sum;\r
+ }\r
+ }\r
+\r
+ /*int arMatrixPCA2( ARMat *input, ARMat *evec, ARVec *ev );*/\r
+ public static void arMatrixPCA2( NyARMat input, NyARMat evec, NyARVec ev) throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ NyARMat work;\r
+ // double srow; // unreferenced\r
+ double sum;\r
+ int row, clm;\r
+ int check;\r
+\r
+ row=input.row;//row = input->row;\r
+ clm=input.clm;//clm = input->clm;\r
+ check = (row < clm)? row: clm;\r
+ if( row < 2 || clm < 2 ){\r
+ throw new NyARException();\r
+ }\r
+ if( evec.getClm()!= input.clm|| evec.row!=check){//if( evec->clm != input->clm || evec->row != check ){\r
+ throw new NyARException();\r
+ }\r
+ if( ev.getClm() != check ){//if( ev->clm != check ){\r
+ throw new NyARException();\r
+ }\r
+ \r
+ NyARException.trap("未チェックのパス");\r
+ work =input.matrixAllocDup();\r
+\r
+ NyARException.trap("未チェックパス");\r
+ work.PCA_PCA(evec, ev );//rval = PCA( work, evec, ev );\r
+ sum = 0.0;\r
+ double[] ev_array=ev.getArray();\r
+ for(int i = 0; i < ev.getClm(); i++ ){//for( i = 0; i < ev->clm; i++ ){\r
+ NyARException.trap("未チェックパス");\r
+ sum+=ev_array[i];//sum += ev->v[i];\r
+ }\r
+ for(int i = 0; i < ev.getClm(); i++ ){//for(int i = 0; i < ev->clm; i++ ){\r
+ NyARException.trap("未チェックパス");\r
+ ev_array[i]/=sum;//ev->v[i] /= sum;\r
+ }\r
+ return;\r
+ }\r
+ public static NyARMat matrixAllocMul(NyARMat a, NyARMat b) throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ NyARMat dest=new NyARMat(a.row, b.clm);\r
+ NyARException.trap("未チェックのパス");\r
+ dest.matrixMul(a, b);\r
+ return dest;\r
+ }\r
+ /*static double mdet(double *ap, int dimen, int rowa)*/\r
+ private static double Det_mdet(double[][] ap, int dimen, int rowa) throws NyARException\r
+ {\r
+ NyARException.trap("動作未チェック/配列化未チェック");\r
+ double det = 1.0;\r
+ double work;\r
+ int is = 0;\r
+ int mmax;\r
+ \r
+ for(int k = 0; k < dimen - 1; k++) {\r
+ mmax = k;\r
+ for(int i = k + 1; i < dimen; i++){\r
+// if (Math.abs(arMatrixDet_MATRIX_get(ap, i, k, rowa)) > Math.abs(arMatrixDet_MATRIX_get(ap, mmax, k, rowa))){\r
+ if (Math.abs(ap[i][k]) > Math.abs(ap[mmax][k])){\r
+ mmax = i;\r
+ }\r
+ }\r
+ if(mmax != k) {\r
+ for (int j = k; j < dimen; j++) {\r
+ work = ap[k][j];//work = MATRIX(ap, k, j, rowa);\r
+ ap[k][j]=ap[mmax][j];//MATRIX(ap, k, j, rowa) = MATRIX(ap, mmax, j, rowa);\r
+ ap[mmax][j]=work;//MATRIX(ap, mmax, j, rowa) = work;\r
+ }\r
+ is++;\r
+ }\r
+ for(int i = k + 1; i < dimen; i++) {\r
+ work = ap[i][k]/ ap[k][k];//work = arMatrixDet_MATRIX_get(ap, i, k, rowa) / arMatrixDet_MATRIX_get(ap, k, k, rowa);\r
+ for (int j = k + 1; j < dimen; j++){\r
+ //MATRIX(ap, i, j, rowa) -= work * MATRIX(ap, k, j, rowa);\r
+ ap[i][j]-=work * ap[k][j];\r
+ }\r
+ }\r
+ }\r
+ for(int i = 0; i < dimen; i++){\r
+ det=ap[i][i];//det *= MATRIX(ap, i, i, rowa);\r
+ }\r
+ for(int i = 0; i < is; i++){ \r
+ det *= -1.0;\r
+ }\r
+ return det;\r
+ }\r
+ /*double arMatrixDet(ARMat *m);*/\r
+ public static double arMatrixDet(NyARMat m) throws NyARException\r
+ {\r
+ NyARException.trap("動作未チェック/配列化未チェック");\r
+ if(m.row != m.clm){\r
+ return 0.0;\r
+ }\r
+ return Det_mdet(m.getArray(), m.row, m.clm);//return mdet(m->m, m->row, m->row);\r
+ }\r
+ private final NyARVec wk_vecTridiagonalize_vec=new NyARVec(0);\r
+ private final NyARVec wk_vecTridiagonalize_vec2=new NyARVec(0);\r
+ /**\r
+ * arVecTridiagonalize関数の代替品\r
+ * a,d,e間で演算をしてる。何をどうしているかはさっぱりさっぱり\r
+ * @param a\r
+ * @param d\r
+ * @param e\r
+ * @param i_e_start\r
+ * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ private void vecTridiagonalize(NyARVec d, NyARVec e,int i_e_start) throws NyARException\r
+ {\r
+ NyARVec vec=wk_vecTridiagonalize_vec;\r
+ //double[][] a_array=a.getArray();\r
+ double s, t, p, q;\r
+ int dim;\r
+\r
+ if(this.clm!=this.row){//if(a.getClm()!=a.getRow()){\r
+ throw new NyARException();\r
+ }\r
+ if(this.clm != d.getClm()){//if(a.getClm() != d.clm){\r
+ throw new NyARException();\r
+ }\r
+ if(this.clm != e.getClm()){//if(a.getClm() != e.clm){\r
+ throw new NyARException();\r
+ }\r
+ dim = this.getClm();\r
+ \r
+ double[] d_vec,e_vec;\r
+ d_vec=d.getArray();\r
+ e_vec=e.getArray();\r
+ double[] a_vec_k;\r
+\r
+ for(int k = 0; k < dim-2; k++ ){\r
+ \r
+ a_vec_k=this.m[k];\r
+ vec.setNewArray(a_vec_k,clm);//vec=this.getRowVec(k);//double[] vec_array=vec.getArray();\r
+ NyARException.trap("未チェックパス"); \r
+ d_vec[k]=a_vec_k[k];//d.v[k]=vec.v[k];//d.set(k,v.get(k)); //d->v[k] = v[k];\r
+\r
+ //wv1.clm = dim-k-1;\r
+ //wv1.v = &(v[k+1]);\r
+ NyARException.trap("未チェックパス"); \r
+ e_vec[k+i_e_start]=vec.vecHousehold(k+1);//e.v[k+i_e_start]=vec.vecHousehold(k+1);//e->v[k] = arVecHousehold(&wv1);\r
+ if(e_vec[k+i_e_start]== 0.0 ){//if(e.v[k+i_e_start]== 0.0 ){//if(e.v[k+i_e_start]== 0.0 ){\r
+ continue;\r
+ }\r
+\r
+ for(int i = k+1; i < dim; i++ ){\r
+ s = 0.0;\r
+ for(int j = k+1; j < i; j++ ) {\r
+ NyARException.trap("未チェックのパス");\r
+ s += this.m[j][i] * a_vec_k[j];//s += a_array[j][i] * vec.v[j];//s += a.get(j*dim+i) * v.get(j);//s += a->m[j*dim+i] * v[j];\r
+ }\r
+ for(int j = i; j < dim; j++ ) {\r
+ NyARException.trap("未チェックのパス");\r
+ s += this.m[i][j] * a_vec_k[j];//s += a_array[i][j] * vec.v[j];//s += a.get(i*dim+j) * v.get(j);//s += a->m[i*dim+j] * v[j];\r
+ }\r
+ NyARException.trap("未チェックのパス");\r
+ d_vec[i]=s;//d.v[i]=s;//d->v[i] = s;\r
+ }\r
+ \r
+\r
+ //wv1.clm = wv2.clm = dim-k-1;\r
+ //wv1.v = &(v[k+1]);\r
+ //wv2.v = &(d->v[k+1]);\r
+ a_vec_k=this.m[k];\r
+ vec.setNewArray(a_vec_k,clm);//vec=this.getRowVec(k);\r
+// vec_array=vec.getArray();\r
+ NyARException.trap("未チェックパス"); \r
+ t = vec.vecInnerproduct(d,k+1)/ 2;\r
+ for(int i = dim-1; i > k; i-- ) {\r
+ NyARException.trap("未チェックパス"); \r
+ p = a_vec_k[i];//p = v.get(i);//p = v[i];\r
+ d_vec[i]-=t*p;q=d_vec[i];//d.v[i]-=t*p;q=d.v[i];//q = d->v[i] -= t*p;\r
+ for(int j = i; j < dim; j++ ){\r
+ NyARException.trap("未チェックパス"); \r
+ this.m[i][j]-=p*(d_vec[j] + q*a_vec_k[j]);//a.m[i][j]-=p*(d.v[j] + q*vec.v[j]);//a->m[i*dim+j] -= p*(d->v[j]) + q*v[j];\r
+ }\r
+ }\r
+ }\r
+\r
+ if( dim >= 2) {\r
+ d_vec[dim-2]=this.m[dim-2][dim-2];//d.v[dim-2]=a.m[dim-2][dim-2];//d->v[dim-2] = a->m[(dim-2)*dim+(dim-2)];\r
+ e_vec[dim-2+i_e_start]=this.m[dim-2][dim-1];//e.v[dim-2+i_e_start]=a.m[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];\r
+ }\r
+\r
+ if( dim >= 1 ){\r
+ d_vec[dim-1]=this.m[dim-1][dim-1];//d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] = a->m[(dim-1)*dim+(dim-1)];\r
+ }\r
+ NyARVec vec2=this.wk_vecTridiagonalize_vec2;\r
+ for(int k = dim-1; k >= 0; k--) {\r
+ a_vec_k=this.m[k];\r
+ vec.setNewArray(a_vec_k,clm);//vec=this.getRowVec(k);//v = a.getPointer(k*dim);//v = &(a->m[k*dim]);\r
+ if( k < dim-2 ) {\r
+ for(int i = k+1; i < dim; i++ ){\r
+ //wv1.clm = wv2.clm = dim-k-1;\r
+ //wv1.v = &(v[k+1]);\r
+ //wv2.v = &(a->m[i*dim+k+1]);\r
+ vec2.setNewArray(this.m[i],clm);//vec2=this.getRowVec(i);\r
+ \r
+ t = vec.vecInnerproduct(vec2,k+1);\r
+ for(int j = k+1; j < dim; j++ ){\r
+ NyARException.trap("未チェックパス"); \r
+ this.m[i][j]-=t*a_vec_k[j];//a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j] -= t * v[j];\r
+ }\r
+ }\r
+ }\r
+ for(int i = 0; i < dim; i++ ){\r
+ a_vec_k[i]=0.0;//v.set(i,0.0);//v[i] = 0.0;\r
+ }\r
+ a_vec_k[k]=1;//v.set(k,1);//v[k] = 1;\r
+ }\r
+ return;\r
+ } \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+\r
+import java.io.*;\r
+import java.nio.*;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.util.DoubleValue;\r
+\r
+/*typedef struct {\r
+ int xsize, ysize;\r
+ double mat[3][4];\r
+ double dist_factor[4];\r
+} ARParam;*/\r
+public class NyARParam{\r
+ private static final int SIZE_OF_PARAM_SET=4+4+(3*4*8)+(4*8);\r
+ private static final int PD_LOOP = 3;\r
+ protected int xsize, ysize;\r
+ private double[] array34=new double[3*4];//Double2dArray mat=new Double2dArray(3,4);\r
+ private double[] dist_factor=new double[4];\r
+ public int getX()\r
+ {\r
+ return xsize;\r
+ }\r
+ public int getY()\r
+ {\r
+ return ysize;\r
+ }\r
+ public double[] getDistFactor()\r
+ {\r
+ return dist_factor;\r
+ }\r
+ /**\r
+ * パラメタを格納した[4x3]配列を返します。\r
+ * @return\r
+ */\r
+ public final double[] get34Array()\r
+ {\r
+ return array34;\r
+ }\r
+ /**\r
+ * ARToolKit標準ファイルから1個目の設定をロードする。\r
+ * @param i_filename\r
+ * @throws NyARException\r
+ */\r
+ public void loadFromARFile(String i_filename) throws NyARException\r
+ {\r
+ try {\r
+ loadFromARFile(new FileInputStream(i_filename));\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ }\r
+ public void loadFromARFile(InputStream i_stream) throws NyARException\r
+ {\r
+ try {\r
+ NyARParam new_inst[] = arParamLoad(i_stream, 1);\r
+ i_stream.close();\r
+ xsize = new_inst[0].xsize;\r
+ ysize = new_inst[0].ysize;\r
+ array34 = new_inst[0].array34;\r
+ dist_factor = new_inst[0].dist_factor;\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ }\r
+ /*static double dot( double a1, double a2, double a3,double b1, double b2, double b3 )*/\r
+ private final static double dot( double a1, double a2, double a3,double b1, double b2, double b3 )\r
+ {\r
+ return( a1 * b1 + a2 * b2 + a3 * b3 );\r
+ }\r
+ /* static double norm( double a, double b, double c )*/\r
+ private final static double norm( double a, double b, double c )\r
+ {\r
+ return Math.sqrt( a*a + b*b + c*c );\r
+ }\r
+ /**\r
+ * int arParamDecompMat( double source[3][4], double cpara[3][4], double trans[3][4] );\r
+ * 関数の置き換え\r
+ * Optimize STEP[754->665]\r
+ * @param o_cpara\r
+ * 戻り引数。3x4のマトリクスを指定すること。\r
+ * @param o_trans\r
+ * 戻り引数。3x4のマトリクスを指定すること。\r
+ * @return\r
+ */\r
+ public void decompMat(NyARMat o_cpara, NyARMat o_trans)\r
+ {\r
+ double[] source=array34;\r
+ double[] Cpara=new double[3*4];//double Cpara[3][4];\r
+ double rem1, rem2, rem3;\r
+ int i;\r
+ if(source[2*4+3]>= 0 ){//if( source[2][3] >= 0 ) {\r
+ //<Optimize>\r
+ //for(int r = 0; r < 3; r++ ){\r
+ // for(int c = 0; c < 4; c++ ){\r
+ // Cpara[r][c]=source[r][c];//Cpara[r][c] = source[r][c];\r
+ // }\r
+ //}\r
+ for(i=0;i<12;i++){\r
+ Cpara[i]=source[i];//Cpara[r][c] = source[r][c];\r
+ }\r
+ //</Optimize>\r
+ }else {\r
+ //<Optimize>\r
+ //for(int r = 0; r < 3; r++ ){\r
+ // for(int c = 0; c < 4; c++ ){\r
+ // Cpara[r][c]=-source[r][c];//Cpara[r][c] = -(source[r][c]);\r
+ // }\r
+ //}\r
+ for(i=0;i<12;i++){\r
+ Cpara[i]=source[i];//Cpara[r][c] = source[r][c];\r
+ }\r
+ //</Optimize>\r
+ }\r
+ \r
+ double[][] cpara=o_cpara.getArray();\r
+ double[][] trans=o_trans.getArray();\r
+ for(int r = 0; r < 3; r++ ){\r
+ for(int c = 0; c < 4; c++ ){\r
+ cpara[r][c]=0.0;//cpara[r][c] = 0.0;\r
+ }\r
+ }\r
+ cpara[2][2]=norm(Cpara[2*4+0],Cpara[2*4+1], Cpara[2*4+2]);//cpara[2][2] = norm( Cpara[2][0], Cpara[2][1], Cpara[2][2] );\r
+ trans[2][0]=Cpara[2*4+0] / cpara[2][2];//trans[2][0] = Cpara[2][0] / cpara[2][2];\r
+ trans[2][1]=Cpara[2*4+1]/ cpara[2][2];//trans[2][1] = Cpara[2][1] / cpara[2][2];\r
+ trans[2][2]=Cpara[2*4+2]/ cpara[2][2];//trans[2][2] = Cpara[2][2] / cpara[2][2];\r
+ trans[2][3]=Cpara[2*4+3] / cpara[2][2];//trans[2][3] = Cpara[2][3] / cpara[2][2];\r
+ \r
+ cpara[1][2]=dot(trans[2][0], trans[2][1], trans[2][2],Cpara[1*4+0], Cpara[1*4+1], Cpara[1*4+2]);//cpara[1][2] = dot( trans[2][0], trans[2][1], trans[2][2],Cpara[1][0], Cpara[1][1], Cpara[1][2] );\r
+ rem1=Cpara[1*4+0]- cpara[1][2] * trans[2][0];//rem1 = Cpara[1][0] - cpara[1][2] * trans[2][0];\r
+ rem2=Cpara[1*4+1] - cpara[1][2] * trans[2][1];//rem2 = Cpara[1][1] - cpara[1][2] * trans[2][1];\r
+ rem3=Cpara[1*4+2] - cpara[1][2] * trans[2][2];//rem3 = Cpara[1][2] - cpara[1][2] * trans[2][2];\r
+ cpara[1][1]=norm(rem1, rem2, rem3 );//cpara[1][1] = norm( rem1, rem2, rem3 );\r
+ trans[1][0]= rem1/cpara[1][1];//trans[1][0] = rem1 / cpara[1][1];\r
+ trans[1][1]=rem2/cpara[1][1];//trans[1][1] = rem2 / cpara[1][1];\r
+ trans[1][2]=rem3 / cpara[1][1];//trans[1][2] = rem3 / cpara[1][1];\r
+ \r
+ cpara[0][2]=dot(trans[2][0],trans[2][1], trans[2][2],Cpara[0*4+0], Cpara[0*4+1], Cpara[0*4+2] );//cpara[0][2] = dot( trans[2][0], trans[2][1], trans[2][2],Cpara[0][0], Cpara[0][1], Cpara[0][2] );\r
+ cpara[0][1]=dot(trans[1][0],trans[1][1], trans[1][2],Cpara[0*4+0], Cpara[0*4+1], Cpara[0*4+2]);//cpara[0][1] = dot( trans[1][0], trans[1][1], trans[1][2],Cpara[0][0], Cpara[0][1], Cpara[0][2] );\r
+ rem1=Cpara[0*4+0]- cpara[0][1]*trans[1][0] - cpara[0][2]*trans[2][0];//rem1 = Cpara[0][0] - cpara[0][1]*trans[1][0] - cpara[0][2]*trans[2][0];\r
+ rem2 = Cpara[0*4+1] - cpara[0][1]*trans[1][1] - cpara[0][2]*trans[2][1];//rem2 = Cpara[0][1] - cpara[0][1]*trans[1][1] - cpara[0][2]*trans[2][1];\r
+ rem3 = Cpara[0*4+2] - cpara[0][1]*trans[1][2] - cpara[0][2]*trans[2][2];//rem3 = Cpara[0][2] - cpara[0][1]*trans[1][2] - cpara[0][2]*trans[2][2];\r
+ cpara[0][0]=norm(rem1, rem2, rem3);//cpara[0][0] = norm( rem1, rem2, rem3 );\r
+ trans[0][0]=rem1 / cpara[0][0];//trans[0][0] = rem1 / cpara[0][0];\r
+ trans[0][1]= rem2 / cpara[0][0];//trans[0][1] = rem2 / cpara[0][0];\r
+ trans[0][2]= rem3 / cpara[0][0];//trans[0][2] = rem3 / cpara[0][0];\r
+ \r
+ trans[1][3]=(Cpara[1*4+3] - cpara[1][2]*trans[2][3]) / cpara[1][1];//trans[1][3] = (Cpara[1][3] - cpara[1][2]*trans[2][3]) / cpara[1][1];\r
+ trans[0][3]=(Cpara[0*4+3] - cpara[0][1]*trans[1][3]- cpara[0][2]*trans[2][3]) / cpara[0][0];//trans[0][3] = (Cpara[0][3] - cpara[0][1]*trans[1][3]- cpara[0][2]*trans[2][3]) / cpara[0][0];\r
+ \r
+ for(int r = 0; r < 3; r++ ){\r
+ for(int c = 0; c < 3; c++ ){\r
+ cpara[r][c]/=cpara[2][2];//cpara[r][c] /= cpara[2][2];\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /*int arParamDisp( ARParam *param );*/\r
+ public int paramDisp()\r
+ {\r
+ System.out.println("--------------------------------------");//printf("--------------------------------------\n");\r
+ System.out.print("SIZE = "+xsize+", "+ysize);//printf("SIZE = %d, %d\n", param->xsize, param->ysize);\r
+ System.out.println("Distortion factor = "+dist_factor[0]+" "+dist_factor[1]+" "+dist_factor[2]+" "+dist_factor[3]);//printf("Distortion factor = %f %f %f %f\n", param->dist_factor[0],param->dist_factor[1], param->dist_factor[2], param->dist_factor[3] );\r
+ for(int j = 0; j < 3; j++ ) {//for(j = 0; j < 3; j++ ) {\r
+ for(int i = 0; i < 4; i++ ){\r
+ System.out.print(array34[j*4+i]+" ");//printf("%7.5f ", param->mat[j][i]);\r
+ }\r
+ System.out.println();// printf("\n");\r
+ }//}\r
+ System.out.println("--------------------------------------");//printf("--------------------------------------\n");\r
+ return 0;\r
+ }\r
+// /*int arParamDecomp( ARParam *source, ARParam *icpara, double trans[3][4] );*/\r
+// private static int arParamDecomp( NyARParam source, NyARParam icpara, double[][] trans)\r
+// {\r
+// icpara.xsize = source.xsize;//icpara->xsize = source->xsize;\r
+// icpara.ysize = source.ysize;//icpara->ysize = source->ysize;\r
+// icpara.dist_factor[0] = source.dist_factor[0];//icpara->dist_factor[0] = source->dist_factor[0];\r
+// icpara.dist_factor[1] = source.dist_factor[1];// icpara->dist_factor[1] = source->dist_factor[1];\r
+// icpara.dist_factor[2] = source.dist_factor[2];//icpara->dist_factor[2] = source->dist_factor[2];\r
+// icpara.dist_factor[3] = source.dist_factor[3];//icpara->dist_factor[3] = source->dist_factor[3];\r
+// return arParamDecompMat(source.mat, icpara.mat, trans );\r
+// }\r
+ /**\r
+ * int arParamChangeSize( ARParam *source, int xsize, int ysize, ARParam *newparam );\r
+ * 関数の代替関数\r
+ * サイズプロパティをi_xsize,i_ysizeに変更します。\r
+ * @param xsize\r
+ * @param ysize\r
+ * @param newparam\r
+ * @return\r
+ * \r
+ */\r
+ public void changeSize(int i_xsize, int i_ysize)\r
+ {\r
+ double scale; \r
+ scale = (double)i_xsize / (double)(xsize);//scale = (double)xsize / (double)(source->xsize);\r
+ \r
+ for(int i = 0; i < 4; i++ ) {\r
+ array34[0*4+i]=array34[0*4+i]*scale;//newparam->mat[0][i] = source->mat[0][i] * scale;\r
+ array34[1*4+i]=array34[1*4+i]*scale;//newparam->mat[1][i] = source->mat[1][i] * scale;\r
+ array34[2*4+i]=array34[2*4+i];//newparam->mat[2][i] = source->mat[2][i];\r
+ }\r
+ \r
+ dist_factor[0] = dist_factor[0] * scale;//newparam->dist_factor[0] = source->dist_factor[0] * scale;\r
+ dist_factor[1] = dist_factor[1] * scale;//newparam->dist_factor[1] = source->dist_factor[1] * scale;\r
+ dist_factor[2] = dist_factor[2] / (scale*scale);//newparam->dist_factor[2] = source->dist_factor[2] / (scale*scale);\r
+ dist_factor[3] = dist_factor[3];//newparam->dist_factor[3] = source->dist_factor[3];\r
+ \r
+ xsize = i_xsize;//newparam->xsize = xsize;\r
+ ysize = i_ysize;//newparam->ysize = ysize;\r
+ }\r
+ /**\r
+ * int arParamIdeal2Observ( const double dist_factor[4], const double ix, const double iy,double *ox, double *oy )\r
+ * 関数の代替関数\r
+ * @param ix\r
+ * @param iy\r
+ * @param ox\r
+ * @param oy\r
+ */\r
+ public void ideal2Observ(double ix,double iy,DoubleValue ox, DoubleValue oy)\r
+ {\r
+\r
+ double x, y, d;\r
+ final double d0,d1,d3;\r
+ final double df[]=this.dist_factor;\r
+ d0=df[0];\r
+ d1=df[1];\r
+ d3=df[3];\r
+ x = (ix - d0) * d3;\r
+ y = (iy - d1) * d3;\r
+ if( x == 0.0 && y == 0.0 ) {\r
+ ox.value=d0;\r
+ oy.value=d1;\r
+ }else{\r
+ d = 1.0 - df[2]/100000000.0 * (x*x+y*y);\r
+ ox.value=x * d + d0;\r
+ oy.value=y * d + d1;\r
+ }\r
+ }\r
+ /**\r
+ * ideal2Observをまとめて実行します。\r
+ * @param i_in\r
+ * double[][2]\r
+ * @param o_out\r
+ * double[][2]\r
+ */\r
+ public void ideal2ObservBatch(double[][] i_in,double[][] o_out,int i_size)\r
+ {\r
+\r
+ double x, y, d;\r
+ final double d0,d1,d3,d2_w;\r
+ final double df[]=this.dist_factor;\r
+ d0=df[0];\r
+ d1=df[1];\r
+ d3=df[3];\r
+ d2_w=df[2]/100000000.0;\r
+ for(int i=0;i<i_size;i++){\r
+ x = (i_in[i][0] - d0) * d3;\r
+ y = (i_in[i][1] - d1) * d3;\r
+ if( x == 0.0 && y == 0.0 ) {\r
+ o_out[i][0]=d0;\r
+ o_out[i][1]=d1;\r
+ }else{\r
+ d = 1.0 - d2_w * (x*x+y*y);\r
+ o_out[i][0]=x * d + d0;\r
+ o_out[i][1]=y * d + d1;\r
+ }\r
+ }\r
+ return;\r
+ } \r
+ \r
+ \r
+ \r
+ \r
+ /**\r
+ * int arParamObserv2Ideal( const double dist_factor[4], const double ox, const double oy,double *ix, double *iy );\r
+ * \r
+ * @param ox\r
+ * @param oy\r
+ * @param ix\r
+ * @param iy\r
+ * @return\r
+ */\r
+ public int observ2Ideal(double ox,double oy,DoubleValue ix,DoubleValue iy)\r
+ {\r
+ double z02, z0, p, q, z, px, py,opttmp_1;\r
+ final double d0,d1,d3;\r
+ final double df[]=this.dist_factor;\r
+ d0=df[0];\r
+ d1=df[1];\r
+ \r
+ px = ox - d0;\r
+ py = oy - d1;\r
+ p = df[2]/100000000.0;\r
+ z02 = px*px+py*py;\r
+ q = z0 = Math.sqrt(z02);//Optimize//q = z0 = Math.sqrt(px*px+ py*py);\r
+ \r
+ for(int i = 1; ; i++ ) {\r
+ if( z0 != 0.0 ) {\r
+ //Optimize opttmp_1\r
+ opttmp_1=p*z02;\r
+ z = z0 - ((1.0 - opttmp_1)*z0 - q) / (1.0 - 3.0*opttmp_1);\r
+ px = px*z/z0;\r
+ py = py*z/z0;\r
+ }else {\r
+ px = 0.0;\r
+ py = 0.0;\r
+ break;\r
+ }\r
+ if( i == PD_LOOP ){\r
+ break;\r
+ }\r
+ z02 = px*px+ py*py;\r
+ z0 = Math.sqrt(z02);//Optimize//z0 = Math.sqrt(px*px+ py*py);\r
+ }\r
+ d3=df[3];\r
+ ix.value=px / d3 + d0;\r
+ iy.value=py / d3 + d1;\r
+ return 0;\r
+ }\r
+ /**\r
+ * 指定範囲のobserv2Idealをまとめて実行して、結果をo_idealに格納します。\r
+ * @param i_x_coord\r
+ * @param i_y_coord\r
+ * @param i_start\r
+ * coord開始点\r
+ * @param i_num\r
+ * 計算数\r
+ * @param o_ideal\r
+ * 出力バッファ[i_num][2]であること。\r
+ */\r
+ public void observ2IdealBatch(int[] i_x_coord,int[] i_y_coord,int i_start,int i_num,double[][] o_ideal)\r
+ {\r
+ double z02, z0,q, z, px, py,opttmp_1;\r
+ final double df[]=this.dist_factor;\r
+ final double d0=df[0];\r
+ final double d1=df[1];\r
+ final double d3=df[3];\r
+ final double p = df[2]/100000000.0;\r
+ for(int j = 0; j < i_num; j++ ){\r
+\r
+ px = i_x_coord[i_start+j] - d0;\r
+ py = i_y_coord[i_start+j] - d1;\r
+\r
+ z02 = px*px+py*py;\r
+ q = z0 = Math.sqrt(z02);//Optimize//q = z0 = Math.sqrt(px*px+ py*py);\r
+\r
+ for(int i = 1; ; i++ ) {\r
+ if( z0 != 0.0 ) {\r
+ //Optimize opttmp_1\r
+ opttmp_1=p*z02;\r
+ z = z0 - ((1.0 - opttmp_1)*z0 - q) / (1.0 - 3.0*opttmp_1);\r
+ px = px*z/z0;\r
+ py = py*z/z0;\r
+ }else {\r
+ px = 0.0;\r
+ py = 0.0;\r
+ break;\r
+ }\r
+ if( i == PD_LOOP ){\r
+ break;\r
+ }\r
+ z02 = px*px+ py*py;\r
+ z0 = Math.sqrt(z02);//Optimize//z0 = Math.sqrt(px*px+ py*py);\r
+ }\r
+ o_ideal[j][0]=px / d3 + d0;\r
+ o_ideal[j][1]=py / d3 + d1;\r
+ } \r
+ } \r
+ \r
+ \r
+ \r
+ \r
+ /**\r
+ * int arParamLoad( const char *filename, int num, ARParam *param, ...);\r
+ * i_streamの入力ストリームからi_num個の設定を読み込み、パラメタを配列にして返します。\r
+ * @param filename\r
+ * @param num\r
+ * @param param\r
+ * @return\r
+ * 設定を格納した配列を返します。\r
+ * @throws Exception\r
+ * i_num個の設定が読み出せない場合、JartkExceptionを発生します。\r
+ */\r
+ private static NyARParam[] arParamLoad(InputStream i_stream, int i_num) throws NyARException\r
+ {\r
+ try{\r
+ int read_size=SIZE_OF_PARAM_SET*i_num;\r
+ byte[] buf=new byte[read_size];\r
+ i_stream.read(buf);\r
+ //返却配列を確保\r
+ NyARParam[] result=new NyARParam[i_num];\r
+ \r
+ //バッファを加工\r
+ ByteBuffer bb = ByteBuffer.wrap(buf);\r
+ bb.order(ByteOrder.BIG_ENDIAN);\r
+ \r
+ //固定回数パースして配列に格納\r
+ for(int i=0;i<i_num;i++){\r
+ NyARParam new_param=new NyARParam();;\r
+ new_param.xsize=bb.getInt();\r
+ new_param.ysize=bb.getInt();\r
+ for(int i2=0;i2<3;i2++){\r
+ for(int i3=0;i3<4;i3++){\r
+ new_param.array34[i2*4+i3]=bb.getDouble();\r
+ }\r
+ }\r
+ for(int i2=0;i2<4;i2++){\r
+ new_param.dist_factor[i2]=bb.getDouble();\r
+ }\r
+ result[i]=new_param;\r
+ }\r
+ return result;\r
+ }catch(Exception e){\r
+ throw new NyARException(e);\r
+ }\r
+ }\r
+ public static int arParamSave(String filename,int num, NyARParam param[]) throws Exception\r
+ {\r
+ NyARException.trap("未チェックの関数");\r
+ byte buf[]=new byte[SIZE_OF_PARAM_SET*param.length];\r
+ //バッファをラップ\r
+ ByteBuffer bb = ByteBuffer.wrap(buf);\r
+ bb.order(ByteOrder.BIG_ENDIAN);\r
+\r
+ //書き込み\r
+ for(int i=0;i<param.length;i++){\r
+ bb.putInt(param[i].xsize);\r
+ bb.putInt(param[i].ysize);\r
+ for(int i2=0;i2<3;i2++){\r
+ for(int i3=0;i3<4;i3++){\r
+ bb.putDouble(param[i].array34[i2*4+i3]);\r
+ }\r
+ }\r
+ for(int i2=0;i2<4;i2++){\r
+ bb.putDouble(param[i].dist_factor[i2]);\r
+ }\r
+ }\r
+ //ファイルに保存\r
+ FileOutputStream fs=new FileOutputStream(filename);\r
+ fs.write(buf);\r
+ fs.close();\r
+\r
+ return 0;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * ARMarkerInfoに相当するクラス。 スクエア情報を保持します。\r
+ * \r
+ */\r
+public class NyARSquare extends NyARMarker {\r
+ // private NyARMarker marker;\r
+ // public int area;\r
+ // public double[] pos;\r
+ public double[][] line = new double[4][3]; // double[4][3]\r
+ public double[][] sqvertex = new double[4][2];// double[4][2];\r
+\r
+ public NyARSquare() {\r
+ super();\r
+ }\r
+\r
+ private final NyARMat wk_getLine_input = new NyARMat(1, 2);\r
+ private final NyARMat wk_getLine_evec = new NyARMat(2, 2);\r
+ private final NyARVec wk_getLine_ev = new NyARVec(2);\r
+ private final NyARVec wk_getLine_mean = new NyARVec(2);\r
+\r
+ /**\r
+ * arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[],\r
+ * double line[4][3], double v[4][2]) arGetLine2(int x_coord[], int\r
+ * y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2],\r
+ * double *dist_factor) の2関数の合成品です。 格納しているマーカー情報に対して、GetLineの計算を行い、結果を返します。\r
+ * Optimize:STEP[424->391]\r
+ * \r
+ * @param i_cparam\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public boolean getLine(NyARParam i_cparam) throws NyARException {\r
+ double w1;\r
+ int st, ed, n;\r
+ int i;\r
+\r
+ final double[][] l_sqvertex = this.sqvertex;\r
+ final double[][] l_line = this.line;\r
+ final int[] l_mkvertex = this.mkvertex;\r
+ final int[] l_x_coord = this.x_coord;\r
+ final int[] l_y_coord = this.y_coord;\r
+ final NyARVec ev = this.wk_getLine_ev; // matrixPCAの戻り値を受け取る\r
+ final NyARVec mean = this.wk_getLine_mean;// matrixPCAの戻り値を受け取る\r
+ final double[] mean_array = mean.getArray();\r
+ double[] l_line_i, l_line_2;\r
+\r
+ NyARMat input = this.wk_getLine_input;// 次処理で初期化される。\r
+ NyARMat evec = this.wk_getLine_evec;// アウトパラメータを受け取るから初期化不要//new\r
+ // NyARMat(2,2);\r
+ double[][] evec_array = evec.getArray();\r
+ for (i = 0; i < 4; i++) {\r
+ w1 = (double) (l_mkvertex[i + 1] - l_mkvertex[i] + 1) * 0.05 + 0.5;\r
+ st = (int) (l_mkvertex[i] + w1);\r
+ ed = (int) (l_mkvertex[i + 1] - w1);\r
+ n = ed - st + 1;\r
+ if (n < 2) {\r
+ // nが2以下でmatrix.PCAを計算することはできないので、エラーにしておく。\r
+ return false;// throw new NyARException();\r
+ }\r
+ input.realloc(n, 2);\r
+ // バッチ取得\r
+ i_cparam.observ2IdealBatch(l_x_coord, l_y_coord, st, n, input\r
+ .getArray());\r
+ // for( j = 0; j < n; j++ ) {\r
+ // i_cparam.observ2Ideal(l_x_coord[st+j],\r
+ // l_y_coord[st+j],dv1,dv2);//arParamObserv2Ideal( dist_factor,\r
+ // x_coord[st+j], y_coord[st+j],&(input->m[j*2+0]),\r
+ // &(input->m[j*2+1]) );\r
+ // in_array[j][0]=dv1.value;\r
+ // in_array[j][1]=dv2.value;\r
+ // }\r
+ input.matrixPCA(evec, ev, mean);\r
+ l_line_i = l_line[i];\r
+ l_line_i[0] = evec_array[0][1];// line[i][0] = evec->m[1];\r
+ l_line_i[1] = -evec_array[0][0];// line[i][1] = -evec->m[0];\r
+ l_line_i[2] = -(l_line_i[0] * mean_array[0] + l_line_i[1]\r
+ * mean_array[1]);// line[i][2] = -(line[i][0]*mean->v[0]\r
+ // + line[i][1]*mean->v[1]);\r
+ }\r
+\r
+ for (i = 0; i < 4; i++) {\r
+ l_line_i = l_line[i];\r
+ l_line_2 = l_line[(i + 3) % 4];\r
+ w1 = l_line_2[0] * l_line_i[1] - l_line_i[0] * l_line_2[1];\r
+ if (w1 == 0.0) {\r
+ return false;\r
+ }\r
+ l_sqvertex[i][0] = (l_line_2[1] * l_line_i[2] - l_line_i[1]\r
+ * l_line_2[2])\r
+ / w1;\r
+ l_sqvertex[i][1] = (l_line_i[0] * l_line_2[2] - l_line_2[0]\r
+ * l_line_i[2])\r
+ / w1;\r
+ }\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+public class NyARSquareList extends NyARMarkerList\r
+{\r
+ private final NyARSquare[] square_array;\r
+ private int square_array_num;\r
+ public NyARSquareList(int i_number_of_holder)\r
+ {\r
+ super(new NyARSquare[i_number_of_holder]);\r
+ //マーカーホルダに実体を割り当てる。\r
+ for(int i=0;i<this.marker_holder.length;i++){\r
+ this.marker_holder[i]=new NyARSquare();\r
+ }\r
+ this.square_array=new NyARSquare[i_number_of_holder];\r
+ this.square_array_num=0;\r
+ }\r
+ /**\r
+ * マーカーアレイをフィルタして、square_arrayを更新する。\r
+ * [[この関数はマーカー検出処理と密接に関係する関数です。\r
+ * NyARDetectSquareクラス以外から呼び出さないで下さい。]]\r
+ */\r
+ public final void updateSquareArray(NyARParam i_param) throws NyARException\r
+ {\r
+ NyARSquare square;\r
+ int j=0;\r
+ for (int i = 0; i <this.marker_array_num; i++){\r
+// double[][] line =new double[4][3];\r
+// double[][] vertex =new double[4][2];\r
+ //NyARMarker marker=detect.getMarker(i);\r
+ square=(NyARSquare)this.marker_array[i];\r
+ //・・・線の検出??\r
+ if (!square.getLine(i_param))\r
+ {\r
+ continue;\r
+ }\r
+ this.square_array[j]=square;\r
+//ここで計算するのは良くないと思うんだ \r
+// marker_infoL[j].id = id.get();\r
+// marker_infoL[j].dir = dir.get();\r
+// marker_infoL[j].cf = cf.get(); \r
+ j++;\r
+ }\r
+ this.square_array_num=j;\r
+ }\r
+ /**\r
+ * スクエア配列に格納されている要素数を返します。\r
+ * @return\r
+ */\r
+ public final int getSquareNum()\r
+ {\r
+ return this.square_array_num;\r
+ }\r
+ /**\r
+ * スクエア配列の要素を返します。\r
+ * スクエア配列はマーカーアレイをさらにフィルタした結果です。\r
+ * マーカーアレイの部分集合になっている点に注意してください。\r
+ * @param i_index\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public final NyARSquare getSquare(int i_index) throws NyARException\r
+ {\r
+ if(i_index>=this.square_array_num){\r
+ throw new NyARException();\r
+ }\r
+ return this.square_array[i_index];\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+\r
+\r
+\r
+import jp.nyatla.nyartoolkit.*;\r
+\r
+\r
+/**\r
+ * This class calculates ARMatrix from square information.\r
+ * --\r
+ * 変換行列を計算するクラス。\r
+ *\r
+ */\r
+public interface NyARTransMat{\r
+ public void setCenter(double i_x,double i_y);\r
+ public double transMat(NyARSquare i_square,int i_direction, double i_width,NyARTransMatResult o_result)throws NyARException;\r
+ public double transMatContinue(NyARSquare i_square,int i_direction, double i_width,NyARTransMatResult io_result_conv)throws NyARException;\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.*;\r
+/**\r
+ * NyARTransMat戻り値専用のNyARMat\r
+ *\r
+ */\r
+public class NyARTransMatResult extends NyARMat\r
+{\r
+ private boolean has_value=false;\r
+ public NyARTransMatResult()\r
+ {\r
+ super(3,4);\r
+ }\r
+ /**\r
+ * この関数は使えません。\r
+ * @param i_row\r
+ * @param i_clm\r
+ * @throws NyARException\r
+ */\r
+ public NyARTransMatResult(int i_row,int i_clm) throws NyARException\r
+ {\r
+ super();//ここで例外発生\r
+ }\r
+ /**\r
+ * パラメータで変換行列を更新します。\r
+ * @param i_rot\r
+ * @param i_off\r
+ * @param i_trans\r
+ */\r
+ public void updateMatrixValue(NyARTransRot i_rot,double[] i_off,double[] i_trans)\r
+ {\r
+ double[] pa;\r
+ double[] rot=i_rot.getArray();\r
+\r
+ pa=this.m[0];\r
+ pa[0] = rot[0*3+0];\r
+ pa[1] = rot[0*3+1];\r
+ pa[2] = rot[0*3+2];\r
+ pa[3] = rot[0*3+0]*i_off[0] + rot[0*3+1]*i_off[1] + rot[0*3+2]*i_off[2] + i_trans[0];\r
+\r
+ pa=this.m[1];\r
+ pa[0] = rot[1*3+0];\r
+ pa[1] = rot[1*3+1];\r
+ pa[2] = rot[1*3+2];\r
+ pa[3] = rot[1*3+0]*i_off[0] + rot[1*3+1]*i_off[1] + rot[1*3+2]*i_off[2] + i_trans[1];\r
+\r
+ pa=this.m[2];\r
+ pa[0] = rot[2*3+0];\r
+ pa[1] = rot[2*3+1];\r
+ pa[2] = rot[2*3+2];\r
+ pa[3] = rot[2*3+0]*i_off[0] + rot[2*3+1]*i_off[1] + rot[2*3+2]*i_off[2] + i_trans[2];\r
+\r
+\r
+ this.has_value=true;\r
+ return;\r
+ }\r
+ public void copyFrom(NyARTransMatResult i_from) throws NyARException\r
+ {\r
+ super.copyFrom(i_from);\r
+ this.has_value=i_from.has_value;\r
+ }\r
+ public boolean hasValue()\r
+ {\r
+ return this.has_value;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.util.DoubleValue;\r
+\r
+public class NyARTransMat_O1 implements NyARTransMat {\r
+ private final static int AR_FITTING_TO_IDEAL = 0;// #define\r
+ // AR_FITTING_TO_IDEAL 0\r
+ private final static int AR_FITTING_TO_INPUT = 1;// #define\r
+ // AR_FITTING_TO_INPUT 1\r
+ private final static int arFittingMode = AR_FITTING_TO_INPUT;\r
+\r
+ private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define\r
+ // AR_GET_TRANS_MAT_MAX_LOOP_COUNT\r
+ // 5\r
+ private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define\r
+ // AR_GET_TRANS_MAT_MAX_FIT_ERROR\r
+ // 1.0\r
+ private final static double AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR = 1.0;\r
+ private final static int P_MAX = 10;// 頂点の数(4で十分だけどなんとなく10)//#define P_MAX\r
+ // 500\r
+ private final static int NUMBER_OF_VERTEX = 4;// 処理対象の頂点数\r
+ private final NyARTransRot transrot;\r
+ private final double[] center = { 0.0, 0.0 };\r
+ private final NyARParam param;\r
+\r
+ // private final NyARMat result_mat=new NyARMat(3,4);\r
+ public NyARTransMat_O1(NyARParam i_param) throws NyARException {\r
+ param = i_param;\r
+ transrot = new NyARTransRot_O3(i_param, NUMBER_OF_VERTEX);\r
+\r
+ }\r
+\r
+ public void setCenter(double i_x, double i_y) {\r
+ center[0] = i_x;\r
+ center[1] = i_x;\r
+ }\r
+\r
+ // public NyARMat getTransformationMatrix()\r
+ // {\r
+ // return result_mat;\r
+ // }\r
+\r
+ private final double[][] wk_transMat_pos3d = new double[P_MAX][3];// pos3d[P_MAX][3];\r
+ private final double[][] wk_transMat_ppos2d = new double[4][2];\r
+ private final double[][] wk_transMat_ppos3d = new double[4][2];\r
+ private final double[] wk_transMat_off = new double[3];\r
+\r
+ /**\r
+ * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double\r
+ * width, double conv[3][4] ) 関数の置き換え。 保持している変換行列を更新する。\r
+ * \r
+ * @param square\r
+ * 計算対象のNyARSquareオブジェクト\r
+ * @param i_direction\r
+ * マーカーの方向\r
+ * @param i_width\r
+ * マーカーのサイズ(mm)\r
+ * @param o_result_conv\r
+ * 変換行列を受け取るオブジェクトを指定します。\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double transMat(NyARSquare square, int i_direction, double i_width,\r
+ NyARTransMatResult o_result_conv) throws NyARException {\r
+ double[][] ppos2d = wk_transMat_ppos2d;\r
+ double[][] ppos3d = wk_transMat_ppos3d;\r
+ double[] off = wk_transMat_off;\r
+ double[][] pos3d = wk_transMat_pos3d;\r
+ int dir;\r
+ double err = -1;\r
+\r
+ transrot.initRot(square, i_direction);\r
+\r
+ dir = i_direction;\r
+ ppos2d[0][0] = square.sqvertex[(4 - dir) % 4][0];\r
+ ppos2d[0][1] = square.sqvertex[(4 - dir) % 4][1];\r
+ ppos2d[1][0] = square.sqvertex[(5 - dir) % 4][0];\r
+ ppos2d[1][1] = square.sqvertex[(5 - dir) % 4][1];\r
+ ppos2d[2][0] = square.sqvertex[(6 - dir) % 4][0];\r
+ ppos2d[2][1] = square.sqvertex[(6 - dir) % 4][1];\r
+ ppos2d[3][0] = square.sqvertex[(7 - dir) % 4][0];\r
+ ppos2d[3][1] = square.sqvertex[(7 - dir) % 4][1];\r
+ ppos3d[0][0] = center[0] - i_width / 2.0;\r
+ ppos3d[0][1] = center[1] + i_width / 2.0;\r
+ ppos3d[1][0] = center[0] + i_width / 2.0;\r
+ ppos3d[1][1] = center[1] + i_width / 2.0;\r
+ ppos3d[2][0] = center[0] + i_width / 2.0;\r
+ ppos3d[2][1] = center[1] - i_width / 2.0;\r
+ ppos3d[3][0] = center[0] - i_width / 2.0;\r
+ ppos3d[3][1] = center[1] - i_width / 2.0;\r
+\r
+ // arGetTransMat3の前段処理(pos3dとoffを初期化)\r
+ arGetTransMat3_initPos3d(ppos3d, pos3d, off);\r
+\r
+ for (int i = 0; i < AR_GET_TRANS_MAT_MAX_LOOP_COUNT; i++) {\r
+ err = arGetTransMat3(ppos2d, pos3d, off, o_result_conv);\r
+ if (err < AR_GET_TRANS_MAT_MAX_FIT_ERROR) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ return err;\r
+ }\r
+\r
+ /**\r
+ * transMatContinue用のワーク\r
+ */\r
+ private final NyARTransMatResult wk_transMatContinue_result = new NyARTransMatResult();\r
+\r
+ /**\r
+ * double arGetTransMatCont( ARMarkerInfo *marker_info, double\r
+ * prev_conv[3][4],double center[2], double width, double conv[3][4] )\r
+ * \r
+ * @param i_square\r
+ * @param i_direction\r
+ * マーカーの方位を指定する。\r
+ * @param i_width\r
+ * @param io_result_conv\r
+ * 計算履歴を持つNyARTransMatResultオブジェクトを指定する。\r
+ * 履歴を持たない場合は、transMatと同じ処理を行う。\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double transMatContinue(NyARSquare i_square, int i_direction,\r
+ double i_width, NyARTransMatResult io_result_conv)\r
+ throws NyARException {\r
+ // io_result_convが初期値なら、transMatで計算する。\r
+ if (!io_result_conv.hasValue()) {\r
+ return this\r
+ .transMat(i_square, i_direction, i_width, io_result_conv);\r
+ }\r
+\r
+ double err1, err2;\r
+ int i, dir;\r
+ double[][] ppos2d = wk_transMat_ppos2d;\r
+ double[][] ppos3d = wk_transMat_ppos3d;\r
+ double[] off = wk_transMat_off;\r
+ double[][] pos3d = wk_transMat_pos3d;\r
+\r
+ // arGetTransMatContSub計算部分\r
+ transrot.initRotByPrevResult(io_result_conv);\r
+\r
+ dir = i_direction;\r
+ ppos2d[0][0] = i_square.sqvertex[(4 - dir) % 4][0];\r
+ ppos2d[0][1] = i_square.sqvertex[(4 - dir) % 4][1];\r
+ ppos2d[1][0] = i_square.sqvertex[(5 - dir) % 4][0];\r
+ ppos2d[1][1] = i_square.sqvertex[(5 - dir) % 4][1];\r
+ ppos2d[2][0] = i_square.sqvertex[(6 - dir) % 4][0];\r
+ ppos2d[2][1] = i_square.sqvertex[(6 - dir) % 4][1];\r
+ ppos2d[3][0] = i_square.sqvertex[(7 - dir) % 4][0];\r
+ ppos2d[3][1] = i_square.sqvertex[(7 - dir) % 4][1];\r
+ ppos3d[0][0] = center[0] - i_width / 2.0;\r
+ ppos3d[0][1] = center[1] + i_width / 2.0;\r
+ ppos3d[1][0] = center[0] + i_width / 2.0;\r
+ ppos3d[1][1] = center[1] + i_width / 2.0;\r
+ ppos3d[2][0] = center[0] + i_width / 2.0;\r
+ ppos3d[2][1] = center[1] - i_width / 2.0;\r
+ ppos3d[3][0] = center[0] - i_width / 2.0;\r
+ ppos3d[3][1] = center[1] - i_width / 2.0;\r
+\r
+ // arGetTransMat3の前段処理(pos3dとoffを初期化)\r
+ arGetTransMat3_initPos3d(ppos3d, pos3d, off);\r
+\r
+ err1 = err2 = -1;\r
+ for (i = 0; i < AR_GET_TRANS_MAT_MAX_LOOP_COUNT; i++) {\r
+ err1 = arGetTransMat3(ppos2d, pos3d, off, io_result_conv);\r
+ if (err1 < AR_GET_TRANS_MAT_MAX_FIT_ERROR) {\r
+ // 十分な精度を達成できたらブレーク\r
+ break;\r
+ }\r
+ }\r
+\r
+ // エラー値が許容範囲でなければTransMatをやり直し\r
+ if (err1 > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {\r
+ NyARTransMatResult result2 = this.wk_transMatContinue_result;\r
+ // transMatを実行\r
+ transrot.initRot(i_square, i_direction);\r
+ err2 = transMat(i_square, i_direction, i_width, result2);\r
+ // transmMatここまで\r
+ if (err2 < err1) {\r
+ io_result_conv.copyFrom(result2);\r
+ err1 = err2;\r
+ }\r
+ }\r
+ return err1;\r
+ }\r
+\r
+ private final double[] wk_arGetTransMat3_initPos3d_pmax = new double[3];\r
+ private final double[] wk_arGetTransMat3_initPos3d_pmin = new double[3];\r
+\r
+ /**\r
+ * arGetTransMat3関数の前処理部分。i_ppos3dから、o_pos3dとoffを計算する。\r
+ * 計算結果から再帰的に変更される可能性が無いので、切り離し。\r
+ * \r
+ * @param i_ppos3d\r
+ * 入力配列[num][3]\r
+ * @param o_pos3d\r
+ * 出力配列[P_MAX][3]\r
+ * @param o_off\r
+ * [3]\r
+ * @throws NyARException\r
+ */\r
+ private final void arGetTransMat3_initPos3d(double i_ppos3d[][],\r
+ double[][] o_pos3d, double[] o_off) throws NyARException {\r
+ double[] pmax = wk_arGetTransMat3_initPos3d_pmax;// new double[3];\r
+ double[] pmin = wk_arGetTransMat3_initPos3d_pmin;// new\r
+ // double[3];//double\r
+ // off[3], pmax[3],\r
+ // pmin[3];\r
+ int i;\r
+ pmax[0] = pmax[1] = pmax[2] = -10000000000.0;\r
+ pmin[0] = pmin[1] = pmin[2] = 10000000000.0;\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ if (i_ppos3d[i][0] > pmax[0]) {\r
+ pmax[0] = i_ppos3d[i][0];\r
+ }\r
+ if (i_ppos3d[i][0] < pmin[0]) {\r
+ pmin[0] = i_ppos3d[i][0];\r
+ }\r
+ if (i_ppos3d[i][1] > pmax[1]) {\r
+ pmax[1] = i_ppos3d[i][1];\r
+ }\r
+ if (i_ppos3d[i][1] < pmin[1]) {\r
+ pmin[1] = i_ppos3d[i][1];\r
+ }\r
+ /*\r
+ * オリジナルでもコメントアウト if( ppos3d[i][2] > pmax[2] ) pmax[2] =\r
+ * ppos3d[i][2]; if( ppos3d[i][2] < pmin[2] ) pmin[2] =\r
+ * ppos3d[i][2];\r
+ */\r
+ }\r
+ o_off[0] = -(pmax[0] + pmin[0]) / 2.0;\r
+ o_off[1] = -(pmax[1] + pmin[1]) / 2.0;\r
+ o_off[2] = -(pmax[2] + pmin[2]) / 2.0;\r
+\r
+ double[] o_pos3d_pt;\r
+ double[] i_pos_pd_pt;\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ o_pos3d_pt = o_pos3d[i];\r
+ i_pos_pd_pt = i_ppos3d[i];\r
+ o_pos3d_pt[0] = i_pos_pd_pt[0] + o_off[0];\r
+ o_pos3d_pt[1] = i_pos_pd_pt[1] + o_off[1];\r
+ o_pos3d_pt[2] = 0.0;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * double arGetTransMat3( double rot[3][3], double ppos2d[][2],double\r
+ * ppos3d[][2], int num, double conv[3][4],double *dist_factor, double\r
+ * cpara[3][4] ) STEP 414->\r
+ * \r
+ * @param ppos2d\r
+ * @param i_pos3d\r
+ * @param i_off\r
+ * @param num\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ private final double arGetTransMat3(double ppos2d[][],\r
+ final double i_pos3d[][], final double i_off[],\r
+ NyARTransMatResult o_result_conv) throws NyARException {\r
+\r
+ double ret;\r
+ ret = arGetTransMatSub(ppos2d, i_pos3d, i_off, o_result_conv);\r
+\r
+ // double[][] conv=o_result_conv.getArray();\r
+ // double[] rot=transrot.getArray();\r
+ // for(int i=0;i<3;i++){\r
+ // conv[i][0] = rot[i*3+0];\r
+ // conv[i][1] = rot[i*3+1];\r
+ // conv[i][2] = rot[i*3+2];\r
+ // }\r
+ // conv[0][3] = conv[0][0]*i_off[0] + conv[0][1]*i_off[1] +\r
+ // conv[0][2]*i_off[2] + conv[0][3];\r
+ // conv[1][3] = conv[1][0]*i_off[0] + conv[1][1]*i_off[1] +\r
+ // conv[1][2]*i_off[2] + conv[1][3];\r
+ // conv[2][3] = conv[2][0]*i_off[0] + conv[2][1]*i_off[1] +\r
+ // conv[2][2]*i_off[2] + conv[2][3];\r
+ return ret;\r
+ }\r
+\r
+ private final NyARMat wk_arGetTransMatSub_mat_a = new NyARMat(\r
+ NUMBER_OF_VERTEX * 2, 3);\r
+ private final NyARMat wk_arGetTransMatSub_mat_b = new NyARMat(3,\r
+ NUMBER_OF_VERTEX * 2);\r
+ private final NyARMat wk_arGetTransMatSub_mat_c = new NyARMat(\r
+ NUMBER_OF_VERTEX * 2, 1);\r
+ private final NyARMat wk_arGetTransMatSub_mat_d = new NyARMat(3, 3);\r
+ private final NyARMat wk_arGetTransMatSub_mat_e = new NyARMat(3, 1);\r
+ private final NyARMat wk_arGetTransMatSub_mat_f = new NyARMat(3, 1);\r
+ private final double[] wk_arGetTransMatSub_trans = new double[3];\r
+ private final double[][] wk_arGetTransMatSub_pos2d = new double[P_MAX][2];// pos2d[P_MAX][2];\r
+ private final DoubleValue wk_arGetTransMatSub_a1 = new DoubleValue();\r
+ private final DoubleValue wk_arGetTransMatSub_a2 = new DoubleValue();\r
+\r
+ /**\r
+ * static double arGetTransMatSub( double rot[3][3], double\r
+ * ppos2d[][2],double pos3d[][3], int num, double conv[3][4],double\r
+ * *dist_factor, double cpara[3][4] ) Optimize:2008.04.20:STEP[1033→1004]\r
+ * \r
+ * @param i_ppos2d\r
+ * @param i_pos3d\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ private final double arGetTransMatSub(double i_ppos2d[][],\r
+ double i_pos3d[][], double[] i_off, NyARTransMatResult o_result_conv)\r
+ throws NyARException {\r
+ double[][] pos2d = wk_arGetTransMatSub_pos2d;\r
+ double cpara[] = param.get34Array();\r
+ NyARMat mat_a, mat_b, mat_c, mat_d, mat_e, mat_f;// ARMat *mat_a,\r
+ // *mat_b, *mat_c,\r
+ // *mat_d, *mat_e,\r
+ // *mat_f;\r
+\r
+ double wx, wy, wz;\r
+ double ret;\r
+ int i;\r
+ double[] po2d_pt;\r
+\r
+ mat_a = this.wk_arGetTransMatSub_mat_a;\r
+ // mat_a.realloc(NUMBER_OF_VERTEX*2,3);\r
+ double[][] a_array = mat_a.getArray();\r
+\r
+ mat_b = this.wk_arGetTransMatSub_mat_b;\r
+ // mat_b.realloc(3,NUMBER_OF_VERTEX*2);\r
+ double[][] b_array = mat_b.getArray();\r
+\r
+ DoubleValue a1 = wk_arGetTransMatSub_a1;\r
+ DoubleValue a2 = wk_arGetTransMatSub_a2;\r
+ if (arFittingMode == AR_FITTING_TO_INPUT) {\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ param.ideal2Observ(i_ppos2d[i][0], i_ppos2d[i][1], a1, a2);// arParamIdeal2Observ(dist_factor,\r
+ // ppos2d[i][0],\r
+ // ppos2d[i][1],&pos2d[i][0],\r
+ // &pos2d[i][1]);\r
+ po2d_pt = pos2d[i];\r
+ po2d_pt[0] = a1.value;\r
+ po2d_pt[1] = a2.value;\r
+ }\r
+ } else {\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ po2d_pt = pos2d[i];\r
+ pos2d[i][0] = i_ppos2d[i][0];\r
+ pos2d[i][1] = i_ppos2d[i][1];\r
+ }\r
+ }\r
+ mat_c = this.wk_arGetTransMatSub_mat_c;// 次処理で値をもらうので、初期化の必要は無い。\r
+ // mat_c.realloc(NUMBER_OF_VERTEX*2,1);\r
+ double[][] c_array = mat_c.getArray();\r
+ double[] rot = transrot.getArray();\r
+ double[] i_pos3d_pt;\r
+ int x2;\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ x2 = i * 2;\r
+ i_pos3d_pt = i_pos3d[i];\r
+ po2d_pt = pos2d[i];\r
+ wx = rot[0] * i_pos3d_pt[0] + rot[1] * i_pos3d_pt[1] + rot[2]\r
+ * i_pos3d_pt[2];\r
+ wy = rot[3] * i_pos3d_pt[0] + rot[4] * i_pos3d_pt[1] + rot[5]\r
+ * i_pos3d_pt[2];\r
+ wz = rot[6] * i_pos3d_pt[0] + rot[7] * i_pos3d_pt[1] + rot[8]\r
+ * i_pos3d_pt[2];\r
+ // </Optimize>\r
+ a_array[x2][0] = b_array[0][x2] = cpara[0 * 4 + 0];// mat_a->m[j*6+0]\r
+ // =\r
+ // mat_b->m[num*0+j*2]\r
+ // =\r
+ // cpara[0][0];\r
+ a_array[x2][1] = b_array[1][x2] = cpara[0 * 4 + 1];// mat_a->m[j*6+1]\r
+ // =\r
+ // mat_b->m[num*2+j*2]\r
+ // =\r
+ // cpara[0][1];\r
+ a_array[x2][2] = b_array[2][x2] = cpara[0 * 4 + 2] - po2d_pt[0];// mat_a->m[j*6+2]\r
+ // =\r
+ // mat_b->m[num*4+j*2]\r
+ // =\r
+ // cpara[0][2]\r
+ // -\r
+ // pos2d[j][0];\r
+ a_array[x2 + 1][0] = b_array[0][x2 + 1] = 0.0;// mat_a->m[j*6+3] =\r
+ // mat_b->m[num*0+j*2+1]\r
+ // = 0.0;\r
+ a_array[x2 + 1][1] = b_array[1][x2 + 1] = cpara[1 * 4 + 1];// mat_a->m[j*6+4]\r
+ // =\r
+ // mat_b->m[num*2+j*2+1]\r
+ // =\r
+ // cpara[1][1];\r
+ a_array[x2 + 1][2] = b_array[2][x2 + 1] = cpara[1 * 4 + 2]\r
+ - po2d_pt[1];// mat_a->m[j*6+5] = mat_b->m[num*4+j*2+1] =\r
+ // cpara[1][2] - pos2d[j][1];\r
+ c_array[x2][0] = wz * po2d_pt[0] - cpara[0 * 4 + 0] * wx\r
+ - cpara[0 * 4 + 1] * wy - cpara[0 * 4 + 2] * wz;// mat_c->m[j*2+0]\r
+ // = wz *\r
+ // pos2d[j][0]-\r
+ // cpara[0][0]*wx\r
+ // -\r
+ // cpara[0][1]*wy\r
+ // -\r
+ // cpara[0][2]*wz;\r
+ c_array[x2 + 1][0] = wz * po2d_pt[1] - cpara[1 * 4 + 1] * wy\r
+ - cpara[1 * 4 + 2] * wz;// mat_c->m[j*2+1] = wz *\r
+ // pos2d[j][1]- cpara[1][1]*wy -\r
+ // cpara[1][2]*wz;\r
+ }\r
+ mat_d = this.wk_arGetTransMatSub_mat_d;// 次処理で値をもらうので、初期化の必要は無い。\r
+ mat_e = this.wk_arGetTransMatSub_mat_e;// 次処理で値をもらうので、初期化の必要は無い。\r
+ mat_f = this.wk_arGetTransMatSub_mat_f;// 次処理で値をもらうので、初期化の必要は無い。\r
+ double[][] f_array = mat_f.getArray();\r
+\r
+ mat_d.matrixMul(mat_b, mat_a);\r
+ mat_e.matrixMul(mat_b, mat_c);\r
+ mat_d.matrixSelfInv();\r
+ mat_f.matrixMul(mat_d, mat_e);\r
+\r
+ double[] trans = wk_arGetTransMatSub_trans;// double trans[3];\r
+ trans[0] = f_array[0][0];// trans[0] = mat_f->m[0];\r
+ trans[1] = f_array[1][0];\r
+ trans[2] = f_array[2][0];// trans[2] = mat_f->m[2];\r
+\r
+ ret = transrot.modifyMatrix(trans, i_pos3d, pos2d);\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ x2 = i * 2;\r
+ i_pos3d_pt = i_pos3d[i];\r
+ po2d_pt = pos2d[i];\r
+ // <Optimize>\r
+ // wx = rot[0][0] * pos3d[j][0]+ rot[0][1] * pos3d[j][1]+ rot[0][2]\r
+ // * pos3d[j][2];\r
+ // wy = rot[1][0] * pos3d[j][0]+ rot[1][1] * pos3d[j][1]+ rot[1][2]\r
+ // * pos3d[j][2];\r
+ // wz = rot[2][0] * pos3d[j][0]+ rot[2][1] * pos3d[j][1]+ rot[2][2]\r
+ // * pos3d[j][2];\r
+ wx = rot[0] * i_pos3d_pt[0] + rot[1] * i_pos3d_pt[1] + rot[2]\r
+ * i_pos3d_pt[2];\r
+ wy = rot[3] * i_pos3d_pt[0] + rot[4] * i_pos3d_pt[1] + rot[5]\r
+ * i_pos3d_pt[2];\r
+ wz = rot[6] * i_pos3d_pt[0] + rot[7] * i_pos3d_pt[1] + rot[8]\r
+ * i_pos3d_pt[2];\r
+ // </Optimize>\r
+ a_array[x2][0] = b_array[0][x2] = cpara[0 * 4 + 0];// mat_a->m[j*6+0]\r
+ // =\r
+ // mat_b->m[num*0+j*2]\r
+ // =\r
+ // cpara[0][0];\r
+ a_array[x2][1] = b_array[1][x2] = cpara[0 * 4 + 1];// mat_a->m[j*6+1]\r
+ // =\r
+ // mat_b->m[num*2+j*2]\r
+ // =\r
+ // cpara[0][1];\r
+ a_array[x2][2] = b_array[2][x2] = cpara[0 * 4 + 2] - po2d_pt[0];// mat_a->m[j*6+2]\r
+ // =\r
+ // mat_b->m[num*4+j*2]\r
+ // =\r
+ // cpara[0][2]\r
+ // -\r
+ // pos2d[j][0];\r
+ a_array[x2 + 1][0] = b_array[0][x2 + 1] = 0.0;// mat_a->m[j*6+3] =\r
+ // mat_b->m[num*0+j*2+1]\r
+ // = 0.0;\r
+ a_array[x2 + 1][1] = b_array[1][x2 + 1] = cpara[1 * 4 + 1];// mat_a->m[j*6+4]\r
+ // =\r
+ // mat_b->m[num*2+j*2+1]\r
+ // =\r
+ // cpara[1][1];\r
+ a_array[x2 + 1][2] = b_array[2][x2 + 1] = cpara[1 * 4 + 2]\r
+ - po2d_pt[1];// mat_a->m[j*6+5] = mat_b->m[num*4+j*2+1] =\r
+ // cpara[1][2] - pos2d[j][1];\r
+ c_array[x2][0] = wz * po2d_pt[0] - cpara[0 * 4 + 0] * wx\r
+ - cpara[0 * 4 + 1] * wy - cpara[0 * 4 + 2] * wz;// mat_c->m[j*2+0]\r
+ // = wz *\r
+ // pos2d[j][0]-\r
+ // cpara[0][0]*wx\r
+ // -\r
+ // cpara[0][1]*wy\r
+ // -\r
+ // cpara[0][2]*wz;\r
+ c_array[x2 + 1][0] = wz * po2d_pt[1] - cpara[1 * 4 + 1] * wy\r
+ - cpara[1 * 4 + 2] * wz;// mat_c->m[j*2+1] = wz *\r
+ // pos2d[j][1]- cpara[1][1]*wy -\r
+ // cpara[1][2]*wz;\r
+ }\r
+\r
+ mat_d.matrixMul(mat_b, mat_a);\r
+ mat_e.matrixMul(mat_b, mat_c);\r
+ mat_d.matrixSelfInv();\r
+ mat_f.matrixMul(mat_d, mat_e);\r
+\r
+ trans[0] = f_array[0][0];// trans[0] = mat_f->m[0];\r
+ trans[1] = f_array[1][0];\r
+ trans[2] = f_array[2][0];// trans[2] = mat_f->m[2];\r
+\r
+ ret = transrot.modifyMatrix(trans, i_pos3d, pos2d);\r
+ // 変換行列を保存\r
+ o_result_conv.updateMatrixValue(this.transrot, i_off, trans);\r
+\r
+ // double[][] conv=o_result_conv.getArray();\r
+ // for( i = 2; i >=0; i-- ) {//<Optimize/>for( j = 0; j < 3; j++ ) {\r
+ // //<Optimize>\r
+ // //for( i = 0; i < 3; i++ ){\r
+ // // conv[j][i] = rot[j][i];\r
+ // //}\r
+ // conv[i][0] = rot[i*3+0];\r
+ // conv[i][1] = rot[i*3+1];\r
+ // conv[i][2] = rot[i*3+2];\r
+ // //</Optimize>\r
+ // conv[i][3] = trans[i];\r
+ // }\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * This class calculates ARMatrix from square information and holds it. --\r
+ * 変換行列を計算して、結果を保持するクラス。\r
+ * \r
+ */\r
+public class NyARTransMat_O2 implements NyARTransMat {\r
+ private final static int AR_FITTING_TO_IDEAL = 0;// #define\r
+ // AR_FITTING_TO_IDEAL 0\r
+ private final static int AR_FITTING_TO_INPUT = 1;// #define\r
+ // AR_FITTING_TO_INPUT 1\r
+ private final static int arFittingMode = AR_FITTING_TO_INPUT;\r
+\r
+ private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define\r
+ // AR_GET_TRANS_MAT_MAX_LOOP_COUNT\r
+ // 5\r
+ private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define\r
+ // AR_GET_TRANS_MAT_MAX_FIT_ERROR\r
+ // 1.0\r
+ private final static double AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR = 1.0;\r
+ private final static int P_MAX = 10;// 頂点の数(4で十分だけどなんとなく10)//#define P_MAX\r
+ // 500\r
+ private final static int NUMBER_OF_VERTEX = 4;// 処理対象の頂点数\r
+ private final NyARTransRot transrot;\r
+ private final double[] center = { 0.0, 0.0 };\r
+ private final NyARParam param;\r
+ private final NyARMat result_mat = new NyARMat(3, 4);\r
+\r
+ public NyARTransMat_O2(NyARParam i_param) throws NyARException {\r
+ param = i_param;\r
+ transrot = new NyARTransRot_O3(i_param, NUMBER_OF_VERTEX);\r
+\r
+ }\r
+\r
+ public void setCenter(double i_x, double i_y) {\r
+ center[0] = i_x;\r
+ center[1] = i_x;\r
+ }\r
+\r
+ public NyARMat getTransformationMatrix() {\r
+ return result_mat;\r
+ }\r
+\r
+ /**\r
+ * transMat関数の初期化関数を分離したものです。\r
+ * \r
+ * @param square\r
+ * @param i_direction\r
+ * @param i_width\r
+ * @param o_ppos2d\r
+ * @param o_ppos3d\r
+ */\r
+ private final void init_transMat_ppos(NyARSquare square, int i_direction,\r
+ double i_width, double[][] o_ppos2d, double[][] o_ppos3d) {\r
+ o_ppos2d[0][0] = square.sqvertex[(4 - i_direction) % 4][0];\r
+ o_ppos2d[0][1] = square.sqvertex[(4 - i_direction) % 4][1];\r
+ o_ppos2d[1][0] = square.sqvertex[(5 - i_direction) % 4][0];\r
+ o_ppos2d[1][1] = square.sqvertex[(5 - i_direction) % 4][1];\r
+ o_ppos2d[2][0] = square.sqvertex[(6 - i_direction) % 4][0];\r
+ o_ppos2d[2][1] = square.sqvertex[(6 - i_direction) % 4][1];\r
+ o_ppos2d[3][0] = square.sqvertex[(7 - i_direction) % 4][0];\r
+ o_ppos2d[3][1] = square.sqvertex[(7 - i_direction) % 4][1];\r
+\r
+ double c0, c1, w_2;\r
+ c0 = center[0];\r
+ c1 = center[1];\r
+ w_2 = i_width / 2.0;\r
+\r
+ o_ppos3d[0][0] = c0 - w_2;// center[0] - w/2.0;\r
+ o_ppos3d[0][1] = c1 + w_2;// center[1] + w/2.0;\r
+ o_ppos3d[1][0] = c0 + w_2;// center[0] + w/2.0;\r
+ o_ppos3d[1][1] = c1 + w_2;// center[1] + w/2.0;\r
+ o_ppos3d[2][0] = c0 + w_2;// center[0] + w/2.0;\r
+ o_ppos3d[2][1] = c1 - w_2;// center[1] - w/2.0;\r
+ o_ppos3d[3][0] = c0 - w_2;// center[0] - w/2.0;\r
+ o_ppos3d[3][1] = c1 - w_2;// center[1] - w/2.0;\r
+ return;\r
+ }\r
+\r
+ private final double[][] wk_transMat_pos3d = new double[P_MAX][3];// pos3d[P_MAX][3];\r
+ private final double[][] wk_transMat_ppos2d = new double[4][2];\r
+ private final double[][] wk_transMat_ppos3d = new double[4][2];\r
+ private final double[] wk_transMat_off = new double[3];\r
+ private final double[][] wk_transMat_pos2d = new double[P_MAX][2];// pos2d[P_MAX][2];\r
+ private final NyARMat wk_transMat_mat_b = new NyARMat(3,\r
+ NUMBER_OF_VERTEX * 2);\r
+ private final NyARMat wk_transMat_mat_d = new NyARMat(3, 3);\r
+ private final double[] wk_transMat_mat_trans = new double[3];\r
+\r
+ /**\r
+ * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double\r
+ * width, double conv[3][4] ) 演算シーケンス最適化のため、arGetTransMat3等の関数フラグメントを含みます。\r
+ * 保持している変換行列を更新する。\r
+ * \r
+ * @param square\r
+ * 計算対象のNyARSquareオブジェクト\r
+ * @param i_direction\r
+ * @param width\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double transMat(NyARSquare square, int i_direction, double width,\r
+ NyARTransMatResult o_result_conv) throws NyARException {\r
+ double[][] ppos2d = wk_transMat_ppos2d;\r
+ double[][] ppos3d = wk_transMat_ppos3d;\r
+ double[] off = wk_transMat_off;\r
+ double[][] pos3d = wk_transMat_pos3d;\r
+\r
+ // rotationの初期化\r
+ transrot.initRot(square, i_direction);\r
+\r
+ // ppos2dとppos3dの初期化\r
+ init_transMat_ppos(square, i_direction, width, ppos2d, ppos3d);\r
+\r
+ // arGetTransMat3の前段処理(pos3dとoffを初期化)\r
+ double[][] pos2d = this.wk_transMat_pos2d;\r
+ final NyARMat mat_b = this.wk_transMat_mat_b;\r
+ final NyARMat mat_d = this.wk_transMat_mat_d;\r
+\r
+ arGetTransMat3_initTransMat(ppos3d, ppos2d, pos2d, pos3d, off, mat_b,\r
+ mat_d);\r
+\r
+ double err = -1;\r
+ double[] trans = this.wk_transMat_mat_trans;\r
+ for (int i = 0; i < AR_GET_TRANS_MAT_MAX_LOOP_COUNT; i++) {\r
+ // <arGetTransMat3>\r
+ err = arGetTransMatSub(pos2d, pos3d, mat_b, mat_d, trans);\r
+ // //</arGetTransMat3>\r
+ if (err < AR_GET_TRANS_MAT_MAX_FIT_ERROR) {\r
+ break;\r
+ }\r
+ }\r
+ // マトリクスの保存\r
+ o_result_conv.updateMatrixValue(this.transrot, off, trans);\r
+ return err;\r
+ }\r
+\r
+ private final NyARTransMatResult wk_transMatContinue_result = new NyARTransMatResult();\r
+\r
+ /**\r
+ * double arGetTransMatCont( ARMarkerInfo *marker_info, double\r
+ * prev_conv[3][4],double center[2], double width, double conv[3][4] )\r
+ * \r
+ * @param i_square\r
+ * @param i_direction\r
+ * マーカーの方位を指定する。\r
+ * @param i_width\r
+ * @param io_result_conv\r
+ * 計算履歴を持つNyARTransMatResultオブジェクトを指定する。\r
+ * 履歴を持たない場合は、transMatと同じ処理を行う。\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double transMatContinue(NyARSquare i_square, int i_direction,\r
+ double i_width, NyARTransMatResult io_result_conv)\r
+ throws NyARException {\r
+ // io_result_convが初期値なら、transMatで計算する。\r
+ if (!io_result_conv.hasValue()) {\r
+ return this\r
+ .transMat(i_square, i_direction, i_width, io_result_conv);\r
+ }\r
+\r
+ double[][] ppos2d = wk_transMat_ppos2d;\r
+ double[][] ppos3d = wk_transMat_ppos3d;\r
+ double[] off = wk_transMat_off;\r
+ double[][] pos3d = wk_transMat_pos3d;\r
+\r
+ // arGetTransMatContSub計算部分\r
+ transrot.initRotByPrevResult(io_result_conv);\r
+\r
+ // ppos2dとppos3dの初期化\r
+ init_transMat_ppos(i_square, i_direction, i_width, ppos2d, ppos3d);\r
+\r
+ // arGetTransMat3の前段処理(pos3dとoffを初期化)\r
+ double[][] pos2d = this.wk_transMat_pos2d;\r
+ final NyARMat mat_b = this.wk_transMat_mat_b;\r
+ final NyARMat mat_d = this.wk_transMat_mat_d;\r
+\r
+ // transMatに必要な初期値を計算\r
+ arGetTransMat3_initTransMat(ppos3d, ppos2d, pos2d, pos3d, off, mat_b,\r
+ mat_d);\r
+\r
+ double err1, err2;\r
+ int i;\r
+\r
+ err1 = err2 = -1;\r
+ double[] trans = this.wk_transMat_mat_trans;\r
+ for (i = 0; i < AR_GET_TRANS_MAT_MAX_LOOP_COUNT; i++) {\r
+ err1 = arGetTransMatSub(pos2d, pos3d, mat_b, mat_d, trans);\r
+ if (err1 < AR_GET_TRANS_MAT_MAX_FIT_ERROR) {\r
+ // 十分な精度を達成できたらブレーク\r
+ break;\r
+ }\r
+ }\r
+ // 値を保存\r
+ io_result_conv.updateMatrixValue(this.transrot, off, trans);\r
+\r
+ // エラー値が許容範囲でなければTransMatをやり直し\r
+ if (err1 > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {\r
+ NyARTransMatResult result2 = this.wk_transMatContinue_result;\r
+ // transMatを実行(初期化値は共用)\r
+ transrot.initRot(i_square, i_direction);\r
+ err2 = transMat(i_square, i_direction, i_width, result2);\r
+ // transmMatここまで\r
+ if (err2 < err1) {\r
+ // 良い値が取れたら、差換え\r
+ io_result_conv.copyFrom(result2);\r
+ err1 = err2;\r
+ }\r
+ }\r
+ return err1;\r
+ }\r
+\r
+ private final NyARMat wk_arGetTransMat3_mat_a = new NyARMat(\r
+ NUMBER_OF_VERTEX * 2, 3);\r
+\r
+ /**\r
+ * arGetTransMat3関数の前処理部分。i_ppos3dから、o_pos3dとoffを計算する。\r
+ * 計算結果から再帰的に変更される可能性が無いので、切り離し。\r
+ * \r
+ * @param i_ppos3d\r
+ * 入力配列[num][3]\r
+ * @param o_pos3d\r
+ * 出力配列[P_MAX][3]\r
+ * @param o_off\r
+ * [3]\r
+ * @throws NyARException\r
+ */\r
+ private final void arGetTransMat3_initTransMat(double[][] i_ppos3d,\r
+ double[][] i_ppos2d, double[][] o_pos2d, double[][] o_pos3d,\r
+ double[] o_off, NyARMat o_mat_b, NyARMat o_mat_d)\r
+ throws NyARException {\r
+ double pmax0, pmax1, pmax2, pmin0, pmin1, pmin2;\r
+ int i;\r
+ pmax0 = pmax1 = pmax2 = -10000000000.0;\r
+ pmin0 = pmin1 = pmin2 = 10000000000.0;\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ if (i_ppos3d[i][0] > pmax0) {\r
+ pmax0 = i_ppos3d[i][0];\r
+ }\r
+ if (i_ppos3d[i][0] < pmin0) {\r
+ pmin0 = i_ppos3d[i][0];\r
+ }\r
+ if (i_ppos3d[i][1] > pmax1) {\r
+ pmax1 = i_ppos3d[i][1];\r
+ }\r
+ if (i_ppos3d[i][1] < pmin1) {\r
+ pmin1 = i_ppos3d[i][1];\r
+ }\r
+ /*\r
+ * オリジナルでもコメントアウト if( ppos3d[i][2] > pmax[2] ) pmax[2] =\r
+ * ppos3d[i][2]; if( ppos3d[i][2] < pmin[2] ) pmin[2] =\r
+ * ppos3d[i][2];\r
+ */\r
+ }\r
+ o_off[0] = -(pmax0 + pmin0) / 2.0;\r
+ o_off[1] = -(pmax1 + pmin1) / 2.0;\r
+ o_off[2] = -(pmax2 + pmin2) / 2.0;\r
+\r
+ double[] o_pos3d_pt;\r
+ double[] i_pos_pd_pt;\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ o_pos3d_pt = o_pos3d[i];\r
+ i_pos_pd_pt = i_ppos3d[i];\r
+ o_pos3d_pt[0] = i_pos_pd_pt[0] + o_off[0];\r
+ o_pos3d_pt[1] = i_pos_pd_pt[1] + o_off[1];\r
+ o_pos3d_pt[2] = 0.0;\r
+ }\r
+ // ココから先でarGetTransMatSubの初期化処理\r
+ // arGetTransMatSubにあった処理。毎回おなじっぽい。pos2dに変換座標を格納する。\r
+\r
+ if (arFittingMode == AR_FITTING_TO_INPUT) {\r
+ // arParamIdeal2Observをバッチ処理\r
+ param.ideal2ObservBatch(i_ppos2d, o_pos2d, NUMBER_OF_VERTEX);\r
+ } else {\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ o_pos2d[i][0] = i_ppos2d[i][0];\r
+ o_pos2d[i][1] = i_ppos2d[i][1];\r
+ }\r
+ }\r
+\r
+ // 変換マトリクスdとbの準備(arGetTransMatSubの一部)\r
+ final double cpara[] = param.get34Array();\r
+ final NyARMat mat_a = this.wk_arGetTransMat3_mat_a;\r
+ final double[][] a_array = mat_a.getArray();\r
+\r
+ // mat_bの設定\r
+ final double[][] b_array = o_mat_b.getArray();\r
+\r
+ int x2;\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ x2 = i * 2;\r
+ // </Optimize>\r
+ a_array[x2][0] = b_array[0][x2] = cpara[0 * 4 + 0];// mat_a->m[j*6+0]\r
+ // =\r
+ // mat_b->m[num*0+j*2]\r
+ // =\r
+ // cpara[0][0];\r
+ a_array[x2][1] = b_array[1][x2] = cpara[0 * 4 + 1];// mat_a->m[j*6+1]\r
+ // =\r
+ // mat_b->m[num*2+j*2]\r
+ // =\r
+ // cpara[0][1];\r
+ a_array[x2][2] = b_array[2][x2] = cpara[0 * 4 + 2] - o_pos2d[i][0];// mat_a->m[j*6+2]\r
+ // =\r
+ // mat_b->m[num*4+j*2]\r
+ // =\r
+ // cpara[0][2]\r
+ // -\r
+ // pos2d[j][0];\r
+ a_array[x2 + 1][0] = b_array[0][x2 + 1] = 0.0;// mat_a->m[j*6+3] =\r
+ // mat_b->m[num*0+j*2+1]\r
+ // = 0.0;\r
+ a_array[x2 + 1][1] = b_array[1][x2 + 1] = cpara[1 * 4 + 1];// mat_a->m[j*6+4]\r
+ // =\r
+ // mat_b->m[num*2+j*2+1]\r
+ // =\r
+ // cpara[1][1];\r
+ a_array[x2 + 1][2] = b_array[2][x2 + 1] = cpara[1 * 4 + 2]\r
+ - o_pos2d[i][1];// mat_a->m[j*6+5] = mat_b->m[num*4+j*2+1] =\r
+ // cpara[1][2] - pos2d[j][1];\r
+ }\r
+\r
+ // mat_d\r
+ o_mat_d.matrixMul(o_mat_b, mat_a);\r
+ o_mat_d.matrixSelfInv();\r
+ }\r
+\r
+ private final NyARMat wk_arGetTransMatSub_mat_c = new NyARMat(\r
+ NUMBER_OF_VERTEX * 2, 1);\r
+ private final NyARMat wk_arGetTransMatSub_mat_e = new NyARMat(3, 1);\r
+ private final NyARMat wk_arGetTransMatSub_mat_f = new NyARMat(3, 1);\r
+\r
+ /**\r
+ * static double arGetTransMatSub( double rot[3][3], double\r
+ * ppos2d[][2],double pos3d[][3], int num, double conv[3][4],double\r
+ * *dist_factor, double cpara[3][4] ) Optimize:2008.04.20:STEP[1033→1004]\r
+ * \r
+ * @param i_ppos2d\r
+ * @param i_pos3d\r
+ * @param i_mat_b\r
+ * 演算用行列b\r
+ * @param i_mat_d\r
+ * 演算用行列d\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ private final double arGetTransMatSub(double i_ppos2d[][],\r
+ double i_pos3d[][], NyARMat i_mat_b, NyARMat i_mat_d,\r
+ double[] o_trans) throws NyARException {\r
+ double cpara[] = param.get34Array();\r
+ NyARMat mat_c, mat_e, mat_f;// ARMat *mat_a, *mat_b, *mat_c, *mat_d,\r
+ // *mat_e, *mat_f;\r
+\r
+ double wx, wy, wz;\r
+ double ret;\r
+ int i;\r
+\r
+ mat_c = this.wk_arGetTransMatSub_mat_c;// 次処理で値をもらうので、初期化の必要は無い。\r
+ double[][] c_array = mat_c.getArray();\r
+ double[] rot = transrot.getArray();\r
+ double[] i_pos3d_pt;\r
+ int x2;\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ x2 = i * 2;\r
+ i_pos3d_pt = i_pos3d[i];\r
+ wx = rot[0] * i_pos3d_pt[0] + rot[1] * i_pos3d_pt[1] + rot[2]\r
+ * i_pos3d_pt[2];\r
+ wy = rot[3] * i_pos3d_pt[0] + rot[4] * i_pos3d_pt[1] + rot[5]\r
+ * i_pos3d_pt[2];\r
+ wz = rot[6] * i_pos3d_pt[0] + rot[7] * i_pos3d_pt[1] + rot[8]\r
+ * i_pos3d_pt[2];\r
+ c_array[x2][0] = wz * i_ppos2d[i][0] - cpara[0 * 4 + 0] * wx\r
+ - cpara[0 * 4 + 1] * wy - cpara[0 * 4 + 2] * wz;// mat_c->m[j*2+0]\r
+ // = wz *\r
+ // pos2d[j][0]-\r
+ // cpara[0][0]*wx\r
+ // -\r
+ // cpara[0][1]*wy\r
+ // -\r
+ // cpara[0][2]*wz;\r
+ c_array[x2 + 1][0] = wz * i_ppos2d[i][1] - cpara[1 * 4 + 1] * wy\r
+ - cpara[1 * 4 + 2] * wz;// mat_c->m[j*2+1] = wz *\r
+ // pos2d[j][1]- cpara[1][1]*wy -\r
+ // cpara[1][2]*wz;\r
+ }\r
+ mat_e = this.wk_arGetTransMatSub_mat_e;// 次処理で値をもらうので、初期化の必要は無い。\r
+ mat_f = this.wk_arGetTransMatSub_mat_f;// 次処理で値をもらうので、初期化の必要は無い。\r
+ double[][] f_array = mat_f.getArray();\r
+\r
+ mat_e.matrixMul(i_mat_b, mat_c);\r
+ mat_f.matrixMul(i_mat_d, mat_e);\r
+\r
+ // double[] trans=wk_arGetTransMatSub_trans;//double trans[3];\r
+ o_trans[0] = f_array[0][0];// trans[0] = mat_f->m[0];\r
+ o_trans[1] = f_array[1][0];\r
+ o_trans[2] = f_array[2][0];// trans[2] = mat_f->m[2];\r
+ ret = transrot.modifyMatrix(o_trans, i_pos3d, i_ppos2d);\r
+ for (i = 0; i < NUMBER_OF_VERTEX; i++) {\r
+ x2 = i * 2;\r
+ i_pos3d_pt = i_pos3d[i];\r
+ wx = rot[0] * i_pos3d_pt[0] + rot[1] * i_pos3d_pt[1] + rot[2]\r
+ * i_pos3d_pt[2];\r
+ wy = rot[3] * i_pos3d_pt[0] + rot[4] * i_pos3d_pt[1] + rot[5]\r
+ * i_pos3d_pt[2];\r
+ wz = rot[6] * i_pos3d_pt[0] + rot[7] * i_pos3d_pt[1] + rot[8]\r
+ * i_pos3d_pt[2];\r
+ c_array[x2][0] = wz * i_ppos2d[i][0] - cpara[0 * 4 + 0] * wx\r
+ - cpara[0 * 4 + 1] * wy - cpara[0 * 4 + 2] * wz;// mat_c->m[j*2+0]\r
+ // = wz *\r
+ // pos2d[j][0]-\r
+ // cpara[0][0]*wx\r
+ // -\r
+ // cpara[0][1]*wy\r
+ // -\r
+ // cpara[0][2]*wz;\r
+ c_array[x2 + 1][0] = wz * i_ppos2d[i][1] - cpara[1 * 4 + 1] * wy\r
+ - cpara[1 * 4 + 2] * wz;// mat_c->m[j*2+1] = wz *\r
+ // pos2d[j][1]- cpara[1][1]*wy -\r
+ // cpara[1][2]*wz;\r
+ }\r
+\r
+ mat_e.matrixMul(i_mat_b, mat_c);\r
+ mat_f.matrixMul(i_mat_d, mat_e);\r
+ o_trans[0] = f_array[0][0];// trans[0] = mat_f->m[0];\r
+ o_trans[1] = f_array[1][0];\r
+ o_trans[2] = f_array[2][0];// trans[2] = mat_f->m[2];\r
+ ret = transrot.modifyMatrix(o_trans, i_pos3d, i_ppos2d);\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+interface NyARTransRot\r
+{\r
+ public double[] getArray();\r
+ /**\r
+ * \r
+ * @param trans\r
+ * @param vertex\r
+ * @param pos2d\r
+ * [n*2]配列\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double modifyMatrix(double trans[],double vertex[][], double pos2d[][]) throws NyARException;\r
+ public void initRot(NyARSquare marker_info,int i_direction) throws NyARException;\r
+ public void initRotByPrevResult(NyARTransMatResult i_prev_result);\r
+}\r
+\r
+/**\r
+ * NyARTransRot派生クラスで共通に使いそうな関数類をまとめたもの。\r
+ *\r
+ */\r
+abstract class NyARTransRot_OptimizeCommon implements NyARTransRot\r
+{\r
+ protected final int number_of_vertex;\r
+ protected final double[] array=new double[9];\r
+ protected final NyARParam cparam;\r
+ public final void initRotByPrevResult(NyARTransMatResult i_prev_result)\r
+ {\r
+ double[][] prev_array=i_prev_result.getArray();\r
+ double[] pt;\r
+ final double[] L_rot=this.array;\r
+ pt=prev_array[0];\r
+ L_rot[0*3+0]=pt[0];\r
+ L_rot[0*3+1]=pt[1];\r
+ L_rot[0*3+2]=pt[2];\r
+ pt=prev_array[1];\r
+ L_rot[1*3+0]=pt[0];\r
+ L_rot[1*3+1]=pt[1];\r
+ L_rot[1*3+2]=pt[2];\r
+ pt=prev_array[2];\r
+ L_rot[2*3+0]=pt[0];\r
+ L_rot[2*3+1]=pt[1];\r
+ L_rot[2*3+2]=pt[2];\r
+ }\r
+ public final double[] getArray()\r
+ {\r
+ return this.array;\r
+ }\r
+ /**\r
+ * インスタンスを準備します。\r
+ * @param i_param\r
+ * nullを指定した場合、一部の関数が使用不能になります。\r
+ */\r
+ public NyARTransRot_OptimizeCommon(NyARParam i_param,int i_number_of_vertex) throws NyARException\r
+ {\r
+ number_of_vertex=i_number_of_vertex;\r
+ cparam=i_param;\r
+ }\r
+\r
+ private final double[] wk_check_dir_world=new double[6];\r
+ private final double[] wk_check_dir_camera=new double[4];\r
+ private final NyARMat wk_check_dir_NyARMat=new NyARMat( 3, 3 );\r
+ /**\r
+ * static int check_dir( double dir[3], double st[2], double ed[2],double cpara[3][4] )\r
+ * Optimize:STEP[526->468]\r
+ * @param dir\r
+ * @param st\r
+ * @param ed\r
+ * @param cpara\r
+ * \r
+ * @throws NyARException\r
+ */\r
+ protected final void check_dir( double dir[], double st[], double ed[],double cpara[]) throws NyARException\r
+ {\r
+ double h;\r
+ int i, j;\r
+\r
+ NyARMat mat_a = this.wk_check_dir_NyARMat;//ここ、事前に初期化できそう\r
+ double[][] a_array=mat_a.getArray();\r
+ for(j=0;j<3;j++){\r
+ for(i=0;i<3;i++){\r
+ a_array[j][i]=cpara[j*4+i];//m[j*3+i] = cpara[j][i];\r
+ }\r
+ \r
+ }\r
+ // JartkException.trap("未チェックのパス");\r
+ mat_a.matrixSelfInv();\r
+ double[] world=wk_check_dir_world;//[2][3];\r
+ //<Optimize>\r
+ //world[0][0] = a_array[0][0]*st[0]*10.0+ a_array[0][1]*st[1]*10.0+ a_array[0][2]*10.0;//mat_a->m[0]*st[0]*10.0+ mat_a->m[1]*st[1]*10.0+ mat_a->m[2]*10.0;\r
+ //world[0][1] = a_array[1][0]*st[0]*10.0+ a_array[1][1]*st[1]*10.0+ a_array[1][2]*10.0;//mat_a->m[3]*st[0]*10.0+ mat_a->m[4]*st[1]*10.0+ mat_a->m[5]*10.0;\r
+ //world[0][2] = a_array[2][0]*st[0]*10.0+ a_array[2][1]*st[1]*10.0+ a_array[2][2]*10.0;//mat_a->m[6]*st[0]*10.0+ mat_a->m[7]*st[1]*10.0+ mat_a->m[8]*10.0;\r
+ //world[1][0] = world[0][0] + dir[0];\r
+ //world[1][1] = world[0][1] + dir[1];\r
+ //world[1][2] = world[0][2] + dir[2];\r
+ world[0] = a_array[0][0]*st[0]*10.0+ a_array[0][1]*st[1]*10.0+ a_array[0][2]*10.0;//mat_a->m[0]*st[0]*10.0+ mat_a->m[1]*st[1]*10.0+ mat_a->m[2]*10.0;\r
+ world[1] = a_array[1][0]*st[0]*10.0+ a_array[1][1]*st[1]*10.0+ a_array[1][2]*10.0;//mat_a->m[3]*st[0]*10.0+ mat_a->m[4]*st[1]*10.0+ mat_a->m[5]*10.0;\r
+ world[2] = a_array[2][0]*st[0]*10.0+ a_array[2][1]*st[1]*10.0+ a_array[2][2]*10.0;//mat_a->m[6]*st[0]*10.0+ mat_a->m[7]*st[1]*10.0+ mat_a->m[8]*10.0;\r
+ world[3] = world[0] + dir[0];\r
+ world[4] = world[1] + dir[1];\r
+ world[5] = world[2] + dir[2];\r
+ //</Optimize>\r
+\r
+ double[] camera=wk_check_dir_camera;//[2][2];\r
+ for( i = 0; i < 2; i++ ) {\r
+ h = cpara[2*4+0] * world[i*3+0]+ cpara[2*4+1] * world[i*3+1]+ cpara[2*4+2] * world[i*3+2];\r
+ if( h == 0.0 ){\r
+ throw new NyARException();\r
+ }\r
+ camera[i*2+0] = (cpara[0*4+0] * world[i*3+0]+ cpara[0*4+1] * world[i*3+1]+ cpara[0*4+2] * world[i*3+2]) / h;\r
+ camera[i*2+1] = (cpara[1*4+0] * world[i*3+0]+ cpara[1*4+1] * world[i*3+1]+ cpara[1*4+2] * world[i*3+2]) / h;\r
+ }\r
+ //<Optimize>\r
+ //v[0][0] = ed[0] - st[0];\r
+ //v[0][1] = ed[1] - st[1];\r
+ //v[1][0] = camera[1][0] - camera[0][0];\r
+ //v[1][1] = camera[1][1] - camera[0][1];\r
+ double v=(ed[0]-st[0])*(camera[2]-camera[0])+(ed[1]-st[1])*(camera[3]-camera[1]);\r
+ //</Optimize>\r
+ if(v<0) {//if( v[0][0]*v[1][0] + v[0][1]*v[1][1] < 0 ) {\r
+ dir[0] = -dir[0];\r
+ dir[1] = -dir[1];\r
+ dir[2] = -dir[2];\r
+ }\r
+ }\r
+ /*int check_rotation( double rot[2][3] )*/\r
+ protected final static void check_rotation( double rot[][] ) throws NyARException\r
+ {\r
+ double[] v1=new double[3], v2=new double[3], v3=new double[3];\r
+ double ca, cb, k1, k2, k3, k4;\r
+ double a, b, c, d;\r
+ double p1, q1, r1;\r
+ double p2, q2, r2;\r
+ double p3, q3, r3;\r
+ double p4, q4, r4;\r
+ double w;\r
+ double e1, e2, e3, e4;\r
+ int f;\r
+\r
+ v1[0] = rot[0][0];\r
+ v1[1] = rot[0][1];\r
+ v1[2] = rot[0][2];\r
+ v2[0] = rot[1][0];\r
+ v2[1] = rot[1][1];\r
+ v2[2] = rot[1][2];\r
+ v3[0] = v1[1]*v2[2] - v1[2]*v2[1];\r
+ v3[1] = v1[2]*v2[0] - v1[0]*v2[2];\r
+ v3[2] = v1[0]*v2[1] - v1[1]*v2[0];\r
+ w = Math.sqrt( v3[0]*v3[0]+v3[1]*v3[1]+v3[2]*v3[2] );\r
+ if( w == 0.0 ){\r
+ throw new NyARException();\r
+ }\r
+ v3[0] /= w;\r
+ v3[1] /= w;\r
+ v3[2] /= w;\r
+\r
+ cb = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];\r
+ if( cb < 0 ) cb *= -1.0;\r
+ ca = (Math.sqrt(cb+1.0) + Math.sqrt(1.0-cb)) * 0.5;\r
+\r
+ if( v3[1]*v1[0] - v1[1]*v3[0] != 0.0 ) {\r
+ f = 0;\r
+ }\r
+ else {\r
+ if( v3[2]*v1[0] - v1[2]*v3[0] != 0.0 ) {\r
+ w = v1[1]; v1[1] = v1[2]; v1[2] = w;\r
+ w = v3[1]; v3[1] = v3[2]; v3[2] = w;\r
+ f = 1;\r
+ }\r
+ else {\r
+ w = v1[0]; v1[0] = v1[2]; v1[2] = w;\r
+ w = v3[0]; v3[0] = v3[2]; v3[2] = w;\r
+ f = 2;\r
+ }\r
+ }\r
+ if( v3[1]*v1[0] - v1[1]*v3[0] == 0.0 ){\r
+ throw new NyARException();\r
+ }\r
+ k1 = (v1[1]*v3[2] - v3[1]*v1[2]) / (v3[1]*v1[0] - v1[1]*v3[0]);\r
+ k2 = (v3[1] * ca) / (v3[1]*v1[0] - v1[1]*v3[0]);\r
+ k3 = (v1[0]*v3[2] - v3[0]*v1[2]) / (v3[0]*v1[1] - v1[0]*v3[1]);\r
+ k4 = (v3[0] * ca) / (v3[0]*v1[1] - v1[0]*v3[1]);\r
+\r
+ a = k1*k1 + k3*k3 + 1;\r
+ b = k1*k2 + k3*k4;\r
+ c = k2*k2 + k4*k4 - 1;\r
+\r
+ d = b*b - a*c;\r
+ if( d < 0 ){\r
+ throw new NyARException();\r
+ }\r
+ r1 = (-b + Math.sqrt(d))/a;\r
+ p1 = k1*r1 + k2;\r
+ q1 = k3*r1 + k4;\r
+ r2 = (-b - Math.sqrt(d))/a;\r
+ p2 = k1*r2 + k2;\r
+ q2 = k3*r2 + k4;\r
+ if( f == 1 ) {\r
+ w = q1; q1 = r1; r1 = w;\r
+ w = q2; q2 = r2; r2 = w;\r
+ w = v1[1]; v1[1] = v1[2]; v1[2] = w;\r
+ w = v3[1]; v3[1] = v3[2]; v3[2] = w;\r
+ f = 0;\r
+ }\r
+ if( f == 2 ) {\r
+ w = p1; p1 = r1; r1 = w;\r
+ w = p2; p2 = r2; r2 = w;\r
+ w = v1[0]; v1[0] = v1[2]; v1[2] = w;\r
+ w = v3[0]; v3[0] = v3[2]; v3[2] = w;\r
+ f = 0;\r
+ }\r
+\r
+ if( v3[1]*v2[0] - v2[1]*v3[0] != 0.0 ) {\r
+ f = 0;\r
+ }else {\r
+ if( v3[2]*v2[0] - v2[2]*v3[0] != 0.0 ) {\r
+ w = v2[1]; v2[1] = v2[2]; v2[2] = w;\r
+ w = v3[1]; v3[1] = v3[2]; v3[2] = w;\r
+ f = 1;\r
+ }\r
+ else {\r
+ w = v2[0]; v2[0] = v2[2]; v2[2] = w;\r
+ w = v3[0]; v3[0] = v3[2]; v3[2] = w;\r
+ f = 2;\r
+ }\r
+ }\r
+ if( v3[1]*v2[0] - v2[1]*v3[0] == 0.0 ){\r
+ throw new NyARException();\r
+ }\r
+ k1 = (v2[1]*v3[2] - v3[1]*v2[2]) / (v3[1]*v2[0] - v2[1]*v3[0]);\r
+ k2 = (v3[1] * ca) / (v3[1]*v2[0] - v2[1]*v3[0]);\r
+ k3 = (v2[0]*v3[2] - v3[0]*v2[2]) / (v3[0]*v2[1] - v2[0]*v3[1]);\r
+ k4 = (v3[0] * ca) / (v3[0]*v2[1] - v2[0]*v3[1]);\r
+\r
+ a = k1*k1 + k3*k3 + 1;\r
+ b = k1*k2 + k3*k4;\r
+ c = k2*k2 + k4*k4 - 1;\r
+\r
+ d = b*b - a*c;\r
+ if( d < 0 ){\r
+ throw new NyARException();\r
+ }\r
+ r3 = (-b + Math.sqrt(d))/a;\r
+ p3 = k1*r3 + k2;\r
+ q3 = k3*r3 + k4;\r
+ r4 = (-b - Math.sqrt(d))/a;\r
+ p4 = k1*r4 + k2;\r
+ q4 = k3*r4 + k4;\r
+ if( f == 1 ) {\r
+ w = q3; q3 = r3; r3 = w;\r
+ w = q4; q4 = r4; r4 = w;\r
+ w = v2[1]; v2[1] = v2[2]; v2[2] = w;\r
+ w = v3[1]; v3[1] = v3[2]; v3[2] = w;\r
+ f = 0;\r
+ }\r
+ if( f == 2 ) {\r
+ w = p3; p3 = r3; r3 = w;\r
+ w = p4; p4 = r4; r4 = w;\r
+ w = v2[0]; v2[0] = v2[2]; v2[2] = w;\r
+ w = v3[0]; v3[0] = v3[2]; v3[2] = w;\r
+ f = 0;\r
+ }\r
+\r
+ e1 = p1*p3+q1*q3+r1*r3;\r
+ if( e1 < 0 ){\r
+ e1 = -e1;\r
+ }\r
+ e2 = p1*p4+q1*q4+r1*r4;\r
+ if( e2 < 0 ){\r
+ e2 = -e2;\r
+ }\r
+ e3 = p2*p3+q2*q3+r2*r3;\r
+ if( e3 < 0 ){\r
+ e3 = -e3;\r
+ }\r
+ e4 = p2*p4+q2*q4+r2*r4;\r
+ if( e4 < 0 ){\r
+ e4 = -e4;\r
+ }\r
+ if( e1 < e2 ) {\r
+ if( e1 < e3 ) {\r
+ if( e1 < e4 ) {\r
+ rot[0][0] = p1;\r
+ rot[0][1] = q1;\r
+ rot[0][2] = r1;\r
+ rot[1][0] = p3;\r
+ rot[1][1] = q3;\r
+ rot[1][2] = r3;\r
+ }\r
+ else {\r
+ rot[0][0] = p2;\r
+ rot[0][1] = q2;\r
+ rot[0][2] = r2;\r
+ rot[1][0] = p4;\r
+ rot[1][1] = q4;\r
+ rot[1][2] = r4;\r
+ }\r
+ }\r
+ else {\r
+ if( e3 < e4 ) {\r
+ rot[0][0] = p2;\r
+ rot[0][1] = q2;\r
+ rot[0][2] = r2;\r
+ rot[1][0] = p3;\r
+ rot[1][1] = q3;\r
+ rot[1][2] = r3;\r
+ }\r
+ else {\r
+ rot[0][0] = p2;\r
+ rot[0][1] = q2;\r
+ rot[0][2] = r2;\r
+ rot[1][0] = p4;\r
+ rot[1][1] = q4;\r
+ rot[1][2] = r4;\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ if( e2 < e3 ) {\r
+ if( e2 < e4 ) {\r
+ rot[0][0] = p1;\r
+ rot[0][1] = q1;\r
+ rot[0][2] = r1;\r
+ rot[1][0] = p4;\r
+ rot[1][1] = q4;\r
+ rot[1][2] = r4;\r
+ }\r
+ else {\r
+ rot[0][0] = p2;\r
+ rot[0][1] = q2;\r
+ rot[0][2] = r2;\r
+ rot[1][0] = p4;\r
+ rot[1][1] = q4;\r
+ rot[1][2] = r4;\r
+ }\r
+ }\r
+ else {\r
+ if( e3 < e4 ) {\r
+ rot[0][0] = p2;\r
+ rot[0][1] = q2;\r
+ rot[0][2] = r2;\r
+ rot[1][0] = p3;\r
+ rot[1][1] = q3;\r
+ rot[1][2] = r3;\r
+ }\r
+ else {\r
+ rot[0][0] = p2;\r
+ rot[0][1] = q2;\r
+ rot[0][2] = r2;\r
+ rot[1][0] = p4;\r
+ rot[1][1] = q4;\r
+ rot[1][2] = r4;\r
+ }\r
+ }\r
+ }\r
+ } \r
+ /**\r
+ * パラメタa,b,cからrotを計算してインスタンスに保存する。\r
+ * rotを1次元配列に変更\r
+ * Optimize:2008.04.20:STEP[253→186]\r
+ * @param a\r
+ * @param b\r
+ * @param c\r
+ * @param o_rot\r
+ */\r
+ protected final static void arGetRot( double a, double b, double c,double[] o_rot)\r
+ {\r
+ double sina, sinb, sinc;\r
+ double cosa, cosb, cosc;\r
+\r
+ sina = Math.sin(a);\r
+ cosa = Math.cos(a);\r
+ sinb = Math.sin(b);\r
+ cosb = Math.cos(b);\r
+ sinc = Math.sin(c);\r
+ cosc = Math.cos(c);\r
+ //Optimize\r
+ double CACA,SASA,SACA,SASB,CASB,SACACB;\r
+ CACA =cosa*cosa;\r
+ SASA =sina*sina;\r
+ SACA =sina*cosa;\r
+ SASB =sina*sinb;\r
+ CASB =cosa*sinb;\r
+ SACACB=SACA*cosb;\r
+ \r
+\r
+ o_rot[0] = CACA*cosb*cosc+SASA*cosc+SACACB*sinc-SACA*sinc;\r
+ o_rot[1] = -CACA*cosb*sinc-SASA*sinc+SACACB*cosc-SACA*cosc;\r
+ o_rot[2] = CASB;\r
+ o_rot[3] = SACACB*cosc-SACA*cosc+SASA*cosb*sinc+CACA*sinc;\r
+ o_rot[4] = -SACACB*sinc+SACA*sinc+SASA*cosb*cosc+CACA*cosc;\r
+ o_rot[5] = SASB;\r
+ o_rot[6] = -CASB*cosc-SASB*sinc;\r
+ o_rot[7] = CASB*sinc-SASB*cosc;\r
+ o_rot[8] = cosb;\r
+ }\r
+ /**\r
+ * int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc )\r
+ * Optimize:2008.04.20:STEP[481→433]\r
+ * @param rot\r
+ * 2次元配列を1次元化してあります。\r
+ * @param o_abc\r
+ * @return\r
+ */\r
+ protected final int arGetAngle(double[] o_abc)\r
+ {\r
+ double a, b, c,tmp;\r
+ double sina, cosa, sinb, cosb, sinc, cosc;\r
+ double[] rot=array;\r
+ if( rot[8] > 1.0 ) {//<Optimize/>if( rot[2][2] > 1.0 ) {\r
+ rot[8] = 1.0;//<Optimize/>rot[2][2] = 1.0;\r
+ }else if( rot[8] < -1.0 ) {//<Optimize/>}else if( rot[2][2] < -1.0 ) {\r
+ rot[8] = -1.0;//<Optimize/>rot[2][2] = -1.0;\r
+ }\r
+ cosb = rot[8];//<Optimize/>cosb = rot[2][2];\r
+ b = Math.acos( cosb );\r
+ sinb = Math.sin( b );\r
+ if( b >= 0.000001 || b <= -0.000001) {\r
+ cosa = rot[2] / sinb;//<Optimize/>cosa = rot[0][2] / sinb;\r
+ sina = rot[5] / sinb;//<Optimize/>sina = rot[1][2] / sinb;\r
+ if( cosa > 1.0 ) {\r
+ /* printf("cos(alph) = %f\n", cosa); */\r
+ cosa = 1.0;\r
+ sina = 0.0;\r
+ }\r
+ if( cosa < -1.0 ) {\r
+ /* printf("cos(alph) = %f\n", cosa); */\r
+ cosa = -1.0;\r
+ sina = 0.0;\r
+ }\r
+ if( sina > 1.0 ) {\r
+ /* printf("sin(alph) = %f\n", sina); */\r
+ sina = 1.0;\r
+ cosa = 0.0;\r
+ }\r
+ if( sina < -1.0 ) {\r
+ /* printf("sin(alph) = %f\n", sina); */\r
+ sina = -1.0;\r
+ cosa = 0.0;\r
+ }\r
+ a = Math.acos( cosa );\r
+ if( sina < 0 ){\r
+ a = -a;\r
+ }\r
+ //<Optimize>\r
+ //sinc = (rot[2][1]*rot[0][2]-rot[2][0]*rot[1][2])/ (rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
+ //cosc = -(rot[0][2]*rot[2][0]+rot[1][2]*rot[2][1])/ (rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
+ tmp = (rot[2]*rot[2]+rot[5]*rot[5]);\r
+ sinc = (rot[7]*rot[2]-rot[6]*rot[5])/ tmp;\r
+ cosc = -(rot[2]*rot[6]+rot[5]*rot[7])/ tmp;\r
+ //</Optimize>\r
+\r
+ if( cosc > 1.0 ) {\r
+ /* printf("cos(r) = %f\n", cosc); */\r
+ cosc = 1.0;\r
+ sinc = 0.0;\r
+ }\r
+ if( cosc < -1.0 ) {\r
+ /* printf("cos(r) = %f\n", cosc); */\r
+ cosc = -1.0;\r
+ sinc = 0.0;\r
+ }\r
+ if( sinc > 1.0 ) {\r
+ /* printf("sin(r) = %f\n", sinc); */\r
+ sinc = 1.0;\r
+ cosc = 0.0;\r
+ }\r
+ if( sinc < -1.0 ) {\r
+ /* printf("sin(r) = %f\n", sinc); */\r
+ sinc = -1.0;\r
+ cosc = 0.0;\r
+ }\r
+ c = Math.acos( cosc );\r
+ if( sinc < 0 ){\r
+ c = -c;\r
+ }\r
+ }else {\r
+ a = b = 0.0;\r
+ cosa = cosb = 1.0;\r
+ sina = sinb = 0.0;\r
+ cosc = rot[0];//<Optimize/>cosc = rot[0][0];\r
+ sinc = rot[1];//<Optimize/>sinc = rot[1][0];\r
+ if( cosc > 1.0 ) {\r
+ /* printf("cos(r) = %f\n", cosc); */\r
+ cosc = 1.0;\r
+ sinc = 0.0;\r
+ }\r
+ if( cosc < -1.0 ) {\r
+ /* printf("cos(r) = %f\n", cosc); */\r
+ cosc = -1.0;\r
+ sinc = 0.0;\r
+ }\r
+ if( sinc > 1.0 ) {\r
+ /* printf("sin(r) = %f\n", sinc); */\r
+ sinc = 1.0;\r
+ cosc = 0.0;\r
+ }\r
+ if( sinc < -1.0 ) {\r
+ /* printf("sin(r) = %f\n", sinc); */\r
+ sinc = -1.0;\r
+ cosc = 0.0;\r
+ }\r
+ c = Math.acos( cosc );\r
+ if( sinc < 0 ){\r
+ c = -c;\r
+ }\r
+ }\r
+ o_abc[0]=a;//wa.value=a;//*wa = a;\r
+ o_abc[1]=b;//wb.value=b;//*wb = b;\r
+ o_abc[2]=c;//wc.value=c;//*wc = c;\r
+ return 0;\r
+ } \r
+}\r
+\r
+/**\r
+ * NyARModifyMatrixの最適化バージョン1\r
+ * 配列の1次元化、計算ステップの圧縮等の最適化をしてみた。\r
+ *\r
+ */\r
+class NyARTransRot_O1 extends NyARTransRot_OptimizeCommon\r
+{\r
+ public NyARTransRot_O1(NyARParam i_param,int i_number_of_vertex) throws NyARException\r
+ {\r
+ super(i_param,i_number_of_vertex);\r
+ }\r
+ /**\r
+ * int arGetInitRot( ARMarkerInfo *marker_info, double cpara[3][4], double rot[3][3] )\r
+ * Optimize:2008.04.20:STEP[716→698]\r
+ * @param marker_info\r
+ * @param i_direction\r
+ * @param i_param\r
+ * @throws NyARException\r
+ */\r
+ public final void initRot(NyARSquare marker_info,int i_direction) throws NyARException\r
+ {\r
+ double cpara[]= cparam.get34Array();\r
+ double[][] wdir=new double[3][3];\r
+ double w, w1, w2, w3;\r
+ int dir;\r
+ int j;\r
+\r
+ dir = i_direction;\r
+\r
+ for( j = 0; j < 2; j++ ) {\r
+ w1 = marker_info.line[(4-dir+j)%4][0] * marker_info.line[(6-dir+j)%4][1]- marker_info.line[(6-dir+j)%4][0] * marker_info.line[(4-dir+j)%4][1];\r
+ w2 = marker_info.line[(4-dir+j)%4][1] * marker_info.line[(6-dir+j)%4][2]- marker_info.line[(6-dir+j)%4][1] * marker_info.line[(4-dir+j)%4][2];\r
+ w3 = marker_info.line[(4-dir+j)%4][2] * marker_info.line[(6-dir+j)%4][0]- marker_info.line[(6-dir+j)%4][2] * marker_info.line[(4-dir+j)%4][0];\r
+\r
+ wdir[j][0] = w1*(cpara[0*4+1]*cpara[1*4+2]-cpara[0*4+2]*cpara[1*4+1])+ w2*cpara[1*4+1]- w3*cpara[0*4+1];\r
+ wdir[j][1] = -w1*cpara[0*4+0]*cpara[1*4+2]+ w3*cpara[0*4+0];\r
+ wdir[j][2] = w1*cpara[0*4+0]*cpara[1*4+1];\r
+ w = Math.sqrt( wdir[j][0]*wdir[j][0]+ wdir[j][1]*wdir[j][1]+ wdir[j][2]*wdir[j][2] );\r
+ wdir[j][0] /= w;\r
+ wdir[j][1] /= w;\r
+ wdir[j][2] /= w;\r
+ }\r
+\r
+ //以下3ケースは、計算エラーのときは例外が発生する。\r
+ check_dir(wdir[0], marker_info.sqvertex[(4-dir)%4],marker_info.sqvertex[(5-dir)%4], cpara);\r
+\r
+ check_dir(wdir[1], marker_info.sqvertex[(7-dir)%4],marker_info.sqvertex[(4-dir)%4], cpara);\r
+\r
+ check_rotation(wdir);\r
+\r
+\r
+ wdir[2][0] = wdir[0][1]*wdir[1][2] - wdir[0][2]*wdir[1][1];\r
+ wdir[2][1] = wdir[0][2]*wdir[1][0] - wdir[0][0]*wdir[1][2];\r
+ wdir[2][2] = wdir[0][0]*wdir[1][1] - wdir[0][1]*wdir[1][0];\r
+ w = Math.sqrt( wdir[2][0]*wdir[2][0]+ wdir[2][1]*wdir[2][1]+ wdir[2][2]*wdir[2][2] );\r
+ wdir[2][0] /= w;\r
+ wdir[2][1] /= w;\r
+ wdir[2][2] /= w;\r
+ /*\r
+ if( wdir[2][2] < 0 ) {\r
+ wdir[2][0] /= -w;\r
+ wdir[2][1] /= -w;\r
+ wdir[2][2] /= -w;\r
+ }\r
+ else {\r
+ wdir[2][0] /= w;\r
+ wdir[2][1] /= w;\r
+ wdir[2][2] /= w;\r
+ }\r
+ */\r
+ //<Optimize>\r
+ //rot[0][0] = wdir[0][0];\r
+ //rot[1][0] = wdir[0][1];\r
+ //rot[2][0] = wdir[0][2];\r
+ //rot[0][1] = wdir[1][0];\r
+ //rot[1][1] = wdir[1][1];\r
+ //rot[2][1] = wdir[1][2];\r
+ //rot[0][2] = wdir[2][0];\r
+ //rot[1][2] = wdir[2][1];\r
+ //rot[2][2] = wdir[2][2];\r
+ double[] rot=this.array;\r
+ rot[0] = wdir[0][0];\r
+ rot[3] = wdir[0][1];\r
+ rot[6] = wdir[0][2];\r
+ rot[1] = wdir[1][0];\r
+ rot[4] = wdir[1][1];\r
+ rot[7] = wdir[1][2];\r
+ rot[2] = wdir[2][0];\r
+ rot[5] = wdir[2][1];\r
+ rot[8] = wdir[2][2];\r
+ //</Optimize> \r
+ }\r
+ private final double[] wk_arModifyMatrix_combo=new double[12];//[3][4];\r
+ private final double[] wk_arModifyMatrix_abc=new double[3];\r
+ private final double[] wk_arModifyMatrix_rot=new double[9];\r
+ /**\r
+ * Optimize:2008.04.20:STEP[456→-]\r
+ * @param rot\r
+ * [3x3]配列\r
+ * @param trans\r
+ * @param vertex\r
+ * @param pos2d\r
+ * @param num\r
+ * @return\r
+ */\r
+ public final double modifyMatrix(double trans[],double vertex[][], double pos2d[][]) throws NyARException\r
+ {\r
+ int num=this.number_of_vertex;\r
+ double factor;\r
+ double a1, b1, c1;\r
+ double a2, b2, c2;\r
+ double ma = 0.0, mb = 0.0, mc = 0.0;\r
+ double hx, hy, h, x, y;\r
+ double err, minerr=0;\r
+ int t1, t2, t3;\r
+ int s1 = 0, s2 = 0, s3 = 0;\r
+ int i, j;\r
+ double[] combo=this.wk_arModifyMatrix_combo;//arGetNewMatrixで初期化されるので初期化不要//new double[3][4];\r
+ double[] abc=wk_arModifyMatrix_abc;\r
+ double[] rot=wk_arModifyMatrix_rot;\r
+\r
+ arGetAngle(abc);//arGetAngle( rot, &a, &b, &c );\r
+ a2 = abc[0];\r
+ b2 = abc[1];\r
+ c2 = abc[2];\r
+ factor = 10.0*Math.PI/180.0;\r
+ for( j = 0; j < 10; j++ ) {\r
+ minerr = 1000000000.0;\r
+ for(t1=-1;t1<=1;t1++) {\r
+ for(t2=-1;t2<=1;t2++) {\r
+ for(t3=-1;t3<=1;t3++) {\r
+ a1 = a2 + factor*t1;\r
+ b1 = b2 + factor*t2;\r
+ c1 = c2 + factor*t3;\r
+ arGetRot( a1, b1, c1,rot);\r
+ arGetNewMatrix(rot,trans, null, combo );\r
+ err = 0.0;\r
+ for( i = 0; i < num; i++ ) {\r
+ hx = combo[0] * vertex[i][0]+ combo[1] * vertex[i][1]+ combo[2] * vertex[i][2]+ combo[3];\r
+ hy = combo[4] * vertex[i][0]+ combo[5] * vertex[i][1]+ combo[6] * vertex[i][2]+ combo[7];\r
+ h = combo[8] * vertex[i][0]+ combo[9] * vertex[i][1]+ combo[10] * vertex[i][2]+ combo[11];\r
+ x = hx / h;\r
+ y = hy / h;\r
+ err += (pos2d[i][0] - x) * (pos2d[i][0] - x)+ (pos2d[i][1] - y) * (pos2d[i][1] - y);\r
+ }\r
+ if( err < minerr ) {\r
+ minerr = err;\r
+ ma = a1;\r
+ mb = b1;\r
+ mc = c1;\r
+ s1 = t1;\r
+ s2 = t2;\r
+ s3 = t3;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if( s1 == 0 && s2 == 0 && s3 == 0 ){\r
+ factor *= 0.5;\r
+ }\r
+ a2 = ma;\r
+ b2 = mb;\r
+ c2 = mc;\r
+ }\r
+ arGetRot(ma, mb, mc,this.array);\r
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+ return minerr/num;\r
+ }\r
+ private final double[] wk_cpara2_arGetNewMatrix=new double[12];//[3][4];\r
+ /**\r
+ * Optimize:2008.04.20:STEP[569->432]\r
+ * @param i_rot\r
+ * [9]\r
+ * @param trans\r
+ * @param trans2\r
+ * @param ret\r
+ * double[3x4]配列\r
+ * @return\r
+ */\r
+ private final int arGetNewMatrix(double[] i_rot,double trans[], double trans2[][], double ret[]) throws NyARException\r
+ {\r
+ final double cpara[]=cparam.get34Array();\r
+ final double[] cpara2; //この関数で初期化される。\r
+ int j,j_idx;\r
+// double[] cpara_pt;\r
+ //cparaの2次元配列→1次元に変換して計算\r
+ if( trans2 != null ) {\r
+ cpara2=wk_cpara2_arGetNewMatrix; //この関数で初期化される。\r
+\r
+ for( j = 0; j < 3; j++ ) {\r
+// Optimize(使わないから最適化してない)\r
+ NyARException.trap("未チェックのパス");\r
+ cpara2[j*4+0] = cpara[j*4+0] * trans2[0][0]+ cpara[j*4+1] * trans2[1][0]+ cpara[j*4+2] * trans2[2][0];\r
+ cpara2[j*4+1] = cpara[j*4+0] * trans2[0][1]+ cpara[j*4+1] * trans2[1][1]+ cpara[j*4+2] * trans2[2][1];\r
+ cpara2[j*4+2] = cpara[j*4+0] * trans2[0][2]+ cpara[j*4+1] * trans2[1][2]+ cpara[j*4+2] * trans2[2][2];\r
+ cpara2[j*4+3] = cpara[j*4+0] * trans2[0][3]+ cpara[j*4+1] * trans2[1][3]+ cpara[j*4+2] * trans2[2][3];\r
+ }\r
+ }else{\r
+ cpara2=cpara;//cparaの値をそのまま使う\r
+ }\r
+ for( j = 0; j < 3; j++ ) {\r
+ //cpara2_pt=cpara2[j];\r
+ j_idx=j*4;\r
+ //<Optimize>\r
+ //ret[j][0] = cpara2_pt[0] * rot[0][0]+ cpara2_pt[1] * rot[1][0]+ cpara2_pt[2] * rot[2][0];\r
+ //ret[j][1] = cpara2_pt[0] * rot[0][1]+ cpara2_pt[1] * rot[1][1]+ cpara2_pt[2] * rot[2][1];\r
+ //ret[j][2] = cpara2_pt[0] * rot[0][2]+ cpara2_pt[1] * rot[1][2]+ cpara2_pt[2] * rot[2][2];\r
+ //ret[j][3] = cpara2_pt[0] * trans[0]+ cpara2_pt[1] * trans[1]+ cpara2_pt[2] * trans[2]+ cpara2_pt[3];\r
+ ret[j_idx+0] = cpara2[j_idx+0] * i_rot[0]+ cpara2[j_idx+1] * i_rot[3]+ cpara2[j_idx+2] * i_rot[6];\r
+ ret[j_idx+1] = cpara2[j_idx+0] * i_rot[1]+ cpara2[j_idx+1] * i_rot[4]+ cpara2[j_idx+2] * i_rot[7];\r
+ ret[j_idx+2] = cpara2[j_idx+0] * i_rot[2]+ cpara2[j_idx+1] * i_rot[5]+ cpara2[j_idx+2] * i_rot[8];\r
+ ret[j_idx+3] = cpara2[j_idx+0] * trans[0]+ cpara2[j_idx+1] * trans[1]+ cpara2[j_idx+2] * trans[2]+ cpara2[j_idx+3];\r
+ //</Optimize>\r
+ }\r
+ return(0);\r
+ } \r
+}\r
+\r
+/**\r
+ * NyARModifyMatrixの最適化バージョン2\r
+ * 計算手順の変更、構造変更など含む最適化をしたもの\r
+ *\r
+ */\r
+class NyARTransRot_O2 extends NyARTransRot_OptimizeCommon\r
+{\r
+ public NyARTransRot_O2(NyARParam i_param,int i_number_of_vertex) throws NyARException\r
+ {\r
+ super(i_param,i_number_of_vertex);\r
+ } \r
+ \r
+ //private double CACA,SASA,SACA,CA,SA; \r
+ private double CACA,SASA,SACA,CA,SA;\r
+ final public void arGetRotA( double a)\r
+ {\r
+ double sina,cosa;\r
+ sina = Math.sin(a);\r
+ cosa = Math.cos(a);\r
+ //Optimize\r
+ CACA=cosa*cosa;\r
+ SASA=sina*sina;\r
+ SACA=sina*cosa;\r
+ CA=cosa;\r
+ SA=sina;\r
+ }\r
+ private double CACACB,SACACB,SASACB,CASB,SASB;\r
+ final public void arGetRotB(double b,double[] o_rot)\r
+ {\r
+ double sinb,cosb;\r
+ sinb = Math.sin(b);\r
+ cosb = Math.cos(b);\r
+ CACACB=CACA*cosb;\r
+ SACACB=SACA*cosb;\r
+ SASACB=SASA*cosb;\r
+ CASB=CA*sinb;\r
+ SASB=SA*sinb;\r
+ o_rot[2] = CASB;\r
+ o_rot[5] = SASB;\r
+ o_rot[8] = cosb;\r
+ }\r
+ /**\r
+ * 分割arGetRot\r
+ * @param c\r
+ */\r
+ public final void arGetRotC(double c,double[] o_rot)\r
+ {\r
+ double sinc,cosc;\r
+ sinc = Math.sin(c);\r
+ cosc = Math.cos(c);\r
+ double SACASC,SACACBSC,SACACBCC,SACACC;\r
+ SACASC=SACA*sinc;\r
+ SACACC=SACA*cosc;\r
+ SACACBSC=SACACB*sinc;\r
+ SACACBCC=SACACB*cosc;\r
+ o_rot[0] = CACACB*cosc+SASA*cosc+SACACBSC-SACASC;\r
+ o_rot[1] = -CACACB*sinc-SASA*sinc+SACACBCC-SACACC;\r
+ o_rot[3] = SACACBCC-SACACC+SASACB*sinc+CACA*sinc;\r
+ o_rot[4] = -SACACBSC+SACASC+SASACB*cosc+CACA*cosc;\r
+ o_rot[6] = -CASB*cosc-SASB*sinc;\r
+ o_rot[7] = CASB*sinc-SASB*cosc;\r
+ }\r
+ private final double[][] wk_initRot_wdir=new double[3][3];\r
+ /**\r
+ * int arGetInitRot( ARMarkerInfo *marker_info, double cpara[3][4], double rot[3][3] )\r
+ * Optimize:2008.04.20:STEP[716→698]\r
+ * @param marker_info\r
+ * @param i_direction\r
+ * @param i_param\r
+ * @throws NyARException\r
+ */\r
+ public void initRot(NyARSquare marker_info,int i_direction) throws NyARException\r
+ {\r
+ double cpara[]= cparam.get34Array();\r
+ double[][] wdir=wk_initRot_wdir;//この関数で初期化される\r
+ double w, w1, w2, w3;\r
+ int dir;\r
+ int j;\r
+\r
+ dir = i_direction;\r
+\r
+ for( j = 0; j < 2; j++ ) {\r
+ w1 = marker_info.line[(4-dir+j)%4][0] * marker_info.line[(6-dir+j)%4][1]- marker_info.line[(6-dir+j)%4][0] * marker_info.line[(4-dir+j)%4][1];\r
+ w2 = marker_info.line[(4-dir+j)%4][1] * marker_info.line[(6-dir+j)%4][2]- marker_info.line[(6-dir+j)%4][1] * marker_info.line[(4-dir+j)%4][2];\r
+ w3 = marker_info.line[(4-dir+j)%4][2] * marker_info.line[(6-dir+j)%4][0]- marker_info.line[(6-dir+j)%4][2] * marker_info.line[(4-dir+j)%4][0];\r
+\r
+ wdir[j][0] = w1*(cpara[0*4+1]*cpara[1*4+2]-cpara[0*4+2]*cpara[1*4+1])+ w2*cpara[1*4+1]- w3*cpara[0*4+1];\r
+ wdir[j][1] = -w1*cpara[0*4+0]*cpara[1*4+2]+ w3*cpara[0*4+0];\r
+ wdir[j][2] = w1*cpara[0*4+0]*cpara[1*4+1];\r
+ w = Math.sqrt( wdir[j][0]*wdir[j][0]+ wdir[j][1]*wdir[j][1]+ wdir[j][2]*wdir[j][2] );\r
+ wdir[j][0] /= w;\r
+ wdir[j][1] /= w;\r
+ wdir[j][2] /= w;\r
+ }\r
+\r
+ //以下3ケースは、計算エラーのときは例外が発生する。\r
+ check_dir(wdir[0], marker_info.sqvertex[(4-dir)%4],marker_info.sqvertex[(5-dir)%4], cpara);\r
+\r
+ check_dir(wdir[1], marker_info.sqvertex[(7-dir)%4],marker_info.sqvertex[(4-dir)%4], cpara);\r
+\r
+ check_rotation(wdir);\r
+\r
+\r
+ wdir[2][0] = wdir[0][1]*wdir[1][2] - wdir[0][2]*wdir[1][1];\r
+ wdir[2][1] = wdir[0][2]*wdir[1][0] - wdir[0][0]*wdir[1][2];\r
+ wdir[2][2] = wdir[0][0]*wdir[1][1] - wdir[0][1]*wdir[1][0];\r
+ w = Math.sqrt( wdir[2][0]*wdir[2][0]+ wdir[2][1]*wdir[2][1]+ wdir[2][2]*wdir[2][2] );\r
+ wdir[2][0] /= w;\r
+ wdir[2][1] /= w;\r
+ wdir[2][2] /= w;\r
+ //<Optimize>\r
+ //rot[0][0] = wdir[0][0];\r
+ //rot[1][0] = wdir[0][1];\r
+ //rot[2][0] = wdir[0][2];\r
+ //rot[0][1] = wdir[1][0];\r
+ //rot[1][1] = wdir[1][1];\r
+ //rot[2][1] = wdir[1][2];\r
+ //rot[0][2] = wdir[2][0];\r
+ //rot[1][2] = wdir[2][1];\r
+ //rot[2][2] = wdir[2][2];\r
+ double[] rot=this.array;\r
+ rot[0] = wdir[0][0];\r
+ rot[3] = wdir[0][1];\r
+ rot[6] = wdir[0][2];\r
+ rot[1] = wdir[1][0];\r
+ rot[4] = wdir[1][1];\r
+ rot[7] = wdir[1][2];\r
+ rot[2] = wdir[2][0];\r
+ rot[5] = wdir[2][1];\r
+ rot[8] = wdir[2][2];\r
+ //</Optimize> \r
+ }\r
+ private final double[] wk_arModifyMatrix_combo=new double[12];//[3][4];\r
+ private final double[] wk_arModifyMatrix_abc=new double[3];\r
+ private final double[] wk_arModifyMatrix_rot=new double[9]; \r
+ /**\r
+ * arGetRot計算を階層化したModifyMatrix\r
+ * @param nyrot\r
+ * @param trans\r
+ * @param vertex\r
+ * @param pos2d\r
+ * @param num\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double modifyMatrix(double trans[],double vertex[][], double pos2d[][]) throws NyARException\r
+ {\r
+ int num=this.number_of_vertex;\r
+ double factor;\r
+ double a1, b1, c1;\r
+ double a2, b2, c2;\r
+ double ma = 0.0, mb = 0.0, mc = 0.0;\r
+ double hx, hy, h, x, y;\r
+ double err, minerr=0;\r
+ int t1, t2, t3;\r
+ int s1 = 0, s2 = 0, s3 = 0;\r
+ int i, j;\r
+ final double[] combo=this.wk_arModifyMatrix_combo;//arGetNewMatrixで初期化されるので初期化不要//new double[3][4];\r
+ final double[] abc=wk_arModifyMatrix_abc;\r
+ double[] rot=wk_arModifyMatrix_rot;\r
+\r
+ arGetAngle(abc);//arGetAngle( rot, &a, &b, &c );\r
+ a2 = abc[0];\r
+ b2 = abc[1];\r
+ c2 = abc[2];\r
+ factor = 10.0*Math.PI/180.0;\r
+\r
+ nyatla_arGetNewMatrix_row3(trans,combo);//comboの3行目を先に計算\r
+ for( j = 0; j < 10; j++ ) {\r
+ minerr = 1000000000.0;\r
+ for(t1=-1;t1<=1;t1++) {\r
+ a1 = a2 + factor*t1;\r
+ arGetRotA(a1);\r
+ for(t2=-1;t2<=1;t2++) {\r
+ b1 = b2 + factor*t2;\r
+ arGetRotB(b1,rot);\r
+ for(t3=-1;t3<=1;t3++) {\r
+ c1 = c2 + factor*t3;\r
+ arGetRotC(c1,rot);\r
+ //comboの0-2行目を計算\r
+ nyatla_arGetNewMatrix_row012(rot,trans,combo);//第二パラメタは常にnull//arGetNewMatrix(trans, null, combo );\r
+ err = 0.0;\r
+ for( i = 0; i < num; i++ ) {\r
+ hx = combo[0] * vertex[i][0]+ combo[1] * vertex[i][1]+ combo[2] * vertex[i][2]+ combo[3];\r
+ hy = combo[4] * vertex[i][0]+ combo[5] * vertex[i][1]+ combo[6] * vertex[i][2]+ combo[7];\r
+ h = combo[8] * vertex[i][0]+ combo[9] * vertex[i][1]+ combo[10] * vertex[i][2]+ combo[11];\r
+ x = hx / h;\r
+ y = hy / h;\r
+ err += (pos2d[i][0] - x) * (pos2d[i][0] - x)+ (pos2d[i][1] - y) * (pos2d[i][1] - y);\r
+ }\r
+ if( err < minerr ) {\r
+ minerr = err;\r
+ ma = a1;\r
+ mb = b1;\r
+ mc = c1;\r
+ s1 = t1;\r
+ s2 = t2;\r
+ s3 = t3;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if( s1 == 0 && s2 == 0 && s3 == 0 ){\r
+ factor *= 0.5;\r
+ }\r
+ a2 = ma;\r
+ b2 = mb;\r
+ c2 = mc;\r
+ }\r
+ arGetRot(ma,mb,mc,this.array);\r
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+ return minerr/num;\r
+ }\r
+ /**\r
+ * arGetNewMatrixの0-2行目を初期化する関数\r
+ * Optimize:2008.04.20:STEP[569->144]\r
+ * @param i_rot\r
+ * @param trans\r
+ * @param trans2\r
+ * @param ret\r
+ * double[3x4]配列\r
+ * @return\r
+ */\r
+ private final void nyatla_arGetNewMatrix_row012(double i_rot[],double trans[],double ret[]) throws NyARException\r
+ {\r
+ int j;\r
+ double c0,c1,c2;\r
+ final double cpara2[]=cparam.get34Array();\r
+ for( j = 0; j < 3; j++ ) {\r
+ //cpara2_pt=cpara2[j];\r
+ c0=cpara2[j*4+0];\r
+ c1=cpara2[j*4+1];\r
+ c2=cpara2[j*4+2];\r
+ ret[j*4+0] = c0 * i_rot[0]+ c1 * i_rot[3]+ c2 * i_rot[6];\r
+ ret[j*4+1] = c0 * i_rot[1]+ c1 * i_rot[4]+ c2 * i_rot[7];\r
+ ret[j*4+2] = c0 * i_rot[2]+ c1 * i_rot[5]+ c2 * i_rot[8];\r
+ //</Optimize>\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * arGetNewMatrixの3行目を初期化する関数\r
+ * @param trans\r
+ * @param ret\r
+ * @throws NyARException\r
+ */\r
+ private final void nyatla_arGetNewMatrix_row3(double trans[],double ret[]) throws NyARException\r
+ {\r
+ final double cpara2[]=cparam.get34Array();\r
+ int j,j_idx;\r
+ for( j = 0; j < 3; j++ ) {\r
+ j_idx=j*4;\r
+ ret[j_idx+3] = cpara2[j_idx+0] * trans[0]+ cpara2[j_idx+1] * trans[1]+ cpara2[j_idx+2] * trans[2]+ cpara2[j_idx+3];\r
+ }\r
+ return;\r
+ } \r
+}\r
+\r
+\r
+/**\r
+ * NyARModifyMatrixの最適化バージョン3\r
+ * O3版の演算テーブル版\r
+ * 計算速度のみを追求する\r
+ *\r
+ */\r
+class NyARTransRot_O3 extends NyARTransRot_OptimizeCommon\r
+{\r
+ public NyARTransRot_O3(NyARParam i_param,int i_number_of_vertex) throws NyARException\r
+ {\r
+ super(i_param,i_number_of_vertex);\r
+ if(i_number_of_vertex!=4){\r
+ //4以外の頂点数は処理しない\r
+ throw new NyARException();\r
+ }\r
+ } \r
+ \r
+ //private double CACA,SASA,SACA,CA,SA; \r
+ private final double[][] wk_initRot_wdir=new double[3][3];\r
+ /**\r
+ * int arGetInitRot( ARMarkerInfo *marker_info, double cpara[3][4], double rot[3][3] )\r
+ * Optimize:2008.04.20:STEP[716→698]\r
+ * @param marker_info\r
+ * @param i_direction\r
+ * @param i_param\r
+ * @throws NyARException\r
+ */\r
+ public void initRot(NyARSquare marker_info,int i_direction) throws NyARException\r
+ {\r
+ double cpara[]= cparam.get34Array();\r
+ double[][] wdir=wk_initRot_wdir;//この関数で初期化される\r
+ double w, w1, w2, w3;\r
+ int dir;\r
+ int j;\r
+\r
+ dir = i_direction;\r
+\r
+ for( j = 0; j < 2; j++ ) {\r
+ w1 = marker_info.line[(4-dir+j)%4][0] * marker_info.line[(6-dir+j)%4][1]- marker_info.line[(6-dir+j)%4][0] * marker_info.line[(4-dir+j)%4][1];\r
+ w2 = marker_info.line[(4-dir+j)%4][1] * marker_info.line[(6-dir+j)%4][2]- marker_info.line[(6-dir+j)%4][1] * marker_info.line[(4-dir+j)%4][2];\r
+ w3 = marker_info.line[(4-dir+j)%4][2] * marker_info.line[(6-dir+j)%4][0]- marker_info.line[(6-dir+j)%4][2] * marker_info.line[(4-dir+j)%4][0];\r
+\r
+ wdir[j][0] = w1*(cpara[0*4+1]*cpara[1*4+2]-cpara[0*4+2]*cpara[1*4+1])+ w2*cpara[1*4+1]- w3*cpara[0*4+1];\r
+ wdir[j][1] = -w1*cpara[0*4+0]*cpara[1*4+2]+ w3*cpara[0*4+0];\r
+ wdir[j][2] = w1*cpara[0*4+0]*cpara[1*4+1];\r
+ w = Math.sqrt( wdir[j][0]*wdir[j][0]+ wdir[j][1]*wdir[j][1]+ wdir[j][2]*wdir[j][2] );\r
+ wdir[j][0] /= w;\r
+ wdir[j][1] /= w;\r
+ wdir[j][2] /= w;\r
+ }\r
+\r
+ //以下3ケースは、計算エラーのときは例外が発生する。\r
+ check_dir(wdir[0], marker_info.sqvertex[(4-dir)%4],marker_info.sqvertex[(5-dir)%4], cpara);\r
+\r
+ check_dir(wdir[1], marker_info.sqvertex[(7-dir)%4],marker_info.sqvertex[(4-dir)%4], cpara);\r
+\r
+ check_rotation(wdir);\r
+\r
+\r
+ wdir[2][0] = wdir[0][1]*wdir[1][2] - wdir[0][2]*wdir[1][1];\r
+ wdir[2][1] = wdir[0][2]*wdir[1][0] - wdir[0][0]*wdir[1][2];\r
+ wdir[2][2] = wdir[0][0]*wdir[1][1] - wdir[0][1]*wdir[1][0];\r
+ w = Math.sqrt( wdir[2][0]*wdir[2][0]+ wdir[2][1]*wdir[2][1]+ wdir[2][2]*wdir[2][2] );\r
+ wdir[2][0] /= w;\r
+ wdir[2][1] /= w;\r
+ wdir[2][2] /= w;\r
+ double[] rot=this.array;\r
+ rot[0] = wdir[0][0];\r
+ rot[3] = wdir[0][1];\r
+ rot[6] = wdir[0][2];\r
+ rot[1] = wdir[1][0];\r
+ rot[4] = wdir[1][1];\r
+ rot[7] = wdir[1][2];\r
+ rot[2] = wdir[2][0];\r
+ rot[5] = wdir[2][1];\r
+ rot[8] = wdir[2][2];\r
+ //</Optimize> \r
+ }\r
+ private final double[][] wk_arModifyMatrix_double1D=new double[8][3];\r
+ /**\r
+ * arGetRot計算を階層化したModifyMatrix\r
+ * 896\r
+ * @param nyrot\r
+ * @param trans\r
+ * @param vertex\r
+ * [m][3]\r
+ * @param pos2d\r
+ * [n][2]\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double modifyMatrix(double trans[],double vertex[][], double pos2d[][]) throws NyARException\r
+ {\r
+ double factor;\r
+ double a2, b2, c2;\r
+ double ma = 0.0, mb = 0.0, mc = 0.0;\r
+ double h, x, y;\r
+ double err, minerr=0;\r
+ int t1, t2, t3;\r
+ int s1 = 0, s2 = 0, s3 = 0;\r
+\r
+ factor = 10.0*Math.PI/180.0;\r
+ double rot0,rot1,rot3,rot4,rot6,rot7;\r
+ double combo00,combo01,combo02,combo03,combo10,combo11,combo12,combo13,combo20,combo21,combo22,combo23;\r
+ double combo02_2,combo02_5,combo02_8,combo02_11;\r
+ double combo22_2,combo22_5,combo22_8,combo22_11;\r
+ double combo12_2,combo12_5,combo12_8,combo12_11;\r
+ //vertex展開\r
+ final double VX00,VX01,VX02,VX10,VX11,VX12,VX20,VX21,VX22,VX30,VX31,VX32;\r
+ double[] d_pt;\r
+ d_pt=vertex[0];VX00=d_pt[0];VX01=d_pt[1];VX02=d_pt[2];\r
+ d_pt=vertex[1];VX10=d_pt[0];VX11=d_pt[1];VX12=d_pt[2];\r
+ d_pt=vertex[2];VX20=d_pt[0];VX21=d_pt[1];VX22=d_pt[2];\r
+ d_pt=vertex[3];VX30=d_pt[0];VX31=d_pt[1];VX32=d_pt[2];\r
+ final double P2D00,P2D01,P2D10,P2D11,P2D20,P2D21,P2D30,P2D31;\r
+ d_pt=pos2d[0];P2D00=d_pt[0];P2D01=d_pt[1];\r
+ d_pt=pos2d[1];P2D10=d_pt[0];P2D11=d_pt[1];\r
+ d_pt=pos2d[2];P2D20=d_pt[0];P2D21=d_pt[1];\r
+ d_pt=pos2d[3];P2D30=d_pt[0];P2D31=d_pt[1];\r
+ final double cpara[]=cparam.get34Array();\r
+ final double CP0,CP1,CP2,CP3,CP4,CP5,CP6,CP7,CP8,CP9,CP10;\r
+ CP0=cpara[0];CP1=cpara[1];CP2=cpara[2];CP3=cpara[3];\r
+ CP4=cpara[4];CP5=cpara[5];CP6=cpara[6];CP7=cpara[7];\r
+ CP8=cpara[8];CP9=cpara[9];CP10=cpara[10];\r
+ combo03 = CP0 * trans[0]+ CP1 * trans[1]+ CP2 * trans[2]+ CP3;\r
+ combo13 = CP4 * trans[0]+ CP5 * trans[1]+ CP6 * trans[2]+ CP7;\r
+ combo23 = CP8 * trans[0]+ CP9 * trans[1]+ CP10 * trans[2]+ cpara[11];\r
+ double CACA,SASA,SACA,CA,SA;\r
+ double CACACB,SACACB,SASACB,CASB,SASB;\r
+ double SACASC,SACACBSC,SACACBCC,SACACC; \r
+ final double[][] double1D=this.wk_arModifyMatrix_double1D;\r
+\r
+ final double[] abc =double1D[0];\r
+ final double[] a_factor=double1D[1];\r
+ final double[] sinb =double1D[2];\r
+ final double[] cosb =double1D[3];\r
+ final double[] b_factor=double1D[4];\r
+ final double[] sinc =double1D[5];\r
+ final double[] cosc =double1D[6];\r
+ final double[] c_factor=double1D[7];\r
+ double w,w2;\r
+ double wsin,wcos;\r
+\r
+ arGetAngle(abc);//arGetAngle( rot, &a, &b, &c );\r
+ a2 = abc[0];\r
+ b2 = abc[1];\r
+ c2 = abc[2];\r
+ \r
+ //comboの3行目を先に計算\r
+ for(int i = 0; i < 10; i++ ) {\r
+ minerr = 1000000000.0;\r
+ //sin-cosテーブルを計算(これが外に出せるとは…。)\r
+ for(int j=0;j<3;j++){\r
+ w2=factor*(j-1);\r
+ w= a2 + w2;\r
+ a_factor[j]=w;\r
+ w= b2 + w2;\r
+ b_factor[j]=w;\r
+ sinb[j]=Math.sin(w);\r
+ cosb[j]=Math.cos(w);\r
+ w= c2 + w2;\r
+ c_factor[j]=w;\r
+ sinc[j]=Math.sin(w);\r
+ cosc[j]=Math.cos(w);\r
+ }\r
+ //\r
+ for(t1=0;t1<3;t1++) {\r
+ SA = Math.sin(a_factor[t1]);\r
+ CA = Math.cos(a_factor[t1]);\r
+ //Optimize\r
+ CACA=CA*CA;\r
+ SASA=SA*SA;\r
+ SACA=SA*CA;\r
+ for(t2=0;t2<3;t2++) {\r
+ wsin=sinb[t2];\r
+ wcos=cosb[t2];\r
+ CACACB=CACA*wcos;\r
+ SACACB=SACA*wcos;\r
+ SASACB=SASA*wcos;\r
+ CASB=CA*wsin;\r
+ SASB=SA*wsin;\r
+ //comboの計算1\r
+ combo02 = CP0 * CASB+ CP1 * SASB+ CP2 * wcos;\r
+ combo12 = CP4 * CASB+ CP5 * SASB+ CP6 * wcos;\r
+ combo22 = CP8 * CASB+ CP9 * SASB+ CP10 * wcos;\r
+\r
+ combo02_2 =combo02 * VX02 + combo03;\r
+ combo02_5 =combo02 * VX12 + combo03;\r
+ combo02_8 =combo02 * VX22 + combo03;\r
+ combo02_11=combo02 * VX32 + combo03;\r
+ combo12_2 =combo12 * VX02 + combo13;\r
+ combo12_5 =combo12 * VX12 + combo13;\r
+ combo12_8 =combo12 * VX22 + combo13;\r
+ combo12_11=combo12 * VX32 + combo13;\r
+ combo22_2 =combo22 * VX02 + combo23;\r
+ combo22_5 =combo22 * VX12 + combo23;\r
+ combo22_8 =combo22 * VX22 + combo23;\r
+ combo22_11=combo22 * VX32 + combo23; \r
+ for(t3=0;t3<3;t3++){\r
+ wsin=sinc[t3];\r
+ wcos=cosc[t3]; \r
+ SACASC=SACA*wsin;\r
+ SACACC=SACA*wcos;\r
+ SACACBSC=SACACB*wsin;\r
+ SACACBCC=SACACB*wcos;\r
+\r
+ rot0 = CACACB*wcos+SASA*wcos+SACACBSC-SACASC;\r
+ rot3 = SACACBCC-SACACC+SASACB*wsin+CACA*wsin;\r
+ rot6 = -CASB*wcos-SASB*wsin;\r
+\r
+ combo00 = CP0 * rot0+ CP1 * rot3+ CP2 * rot6;\r
+ combo10 = CP4 * rot0+ CP5 * rot3+ CP6 * rot6;\r
+ combo20 = CP8 * rot0+ CP9 * rot3+ CP10 * rot6;\r
+\r
+ rot1 = -CACACB*wsin-SASA*wsin+SACACBCC-SACACC;\r
+ rot4 = -SACACBSC+SACASC+SASACB*wcos+CACA*wcos;\r
+ rot7 = CASB*wsin-SASB*wcos;\r
+ combo01 = CP0 * rot1+ CP1 * rot4+ CP2 * rot7;\r
+ combo11 = CP4 * rot1+ CP5 * rot4+ CP6 * rot7;\r
+ combo21 = CP8 * rot1+ CP9 * rot4+ CP10 * rot7;\r
+ //\r
+ err = 0.0;\r
+ h = combo20 * VX00+ combo21 * VX01+ combo22_2;\r
+ x = P2D00 - (combo00 * VX00+ combo01 * VX01+ combo02_2) / h;\r
+ y = P2D01 - (combo10 * VX00+ combo11 * VX01+ combo12_2) / h;\r
+ err += x*x+y*y;\r
+ h = combo20 * VX10+ combo21 * VX11+ combo22_5;\r
+ x = P2D10 - (combo00 * VX10+ combo01 * VX11+ combo02_5) / h;\r
+ y = P2D11 - (combo10 * VX10+ combo11 * VX11+ combo12_5) / h;\r
+ err += x*x+y*y;\r
+ h = combo20 * VX20+ combo21 * VX21+ combo22_8;\r
+ x = P2D20 - (combo00 * VX20+ combo01 * VX21+ combo02_8) / h;\r
+ y = P2D21 - (combo10 * VX20+ combo11 * VX21+ combo12_8) / h;\r
+ err += x*x+y*y;\r
+ h = combo20 * VX30+ combo21 * VX31+ combo22_11;\r
+ x = P2D30 - (combo00 * VX30+ combo01 * VX31+ combo02_11) / h;\r
+ y = P2D31 - (combo10 * VX30+ combo11 * VX31+ combo12_11) / h;\r
+ err += x*x+y*y;\r
+ if( err < minerr ) {\r
+ minerr = err;\r
+ ma = a_factor[t1];\r
+ mb = b_factor[t2];\r
+ mc = c_factor[t3];\r
+ s1 = t1-1;\r
+ s2 = t2-1;\r
+ s3 = t3-1;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if( s1 == 0 && s2 == 0 && s3 == 0 ){\r
+ factor *= 0.5;\r
+ }\r
+ a2 = ma;\r
+ b2 = mb;\r
+ c2 = mc;\r
+ }\r
+ arGetRot(ma,mb,mc,this.array);\r
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+ return minerr/4;\r
+ } \r
+}\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+public class NyARVec\r
+{\r
+ private int clm;\r
+ public NyARVec(int i_clm)\r
+ {\r
+ v=new double[i_clm];\r
+ clm=i_clm;\r
+ }\r
+ private double[] v;\r
+ /**\r
+ * i_clmサイズの列を格納できるように列サイズを変更します。\r
+ * 実行後、列の各値は不定になります。\r
+ * @param i_clm\r
+ */\r
+ public void realloc(int i_clm)\r
+ {\r
+ if(i_clm<=this.v.length)\r
+ {\r
+ //十分な配列があれば何もしない。\r
+ }else{\r
+ //不十分なら取り直す。\r
+ v=new double[i_clm];\r
+ }\r
+ this.clm=i_clm;\r
+ } \r
+ public int getClm()\r
+ {\r
+ return clm;\r
+ }\r
+ public double[] getArray()\r
+ {\r
+ return v;\r
+ }\r
+ /**\r
+ * arVecDispの代替品\r
+ * @param value\r
+ * @return\r
+ */\r
+ public int arVecDisp() throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ System.out.println(" === vector ("+clm+") ===\n");//printf(" === vector (%d) ===\n", v->clm);\r
+ System.out.print(" |");//printf(" |");\r
+ for(int c = 0; c < clm; c++ ){//for( c = 0; c < v->clm; c++ ){\r
+ System.out.print(" "+v[c]);//printf( " %10g", v->v[c] );\r
+ }\r
+ System.out.println(" |");//printf(" |\n");\r
+ System.out.println(" ===================");//printf(" ===================\n");\r
+ return 0;\r
+ }\r
+ /**\r
+ * arVecInnerproduct関数の代替品\r
+ * @param x\r
+ * @param y\r
+ * @param i_start\r
+ * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double vecInnerproduct(NyARVec y,int i_start) throws NyARException\r
+ {\r
+ NyARException.trap("この関数は動作確認できていません。"); \r
+ double result = 0.0;\r
+// double[] x_array=x.v;.getArray();\r
+// double[] y_array=y.getArray();\r
+ \r
+ if(this.clm!= y.clm){\r
+ throw new NyARException();//exit();\r
+ }\r
+ for(int i = i_start; i < this.clm; i++ ) {\r
+ NyARException.trap("未チェックのパス");\r
+ result += this.v[i] * y.v[i];//result += x->v[i] * y->v[i];\r
+ } \r
+ return result;\r
+ }\r
+ /**\r
+ * double arVecHousehold関数の代替品\r
+ * @param x\r
+ * @param i_start\r
+ * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double vecHousehold(int i_start) throws NyARException\r
+ {\r
+ NyARException.trap("この関数は動作確認できていません。");\r
+ double s, t;\r
+ s = Math.sqrt(this.vecInnerproduct(this,i_start));\r
+// double[] x_array=x.getArray();\r
+ if( s != 0.0 ){\r
+ NyARException.trap("未チェックのパス");\r
+ if(this.v[i_start]< 0){\r
+ s = -s;\r
+ }\r
+ NyARException.trap("未チェックのパス");{\r
+ this.v[i_start]+=s;//x->v[0] += s;\r
+ t = 1 / Math.sqrt(this.v[i_start]* s);//t = 1 / sqrt(x->v[0] * s);\r
+ }\r
+ for(int i = i_start; i < this.clm; i++){\r
+ NyARException.trap("未チェックのパス");\r
+ this.v[i]*=t;//x->v[i] *= t;\r
+ }\r
+ }\r
+ return -s;\r
+ }\r
+// /**\r
+// * arVecTridiagonalize関数の代替品\r
+// * a,d,e間で演算をしてる。何をどうしているかはさっぱりさっぱり\r
+// * @param a\r
+// * @param d\r
+// * @param e\r
+// * @param i_e_start\r
+// * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)\r
+// * @return\r
+// * @throws NyARException\r
+// */\r
+// public static void vecTridiagonalize(NyARMat a, NyARVec d, NyARVec e,int i_e_start) throws NyARException\r
+// {\r
+// NyARVec vec,vec2;\r
+// double[][] a_array=a.getArray();\r
+// double s, t, p, q;\r
+// int dim;\r
+//\r
+// if(a.getClm()!=a.getRow()){\r
+// throw new NyARException();\r
+// }\r
+// if(a.getClm() != d.clm){\r
+// throw new NyARException();\r
+// }\r
+// if(a.getClm() != e.clm){\r
+// throw new NyARException();\r
+// }\r
+// dim = a.getClm();\r
+//\r
+// for(int k = 0; k < dim-2; k++ ){\r
+// vec=a.getRowVec(k);\r
+//// double[] vec_array=vec.getArray();\r
+// NyARException.trap("未チェックパス"); \r
+// d.v[k]=vec.v[k];//d.set(k,v.get(k)); //d->v[k] = v[k];\r
+//\r
+// //wv1.clm = dim-k-1;\r
+// //wv1.v = &(v[k+1]);\r
+// NyARException.trap("未チェックパス"); \r
+// e.v[k+i_e_start]=vec.vecHousehold(k+1);//e->v[k] = arVecHousehold(&wv1);\r
+// if(e.v[k+i_e_start]== 0.0 ){\r
+// continue;\r
+// }\r
+//\r
+// for(int i = k+1; i < dim; i++ ){\r
+// s = 0.0;\r
+// for(int j = k+1; j < i; j++ ) {\r
+// NyARException.trap("未チェックのパス");\r
+// s += a_array[j][i] * vec.v[j];//s += a.get(j*dim+i) * v.get(j);//s += a->m[j*dim+i] * v[j];\r
+// }\r
+// for(int j = i; j < dim; j++ ) {\r
+// NyARException.trap("未チェックのパス");\r
+// s += a_array[i][j] * vec.v[j];//s += a.get(i*dim+j) * v.get(j);//s += a->m[i*dim+j] * v[j];\r
+// }\r
+// NyARException.trap("未チェックのパス");\r
+// d.v[i]=s;//d->v[i] = s;\r
+// }\r
+//\r
+//\r
+// //wv1.clm = wv2.clm = dim-k-1;\r
+// //wv1.v = &(v[k+1]);\r
+// //wv2.v = &(d->v[k+1]);\r
+// vec=a.getRowVec(k);\r
+//// vec_array=vec.getArray();\r
+// NyARException.trap("未チェックパス"); \r
+// t = vec.vecInnerproduct(d,k+1)/ 2;\r
+// for(int i = dim-1; i > k; i-- ) {\r
+// NyARException.trap("未チェックパス"); \r
+// p = vec.v[i];//p = v.get(i);//p = v[i];\r
+// d.v[i]-=t*p;q=d.v[i];//q = d->v[i] -= t*p;\r
+// for(int j = i; j < dim; j++ ){\r
+// NyARException.trap("未チェックパス"); \r
+// a_array[i][j]-=p*(d.v[j] + q*vec.v[j]);//a->m[i*dim+j] -= p*(d->v[j]) + q*v[j];\r
+// }\r
+// }\r
+// }\r
+//\r
+// if( dim >= 2) {\r
+// d.v[dim-2]=a_array[dim-2][dim-2];//d->v[dim-2] = a->m[(dim-2)*dim+(dim-2)];\r
+// e.v[dim-2+i_e_start]=a_array[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];\r
+// }\r
+//\r
+// if( dim >= 1 ){\r
+// d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] = a->m[(dim-1)*dim+(dim-1)];\r
+// }\r
+//\r
+// for(int k = dim-1; k >= 0; k--) {\r
+// vec=a.getRowVec(k);//v = a.getPointer(k*dim);//v = &(a->m[k*dim]);\r
+// if( k < dim-2 ) {\r
+// for(int i = k+1; i < dim; i++ ){\r
+// //wv1.clm = wv2.clm = dim-k-1;\r
+// //wv1.v = &(v[k+1]);\r
+// //wv2.v = &(a->m[i*dim+k+1]);\r
+// vec2=a.getRowVec(i);\r
+//\r
+// t = vec.vecInnerproduct(vec2,k+1);\r
+// for(int j = k+1; j < dim; j++ ){\r
+// NyARException.trap("未チェックパス"); \r
+// a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j] -= t * v[j];\r
+// }\r
+// }\r
+// }\r
+// for(int i = 0; i < dim; i++ ){\r
+// vec.v[i]=0.0;//v.set(i,0.0);//v[i] = 0.0;\r
+// }\r
+// vec.v[k]=1;//v.set(k,1);//v[k] = 1;\r
+// }\r
+// }\r
+ /**\r
+ * 現在ラップしている配列を取り外して、新しい配列をラップします。\r
+ * @param i_v\r
+ * @param i_clm\r
+ */\r
+ public void setNewArray(double[] i_array,int i_clm)\r
+ {\r
+ this.v=i_array;\r
+ this.clm=i_clm; \r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+\r
+/**\r
+ * ARUint32 arGetVersion(char **versionStringRef);\r
+ * 関数の置き換え\r
+ */\r
+public class NyARVersion {\r
+ private static final int AR_HEADER_VERSION_MAJOR=2; //#define AR_HEADER_VERSION_MAJOR 2\r
+ private static final int AR_HEADER_VERSION_MINOR=72;//#define AR_HEADER_VERSION_MINOR 72 \r
+ private static final int AR_HEADER_VERSION_TINY=0;//#define AR_HEADER_VERSION_TINY 0\r
+ private static final int AR_HEADER_VERSION_BUILD=0;//#define AR_HEADER_VERSION_BUILD 0\r
+ private static final String AR_HEADER_VERSION_STRING="2.72.0";//#define AR_HEADER_VERSION_STRING "2.72.0"\r
+ public static final boolean AR_HAVE_HEADER_VERSION_2=true;//#define AR_HAVE_HEADER_VERSION_2\r
+ public static final boolean AR_HAVE_HEADER_VERSION_2_72=true;//#define AR_HAVE_HEADER_VERSION_2_72\r
+\r
+ public static String getARVersion()\r
+ {\r
+ return AR_HEADER_VERSION_STRING;\r
+ }\r
+ public static int getARVersionInt()\r
+ {\r
+ // Represent full version number (major, minor, tiny, build) in\r
+ // binary coded decimal. N.B: Integer division.\r
+ return (int)(0x10000000 * (AR_HEADER_VERSION_MAJOR / 10)) +\r
+ (int)(0x01000000 * (AR_HEADER_VERSION_MAJOR % 10)) +\r
+ (int)(0x00100000 * (AR_HEADER_VERSION_MINOR / 10)) +\r
+ (int)(0x00010000 * (AR_HEADER_VERSION_MINOR % 10)) +\r
+ (int)(0x00001000 * (AR_HEADER_VERSION_TINY / 10)) +\r
+ (int)(0x00000100 * (AR_HEADER_VERSION_TINY % 10)) +\r
+ (int)(0x00000010 * (AR_HEADER_VERSION_BUILD / 10)) +\r
+ (int)(0x00000001 * (AR_HEADER_VERSION_BUILD % 10));\r
+ \r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+import jp.nyatla.nyartoolkit.core.NyARColorPatt;\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * ARColorPattのマッチング計算をするインタフェイスです。\r
+ * 基準Patに対して、計算済みのARCodeデータとの間で比較演算をします。\r
+ * pattern_match関数を分解した3種類のパターン検出クラスを定義します。\r
+ *\r
+ */\r
+public interface NyARMatchPatt{\r
+ public double getConfidence();\r
+ public int getDirection();\r
+ public void evaluate(NyARCode i_code);\r
+ public boolean setPatt(NyARColorPatt i_target_patt) throws NyARException;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+\r
+/**\r
+ * AR_TEMPLATE_MATCHING_BWと同等のルールで\r
+ * マーカーを評価します。\r
+ *\r
+ */\r
+public class NyARMatchPatt_BlackWhite implements NyARMatchPatt{\r
+ private double datapow;\r
+ private int width;\r
+ private int height;\r
+ private double cf=0;\r
+ private int dir=0;\r
+ private int ave;\r
+ private int[][][] input=new int[height][width][3];\r
+ public boolean setPatt(NyARColorPatt i_target_patt) throws NyARException\r
+ {\r
+ width=i_target_patt.getWidth();\r
+ height=i_target_patt.getHeight();\r
+ int[][][] data=i_target_patt.getPatArray(); \r
+ input=new int[height][width][3];\r
+ \r
+ int sum = ave = 0;\r
+ for(int i=0;i<height;i++) {//for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
+ for(int i2=0;i2<width;i2++) {//for(int i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
+ ave += (255-data[i][i2][0])+(255-data[i][i2][1])+(255-data[i][i2][2]);\r
+ }\r
+ }\r
+ ave /= (height*width*3);\r
+\r
+ for(int i=0;i<height;i++){//for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
+ for(int i2=0;i2<width;i2++){//for(int i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
+ input[i][i2][0] = ((255-data[i][i2][0]) + (255-data[i][i2][1]) + (255-data[i][i2][2]))/3 - ave;\r
+ sum += input[i][i2][0]*input[i][i2][0];\r
+ }\r
+ }\r
+ \r
+ datapow = Math.sqrt( (double)sum );\r
+ if( datapow == 0.0 ){\r
+ return false;// throw new NyARException();\r
+// dir.set(0);//*dir = 0;\r
+// cf.set(-1.0);//*cf = -1.0;\r
+// return -1;\r
+ }\r
+ return true;\r
+ }\r
+ public double getConfidence()\r
+ {\r
+ return cf;\r
+ }\r
+ public int getDirection()\r
+ {\r
+ return dir;\r
+ }\r
+ public void evaluate(NyARCode i_code)\r
+ {\r
+ short[][][] patBW=i_code.getPatBW();//static int patBW[AR_PATT_NUM_MAX][4][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ double[] patpowBW=i_code.getPatPowBW();//static double patpowBW[AR_PATT_NUM_MAX][4];\r
+\r
+ double max=0.0;\r
+ int res=-1;\r
+ //本家が飛ぶ。試験データで0.77767376888がが出ればOKってことで\r
+ for(int j = 0; j < 4; j++ ) {\r
+ int sum = 0;\r
+ for(int i=0;i<height;i++){\r
+ for(int i2=0;i2<width;i2++){\r
+ sum += input[i][i2][0]*patBW[j][i][i2];\r
+ }\r
+ }\r
+ double sum2 = sum / patpowBW[j] / datapow;\r
+ if( sum2 > max ) {\r
+ max = sum2;\r
+ res = j;\r
+ }\r
+ }\r
+ dir=res;\r
+ cf=max; \r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+\r
+/**\r
+ * AR_TEMPLATE_MATCHING_COLORかつAR_MATCHING_WITHOUT_PCAと同等のルールで\r
+ * マーカーを評価します。\r
+ *\r
+ */\r
+public class NyARMatchPatt_Color_WITHOUT_PCA implements NyARMatchPatt{\r
+ private int[][][] input=new int[1][1][3];\r
+ private double datapow;\r
+\r
+ private int width =1;\r
+ private int height=1;\r
+ private double cf=0;\r
+ private int dir=0;\r
+ public double getConfidence(){\r
+ return cf;\r
+ }\r
+ public int getDirection(){\r
+ return dir;\r
+ }\r
+ /**\r
+ * input配列サイズを必要に応じて再アロケートする。\r
+ *\r
+ * @param i_width\r
+ * @param i_height\r
+ */\r
+ private void reallocInputArray(int i_width,int i_height)\r
+ {\r
+ if(this.input.length<i_height || this.input[0].length<i_width){\r
+ //配列が十分なサイズでなければ取り直す\r
+ this.input=new int[i_height][i_width][3]; \r
+ }\r
+ this.height=i_height;\r
+ this.width =i_width;\r
+ }\r
+ public boolean setPatt(NyARColorPatt i_target_patt) throws NyARException\r
+ { \r
+ int i,k;\r
+ int[][][] data,linput;\r
+ \r
+ //input配列のサイズとwhも更新// input=new int[height][width][3];\r
+ reallocInputArray(i_target_patt.getWidth(),i_target_patt.getHeight());\r
+ int lwidth =this.width;\r
+ int lheight=this.height;\r
+ linput=this.input;\r
+ data=i_target_patt.getPatArray();\r
+\r
+ int sum=0,l_ave=0,w_sum;\r
+ int[][] data_i,input_i;\r
+ int[] data_i_k,input_i_k;\r
+ for(i=lheight-1;i>=0;i--){//<Optimize/>for(int i=0;i<height;i++) {//for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
+ data_i=data[i];\r
+ for(k=lwidth-1;k>=0;k--) {//<Optimize/>for(int i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
+ //<Optimize/>l_ave += (255-data[i][i2][0])+(255-data[i][i2][1])+(255-data[i][i2][2]);\r
+ data_i_k=data_i[k];\r
+ l_ave += 255*3-data_i_k[0]-data_i_k[1]-data_i_k[2];\r
+ }\r
+ }\r
+ l_ave /= (lheight*lwidth*3);\r
+ for(i=lheight-1;i>=0;i--){//for(i=0;i<height;i++){//for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
+ input_i=linput[i];\r
+ data_i=data[i];\r
+ for(k=lwidth-1;k>=0;k--){//for(i2=0;i2<width;i2++){//for(int i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
+ //<Optimize>\r
+ //for(int i3=0;i3<3;i3++){\r
+ // input[i][i2][i3] = (255-data[i][i2][i3]) - l_ave;\r
+ // sum += input[i][i2][i3]*input[i][i2][i3];\r
+ //}\r
+ data_i_k =data_i[k];\r
+ input_i_k=input_i[k];\r
+ w_sum=(255-data_i_k[0]) - l_ave;\r
+ input_i_k[0]=w_sum;\r
+ sum += w_sum*w_sum;\r
+ \r
+ w_sum=(255-data_i_k[1]) - l_ave;\r
+ input_i_k[1]=w_sum;\r
+ sum += w_sum*w_sum;\r
+ \r
+ w_sum=(255-data_i_k[2]) - l_ave;\r
+ input_i_k[2]=w_sum;\r
+ sum+=w_sum*w_sum;\r
+ //</Optimize>\r
+ }\r
+ }\r
+ datapow = Math.sqrt( (double)sum );\r
+ if(datapow == 0.0){\r
+ return false;// throw new NyARException();\r
+// dir.set(0);//*dir = 0;\r
+// cf.set(-1.0);//*cf = -1.0;\r
+// return -1;\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * public int pattern_match(short[][][] data,IntPointer dir,DoublePointer cf)\r
+\r
+ */\r
+ public void evaluate(NyARCode i_code)\r
+ {\r
+ int[][][][] pat=i_code.getPat();\r
+ double[] patpow=i_code.getPatPow();\r
+ int res= -1;\r
+ double max=0.0;\r
+ int[][][] pat_j,linput;\r
+ int[][] pat_j_i,input_i;\r
+ int[] pat_j_i_k,input_i_k;\r
+ int l_width=this.width;\r
+ int l_height=this.height;\r
+ linput=this.input;\r
+ for(int j = 0; j < 4; j++ ) {\r
+ int sum = 0;\r
+ pat_j=pat[j];\r
+ for(int i=l_height-1;i>=0;i--){//for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
+ input_i=linput[i];\r
+ pat_j_i=pat_j[i];\r
+ for(int k=l_width-1;k>=0;k--){\r
+ pat_j_i_k=pat_j_i[k];\r
+ input_i_k=input_i[k];\r
+// for(int i3=0;i3<3;i3++){\r
+ sum += input_i_k[0]*pat_j_i_k[0];//sum += input[i][i2][i3]*pat[k][j][i][i2][i3];\r
+ sum += input_i_k[1]*pat_j_i_k[1];//sum += input[i][i2][i3]*pat[k][j][i][i2][i3];\r
+ sum += input_i_k[2]*pat_j_i_k[2];//sum += input[i][i2][i3]*pat[k][j][i][i2][i3];\r
+// }\r
+ }\r
+ }\r
+ double sum2 = sum / patpow[j] / datapow;//sum2 = sum / patpow[k][j] / datapow;\r
+ if( sum2 > max ){\r
+ max = sum2;\r
+ res = j;\r
+ }\r
+ }\r
+ dir=res;\r
+ cf=max;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+import jp.nyatla.nyartoolkit.core.NyARColorPatt;\r
+\r
+/**\r
+ * AR_TEMPLATE_MATCHING_COLORかつAR_MATCHING_WITH_PCAと同等のルールで\r
+ * マーカーを評価します。\r
+ *\r
+ */\r
+public class NyARMatchPatt_Color_WITH_PCA implements NyARMatchPatt{\r
+ private final int EVEC_MAX=10;//#define EVEC_MAX 10\r
+ private int evec_dim;//static int evec_dim;\r
+ private int[][][] input;\r
+ private double[][][][] evec;//static double evec[EVEC_MAX][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ private double[][] epat=new double[4][EVEC_MAX];//static double epat[AR_PATT_NUM_MAX][4][EVEC_MAX];\r
+ private int ave;\r
+ private double datapow;\r
+\r
+ private int width;\r
+ private int height;\r
+ private double cf=0;\r
+ private int dir=0;//向きか!\r
+ public double getConfidence(){\r
+ return cf;\r
+ }\r
+ public int getDirection(){\r
+ return dir;\r
+ }\r
+ public boolean setPatt(NyARColorPatt i_target_patt) throws NyARException\r
+ {\r
+ width=i_target_patt.getWidth();\r
+ height=i_target_patt.getHeight();\r
+ int[][][] data=i_target_patt.getPatArray();\r
+ \r
+ input=new int[height][width][3];\r
+ evec=new double[EVEC_MAX][height][width][3];//static double evec[EVEC_MAX][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ int sum;\r
+\r
+ sum = ave = 0;\r
+ for(int i=0;i<height;i++) {//for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
+ for(int i2=0;i2<width;i2++) {//for(int i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
+ ave += (255-data[i][i2][0])+(255-data[i][i2][1])+(255-data[i][i2][2]);\r
+ }\r
+ }\r
+ ave /= (height*width*3);\r
+\r
+ for(int i=0;i<height;i++){//for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
+ for(int i2=0;i2<width;i2++){//for(int i2=0;i2<Config.AR_PATT_SIZE_X;i2++){\r
+ for(int i3=0;i3<3;i3++){\r
+ input[i][i2][i3] = (255-data[i][i2][i3]) - ave;\r
+ sum += input[i][i2][i3]*input[i][i2][i3];\r
+ }\r
+ }\r
+ }\r
+ datapow = Math.sqrt( (double)sum );\r
+ if(datapow == 0.0){\r
+ return false;//throw new NyARException();\r
+// dir.set(0);//*dir = 0;\r
+// cf.set(-1.0);//*cf = -1.0;\r
+// return -1;\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * public int pattern_match(short[][][] data,IntPointer dir,DoublePointer cf)\r
+\r
+ */\r
+ public void evaluate(NyARCode i_code)\r
+ {\r
+ int[][][][] pat=i_code.getPat();\r
+ double[] patpow=i_code.getPatPow();\r
+ double[] invec=new double[EVEC_MAX];\r
+\r
+ double max = 0.0; // fix VC7 compiler warning: uninitialized variable\r
+ //確認\r
+ for(int i = 0; i < evec_dim; i++ ) {\r
+ invec[i] = 0.0;\r
+ for(int j = 0; j <height; j++ ){//for(int j = 0; j <Config.AR_PATT_SIZE_Y; j++ ){\r
+ for(int j2 = 0; j2 <width; j2++ ){\r
+ for(int j3 = 0; j3 <3; j3++ ){\r
+ invec[i] += evec[i][j][j2][j3] * input[j][j2][j3];//invec[i] += evec[i][j] * input[j];\r
+ }\r
+ }\r
+ }\r
+ invec[i] /= datapow;\r
+ }\r
+\r
+ double min = 10000.0;\r
+ int res=-1;\r
+ for(int j = 0; j < 4; j++ ) {\r
+ double sum2 = 0;\r
+ for(int i = 0; i < evec_dim; i++ ) {\r
+ sum2 += (invec[i] - epat[j][i]) * (invec[i] - epat[j][i]);\r
+ }\r
+ if( sum2 < min ) {\r
+ min = sum2;\r
+ res = j;\r
+// res2 = k;//kは常にインスタンスを刺すから、省略可能\r
+ }\r
+ }\r
+\r
+ int sum = 0;\r
+ for(int i=0;i<height;i++){//for(int i=0;i<Config.AR_PATT_SIZE_Y;i++){\r
+ for(int i2=0;i2<width;i2++){//for(int i2=0;i<Config.AR_PATT_SIZE_X;i2++){\r
+ for(int i3=0;i3<3;i3++){\r
+ sum += input[i][i2][i3]*pat[res][i][i2][i3];//sum += input[i][i2][i3]*pat[res2][res][i][i2][i3];\r
+ }\r
+ }\r
+ }\r
+ max = sum / patpow[res] / datapow;\r
+ dir=res;\r
+ cf=max;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+public interface NyARRaster{\r
+ //RGBの合計値を返す\r
+ public int getPixelTotal(int i_x,int i_y);\r
+ /**\r
+ * 一行単位でi_row番目の合計値配列を計算して返す。\r
+ * @param i_row\r
+ * @param o_line\r
+ * getWidth()の戻り値以上のサイズが必要。\r
+ */\r
+ public void getPixelTotalRowLine(int i_row,int[] o_line);\r
+ public int getWidth();\r
+ public int getHeight();\r
+ public void getPixel(int i_x,int i_y,int[] i_rgb);\r
+ /**\r
+ * 複数のピクセル値をi_rgbへ返します。\r
+ * @param i_x\r
+ * xのインデックス配列\r
+ * @param i_y\r
+ * yのインデックス配列\r
+ * @param i_num\r
+ * 返すピクセル値の数\r
+ * @param i_rgb\r
+ * ピクセル値を返すバッファ\r
+ */\r
+ public void getPixelSet(int[] i_x,int i_y[],int i_num,int[] o_rgb);\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+\r
+public class NyARRaster_BGRA implements NyARRaster\r
+{\r
+ private byte[] ref_buf;\r
+ private int width;\r
+ private int height;\r
+ public static NyARRaster_BGRA wrap(byte[] i_buffer,int i_width,int i_height)\r
+ {\r
+ NyARRaster_BGRA new_inst=new NyARRaster_BGRA();\r
+ new_inst.ref_buf=i_buffer;\r
+ new_inst.width =i_width;\r
+ new_inst.height =i_height;\r
+ return new_inst;\r
+ }\r
+ //RGBの合計値を返す\r
+ public int getPixelTotal(int i_x,int i_y)\r
+ {\r
+ int bp=(i_x+i_y*this.width)*4;\r
+ byte[] ref=this.ref_buf;\r
+ return (ref[bp] & 0xff)+(ref[bp+1] & 0xff)+(ref[bp+2] & 0xff);\r
+ }\r
+ public void getPixelTotalRowLine(int i_row,int[] o_line)\r
+ {\r
+ final byte[] ref=this.ref_buf;\r
+ int bp=(i_row+1)*this.width*4-4;\r
+ for(int i=this.width-1;i>=0;i--){\r
+ o_line[i]=(ref[bp] & 0xff)+(ref[bp+1] & 0xff)+(ref[bp+2] & 0xff);\r
+ bp-=4;\r
+ }\r
+ }\r
+ public int getWidth()\r
+ {\r
+ return width;\r
+ }\r
+ public int getHeight()\r
+ {\r
+ return height;\r
+ }\r
+ public void getPixel(int i_x,int i_y,int[] i_rgb)\r
+ {\r
+ byte[] ref=this.ref_buf;\r
+ int bp=(i_x+i_y*this.width)*4;\r
+ i_rgb[0]=(ref[bp+2] & 0xff);//R\r
+ i_rgb[1]=(ref[bp+1] & 0xff);//G\r
+ i_rgb[2]=(ref[bp+0] & 0xff);//B\r
+ }\r
+ public void getPixelSet(int[] i_x,int i_y[],int i_num,int[] o_rgb)\r
+ {\r
+ int width=this.width;\r
+ byte[] ref=this.ref_buf;\r
+ int bp;\r
+ for(int i=i_num-1;i>=0;i--){\r
+ bp=(i_x[i]+i_y[i]*width)*4;\r
+ o_rgb[i*3+0]=(ref[bp+2] & 0xff);//R\r
+ o_rgb[i*3+1]=(ref[bp+1] & 0xff);//G\r
+ o_rgb[i*3+2]=(ref[bp+0] & 0xff);//B\r
+ } \r
+ }\r
+}\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+\r
+/*\r
+ * 真っ黒の矩形を定義する。\r
+ *\r
+ */\r
+public class NyARRaster_Blank implements NyARRaster\r
+{\r
+ private int width;\r
+ private int height;\r
+ public NyARRaster_Blank(int i_width,int i_height)\r
+ {\r
+ width =i_width;\r
+ height =i_height;\r
+ }\r
+ //RGBの合計値を返す\r
+ public int getPixelTotal(int i_x,int i_y)\r
+ {\r
+ return 0;\r
+ }\r
+ public void getPixelTotalRowLine(int i_row,int[] o_line)\r
+ {\r
+ for(int i=this.width-1;i>=0;i--){\r
+ o_line[i]=0;\r
+ }\r
+ } \r
+ public int getWidth()\r
+ {\r
+ return width;\r
+ }\r
+ public int getHeight()\r
+ {\r
+ return height;\r
+ }\r
+ public void getPixel(int i_x,int i_y,int[] i_rgb)\r
+ {\r
+ i_rgb[0]=0;\r
+ i_rgb[1]=0;\r
+ i_rgb[2]=0;\r
+ }\r
+ public void getPixelSet(int[] i_x,int i_y[],int i_num,int[] o_rgb)\r
+ {\r
+ for(int i=i_num-1;i>=0;i--){\r
+ o_rgb[i*3+0]=0;//R\r
+ o_rgb[i*3+1]=0;//G\r
+ o_rgb[i*3+2]=0;//B\r
+ } \r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+public class NyARRaster_RGB implements NyARRaster {\r
+ protected byte[] ref_buf;\r
+ protected int width;\r
+ protected int height;\r
+\r
+ public static NyARRaster_RGB wrap(byte[] i_buffer, int i_width, int i_height) {\r
+ NyARRaster_RGB new_inst = new NyARRaster_RGB();\r
+ new_inst.ref_buf = i_buffer;\r
+ new_inst.width = i_width;\r
+ new_inst.height = i_height;\r
+ return new_inst;\r
+ }\r
+\r
+ public static NyARRaster_RGB wrap(NyARRaster_RGB new_inst, byte[] i_buffer,\r
+ int i_width, int i_height) {\r
+ new_inst.ref_buf = i_buffer;\r
+ new_inst.width = i_width;\r
+ new_inst.height = i_height;\r
+ return new_inst;\r
+ }\r
+\r
+ // RGBの合計値を返す\r
+ public int getPixelTotal(int i_x, int i_y) {\r
+ byte[] ref = this.ref_buf;\r
+ int bp = (i_x + i_y * this.width) * 3;\r
+ return (ref[bp] & 0xff) + (ref[bp + 1] & 0xff) + (ref[bp + 2] & 0xff);\r
+ }\r
+\r
+ public void getPixelTotalRowLine(int i_row, int[] o_line) {\r
+ final byte[] ref = this.ref_buf;\r
+ int bp = (i_row + 1) * this.width * 3 - 3;\r
+ for (int i = this.width - 1; i >= 0; i--) {\r
+ o_line[i] = (ref[bp] & 0xff) + (ref[bp + 1] & 0xff)\r
+ + (ref[bp + 2] & 0xff);\r
+ bp -= 3;\r
+ }\r
+ }\r
+\r
+ public int getWidth() {\r
+ return width;\r
+ }\r
+\r
+ public int getHeight() {\r
+ return height;\r
+ }\r
+\r
+ public void getPixel(int i_x, int i_y, int[] i_rgb) {\r
+ int bp = (i_x + i_y * this.width) * 3;\r
+ byte[] ref = this.ref_buf;\r
+ i_rgb[0] = (ref[bp + 0] & 0xff);// R\r
+ i_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+ i_rgb[2] = (ref[bp + 2] & 0xff);// B\r
+ }\r
+\r
+ public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) {\r
+ int width = this.width;\r
+ byte[] ref = this.ref_buf;\r
+ int bp;\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 3;\r
+ o_rgb[i * 3 + 0] = (ref[bp + 0] & 0xff);// R\r
+ o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref[bp + 2] & 0xff);// B\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.detector;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.match.NyARMatchPatt_Color_WITHOUT_PCA;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+\r
+\r
+class NyARDetectMarkerResult\r
+{\r
+ public int arcode_id;\r
+ public int direction;\r
+ public double confidence;\r
+ public NyARSquare ref_square;\r
+}\r
+class NyARDetectMarkerResultHolder\r
+{\r
+ public NyARDetectMarkerResult[] result_array=new NyARDetectMarkerResult[1];\r
+ /**\r
+ * result_holderを最大i_reserve_size個の要素を格納できるように予約します。\r
+ * @param i_reserve_size\r
+ */\r
+ public void reservHolder(int i_reserve_size)\r
+ {\r
+ if(i_reserve_size>=result_array.length){\r
+ int new_size=i_reserve_size+5;\r
+ result_array=new NyARDetectMarkerResult[new_size];\r
+ for(int i=0;i<new_size;i++){\r
+ result_array[i]=new NyARDetectMarkerResult();\r
+ }\r
+ }\r
+ }\r
+}\r
+/**\r
+ * 複数のマーカーを検出し、それぞれに最も一致するARコードを、コンストラクタで登録したARコードから\r
+ * 探すクラスです。最大300個を認識しますが、ゴミラベルを認識したりするので100個程度が限界です。\r
+ *\r
+ */\r
+public class NyARDetectMarker{\r
+ private static final int AR_SQUARE_MAX=300;\r
+ private boolean is_continue=false;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA match_patt;\r
+ private NyARDetectSquare square;\r
+ private final NyARSquareList square_list=new NyARSquareList(AR_SQUARE_MAX);\r
+ private NyARCode[] codes;\r
+ protected NyARTransMat transmat;\r
+ private double[] marker_width;\r
+ private int number_of_code;\r
+ //検出結果の保存用\r
+ private NyARColorPatt patt;\r
+ \r
+ private NyARDetectMarkerResultHolder result_holder=new NyARDetectMarkerResultHolder();\r
+ \r
+ /**\r
+ * 複数のマーカーを検出し、最も一致するARCodeをi_codeから検索するオブジェクトを作ります。\r
+ * @param i_param\r
+ * カメラパラメータを指定します。\r
+ * @param i_code\r
+ * 検出するマーカーのARCode配列を指定します。配列要素のインデックス番号が、そのままgetARCodeIndex関数で\r
+ * 得られるARCodeインデックスになります。\r
+ * 例えば、要素[1]のARCodeに一致したマーカーである場合は、getARCodeIndexは1を返します。\r
+ * 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。\r
+ * @param i_marker_width\r
+ * i_codeのマーカーサイズをミリメートルで指定した配列を指定します。\r
+ * 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。\r
+ * @param i_number_of_code\r
+ * i_codeに含まれる、ARCodeの数を指定します。\r
+ * @throws NyARException\r
+ */\r
+ public NyARDetectMarker(NyARParam i_param,NyARCode[] i_code,double[] i_marker_width,int i_number_of_code) throws NyARException\r
+ {\r
+ //解析オブジェクトを作る\r
+ this.square=new NyARDetectSquare(i_param);\r
+ this.transmat=new NyARTransMat_O2(i_param);\r
+ //比較コードを保存\r
+ this.codes=i_code;\r
+ //比較コードの解像度は全部同じかな?(違うとパターンを複数種つくらないといけないから)\r
+ int cw=i_code[0].getWidth();\r
+ int ch=i_code[0].getHeight();\r
+ for(int i=1;i<i_number_of_code;i++){\r
+ if(cw!=i_code[i].getWidth() || ch!=i_code[i].getHeight()){\r
+ //違う解像度のが混ざっている。\r
+ throw new NyARException();\r
+ }\r
+ } \r
+ //評価パターンのホルダを作る\r
+ this.patt=new NyARColorPatt_O3(cw,ch);\r
+ this.number_of_code=i_number_of_code;\r
+\r
+ this.marker_width=i_marker_width;\r
+ //評価器を作る。\r
+ this.match_patt=new NyARMatchPatt_Color_WITHOUT_PCA(); \r
+ }\r
+ /**\r
+ * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+ * @param i_image\r
+ * マーカーを検出するイメージを指定します。\r
+ * @param i_thresh\r
+ * 検出閾値を指定します。0~255の範囲で指定してください。\r
+ * 通常は100~130くらいを指定します。\r
+ * @return\r
+ * 見つかったマーカーの数を返します。\r
+ * マーカーが見つからない場合は0を返します。\r
+ * @throws NyARException\r
+ */\r
+ public int detectMarkerLite(NyARRaster i_image,int i_thresh) throws NyARException\r
+ {\r
+ NyARSquareList l_square_list=this.square_list;\r
+ //スクエアコードを探す\r
+ square.detectSquare(i_image, i_thresh,l_square_list);\r
+ \r
+ final int number_of_square=l_square_list.getSquareNum();\r
+ //コードは見つかった?\r
+ if(number_of_square<1){\r
+ //ないや。おしまい。\r
+ return 0;\r
+ }\r
+ //保持リストのサイズを調整\r
+ this.result_holder.reservHolder(number_of_square); \r
+ \r
+ //1スクエア毎に、一致するコードを決定していく\r
+ for(int i=0;i<number_of_square;i++)\r
+ {\r
+ NyARSquare square=l_square_list.getSquare(i);\r
+ //評価基準になるパターンをイメージから切り出す\r
+ if(!this.patt.pickFromRaster(i_image,square)){\r
+ //イメージの切り出しは失敗することもある。\r
+ continue;\r
+ }\r
+ //パターンを評価器にセット\r
+ if(!this.match_patt.setPatt(this.patt)){\r
+ //計算に失敗した。 \r
+ throw new NyARException();\r
+ }\r
+ //コードと順番に比較していく\r
+ int code_index=0;\r
+ match_patt.evaluate(codes[0]);\r
+ double confidence=match_patt.getConfidence();\r
+ int direction=match_patt.getDirection();\r
+ for(int i2=1;i2<this.number_of_code;i2++)\r
+ {\r
+ //コードと比較する\r
+ match_patt.evaluate(codes[i2]);\r
+ double c2=match_patt.getConfidence();\r
+ if(confidence>c2){\r
+ continue;\r
+ }\r
+ //より一致するARCodeの情報を保存\r
+ code_index =i2;\r
+ direction =match_patt.getDirection();\r
+ confidence =c2;\r
+ }\r
+ //i番目のパターン情報を保存する。\r
+ final NyARDetectMarkerResult result=this.result_holder.result_array[i];\r
+ result.arcode_id =code_index;\r
+ result.confidence=confidence;\r
+ result.direction =direction;\r
+ result.ref_square=square;\r
+ }\r
+ return number_of_square;\r
+ }\r
+ /**\r
+ * i_indexのマーカーに対する変換行列を計算し、結果値をo_resultへ格納します。\r
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。\r
+ * @param i_index\r
+ * マーカーのインデックス番号を指定します。\r
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+ * @param o_result\r
+ * 結果値を受け取るオブジェクトを指定してください。\r
+ * @throws NyARException\r
+ */\r
+ public void getTransmationMatrix(int i_index,NyARTransMatResult o_result) throws NyARException\r
+ {\r
+ final NyARDetectMarkerResult result=this.result_holder.result_array[i_index];\r
+ //一番一致したマーカーの位置とかその辺を計算\r
+ if(is_continue){\r
+ transmat.transMatContinue(result.ref_square,result.direction,marker_width[result.arcode_id],o_result);\r
+ }else{\r
+ transmat.transMat(result.ref_square,result.direction,marker_width[result.arcode_id],o_result);\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * i_indexのマーカーの一致度を返します。\r
+ * @param i_index\r
+ * マーカーのインデックス番号を指定します。\r
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+ * @return\r
+ * マーカーの一致度を返します。0~1までの値をとります。\r
+ * 一致度が低い場合には、誤認識の可能性が高くなります。\r
+ * @throws NyARException\r
+ */\r
+ public double getConfidence(int i_index)\r
+ {\r
+ return this.result_holder.result_array[i_index].confidence;\r
+ }\r
+ /**\r
+ * i_indexのマーカーの方位を返します。\r
+ * @param i_index\r
+ * マーカーのインデックス番号を指定します。\r
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+ * @return\r
+ * 0,1,2,3の何れかを返します。\r
+ */ \r
+ public int getDirection(int i_index)\r
+ {\r
+ return this.result_holder.result_array[i_index].direction;\r
+ }\r
+ /**\r
+ * i_indexのマーカーのARCodeインデックスを返します。\r
+ * @param i_index\r
+ * マーカーのインデックス番号を指定します。\r
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+ * @return\r
+ */ \r
+ public int getARCodeIndex(int i_index)\r
+ {\r
+ return this.result_holder.result_array[i_index].arcode_id;\r
+ } \r
+ /**\r
+ * getTransmationMatrixの計算モードを設定します。\r
+ * @param i_is_continue\r
+ * TRUEなら、transMatContinueを使用します。\r
+ * FALSEなら、transMatを使用します。\r
+ */\r
+ public void setContinueMode(boolean i_is_continue)\r
+ {\r
+ this.is_continue=i_is_continue;\r
+ }\r
+ \r
+}\r
+\r
+ \r
+\r
+ \r
+ \r
+ \r
+ \r
+ \r
+ \r
+\r
+ \r
+\r
+\r
+ \r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.detector;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.match.NyARMatchPatt_Color_WITHOUT_PCA;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+/**\r
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
+ *\r
+ */\r
+public class NyARSingleDetectMarker{\r
+ private static final int AR_SQUARE_MAX=100;\r
+ private boolean is_continue=false;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA match_patt;\r
+ private NyARDetectSquare square;\r
+ private final NyARSquareList square_list=new NyARSquareList(AR_SQUARE_MAX);\r
+ private NyARCode code;\r
+ protected NyARTransMat transmat;\r
+ private double marker_width;\r
+ //検出結果の保存用\r
+ private int detected_direction;\r
+ private double detected_confidence;\r
+ private NyARSquare detected_square;\r
+ private NyARColorPatt patt;\r
+ /**\r
+ * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。\r
+ * @param i_param\r
+ * カメラパラメータを指定します。\r
+ * @param i_code\r
+ * 検出するARCodeを指定します。\r
+ * @param i_marker_width\r
+ * ARコードの物理サイズを、ミリメートルで指定します。\r
+ * @throws NyARException\r
+ */\r
+ public NyARSingleDetectMarker(NyARParam i_param,NyARCode i_code,double i_marker_width) throws NyARException\r
+ {\r
+ //解析オブジェクトを作る\r
+ this.square=new NyARDetectSquare(i_param);\r
+ this.transmat=new NyARTransMat_O2(i_param);\r
+ //比較コードを保存\r
+ this.code=i_code;\r
+ this.marker_width=i_marker_width;\r
+ //評価パターンのホルダを作る\r
+ this.patt=new NyARColorPatt_O3(code.getWidth(),code.getHeight());\r
+ //評価器を作る。\r
+ this.match_patt=new NyARMatchPatt_Color_WITHOUT_PCA(); \r
+ }\r
+ /**\r
+ * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+ * @param i_image\r
+ * マーカーを検出するイメージを指定します。\r
+ * @param i_thresh\r
+ * 検出閾値を指定します。0~255の範囲で指定してください。\r
+ * 通常は100~130くらいを指定します。\r
+ * @return\r
+ * マーカーが検出できたかを真偽値で返します。\r
+ * @throws NyARException\r
+ */\r
+ public boolean detectMarkerLite(NyARRaster i_image,int i_thresh) throws NyARException\r
+ {\r
+ detected_square=null;\r
+ NyARSquareList l_square_list=this.square_list;\r
+ //スクエアコードを探す\r
+ square.detectSquare(i_image, i_thresh,l_square_list);\r
+ \r
+ int number_of_square=l_square_list.getSquareNum();\r
+ //コードは見つかった?\r
+ if(number_of_square<1){\r
+ return false;\r
+ }\r
+\r
+ //評価基準になるパターンをイメージから切り出す\r
+ if(!patt.pickFromRaster(i_image,l_square_list.getSquare(0))){\r
+ //パターンの切り出しに失敗\r
+ return false;\r
+ }\r
+ //パターンを評価器にセット\r
+ if(!this.match_patt.setPatt(patt)){\r
+ //計算に失敗した。\r
+ throw new NyARException();\r
+ }\r
+ //コードと比較する\r
+ match_patt.evaluate(code);\r
+ int square_index=0;\r
+ int direction=match_patt.getDirection();\r
+ double confidence=match_patt.getConfidence();\r
+ for(int i=1;i<number_of_square;i++){\r
+ //次のパターンを取得\r
+ patt.pickFromRaster(i_image,l_square_list.getSquare(i));\r
+ //評価器にセットする。\r
+ match_patt.setPatt(patt);\r
+ //コードと比較する\r
+ match_patt.evaluate(code);\r
+ double c2=match_patt.getConfidence();\r
+ if(confidence>c2){\r
+ continue;\r
+ }\r
+ //もっと一致するマーカーがあったぽい\r
+ square_index=i;\r
+ direction=match_patt.getDirection();\r
+ confidence=c2;\r
+ }\r
+ //マーカー情報を保存\r
+ detected_square=l_square_list.getSquare(square_index);\r
+ detected_direction=direction;\r
+ detected_confidence=confidence;\r
+ return true;\r
+ }\r
+ /**\r
+ * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。\r
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。\r
+ * @param o_result\r
+ * 変換行列を受け取るオブジェクトを指定します。\r
+ * @throws NyARException\r
+ */ \r
+ public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException\r
+ {\r
+ //一番一致したマーカーの位置とかその辺を計算\r
+ if(is_continue){\r
+ transmat.transMatContinue(detected_square,detected_direction,marker_width,o_result);\r
+ }else{\r
+ transmat.transMat(detected_square,detected_direction,marker_width,o_result);\r
+ }\r
+ return;\r
+ } \r
+ /**\r
+ * 検出したマーカーの一致度を返します。\r
+ * @return\r
+ * マーカーの一致度を返します。0~1までの値をとります。\r
+ * 一致度が低い場合には、誤認識の可能性が高くなります。\r
+ * @throws NyARException\r
+ */\r
+ public double getConfidence()\r
+ {\r
+ return detected_confidence;\r
+ }\r
+ /**\r
+ * 検出したマーカーの方位を返します。\r
+ * @return\r
+ * 0,1,2,3の何れかを返します。\r
+ */\r
+ public int getDirection()\r
+ {\r
+ return detected_direction;\r
+ }\r
+ /**\r
+ * getTransmationMatrixの計算モードを設定します。\r
+ * 初期値はTRUEです。\r
+ * @param i_is_continue\r
+ * TRUEなら、transMatCont互換の計算をします。\r
+ * FALSEなら、transMat互換の計算をします。\r
+ */\r
+ public void setContinueMode(boolean i_is_continue)\r
+ {\r
+ this.is_continue=i_is_continue;\r
+ }\r
+}\r
+\r
+ \r
+\r
+ \r
+ \r
+ \r
+ \r
+ \r
+ \r
+\r
+ \r
+\r
+\r
+ \r
+\r
--- /dev/null
+/**\r
+ * NyARSingleDetectMarkerにOpenGL向け関数を追加したもの\r
+ * (c)2008 A虎@nyatla.jp\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/\r
+ */\r
+package jp.nyatla.nyartoolkit.jogl.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+import jp.nyatla.nyartoolkit.core.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+\r
+public class GLNyARDetectMarker extends NyARDetectMarker\r
+{\r
+ private NyARTransMatResult trans_mat_result=new NyARTransMatResult();\r
+ private double view_scale_factor=0.025;//#define VIEW_SCALEFACTOR 0.025 // 1.0 ARToolKit unit becomes 0.025 of my OpenGL units.\r
+ public GLNyARDetectMarker(NyARParam i_param,NyARCode[] i_code,double[] i_marker_width,int i_number_of_code) throws NyARException\r
+ {\r
+ super(i_param,i_code,i_marker_width,i_number_of_code); \r
+ }\r
+ public void setScaleFactor(double i_new_value)\r
+ {\r
+ view_scale_factor=i_new_value;\r
+ }\r
+ /**\r
+ * @param i_index\r
+ * マーカーのインデックス番号を指定します。\r
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+ * @param o_result\r
+ * 結果値を格納する配列を指定してください。double[16]以上が必要です。\r
+ * @throws NyARException\r
+ */\r
+ public void getCameraViewRH(int i_index,double[] o_result) throws NyARException\r
+ {\r
+ //座標を計算\r
+ this.getTransmationMatrix(i_index,this.trans_mat_result);\r
+ //行列変換\r
+ double[][] para=this.trans_mat_result.getArray();\r
+ o_result[0 + 0*4] = para[0][0]; // R1C1\r
+ o_result[0 + 1*4] = para[0][1]; // R1C2\r
+ o_result[0 + 2*4] = para[0][2];\r
+ o_result[0 + 3*4] = para[0][3];\r
+ o_result[1 + 0*4] = -para[1][0]; // R2\r
+ o_result[1 + 1*4] = -para[1][1];\r
+ o_result[1 + 2*4] = -para[1][2];\r
+ o_result[1 + 3*4] = -para[1][3];\r
+ o_result[2 + 0*4] = -para[2][0]; // R3\r
+ o_result[2 + 1*4] = -para[2][1];\r
+ o_result[2 + 2*4] = -para[2][2];\r
+ o_result[2 + 3*4] = -para[2][3];\r
+ o_result[3 + 0*4] = 0.0;\r
+ o_result[3 + 1*4] = 0.0;\r
+ o_result[3 + 2*4] = 0.0;\r
+ o_result[3 + 3*4] = 1.0;\r
+ if (view_scale_factor != 0.0) {\r
+ o_result[12] *= view_scale_factor;\r
+ o_result[13] *= view_scale_factor;\r
+ o_result[14] *= view_scale_factor;\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/**\r
+ * NyARParamにOpenGL向け関数を追加したもの\r
+ * (c)2008 A虎@nyatla.jp\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/\r
+ */\r
+package jp.nyatla.nyartoolkit.jogl.utils;\r
+\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.NyARParam;\r
+\r
+public class GLNyARParam extends NyARParam {\r
+ private double view_distance_min = 0.1;// #define VIEW_DISTANCE_MIN 0.1 //\r
+ // Objects closer to the camera than\r
+ // this will not be displayed.\r
+ private double view_distance_max = 100.0;// #define VIEW_DISTANCE_MAX\r
+ // 100.0 // Objects further away\r
+ // from the camera than this\r
+ // will not be displayed.\r
+ private double[] m_projection = null;\r
+\r
+ private float[] m_projectionF = null;\r
+\r
+ public void setViewDistanceMin(double i_new_value) {\r
+ m_projection = null;// キャッシュ済変数初期化\r
+ view_distance_min = i_new_value;\r
+ }\r
+\r
+ public void setViewDistanceMax(double i_new_value) {\r
+ m_projection = null;// キャッシュ済変数初期化\r
+ view_distance_max = i_new_value;\r
+ }\r
+\r
+ /**\r
+ * void arglCameraFrustumRH(const ARParam *cparam, const double focalmin,\r
+ * const double focalmax, GLdouble m_projection[16]) 関数の置き換え\r
+ * \r
+ * @param focalmin\r
+ * @param focalmax\r
+ * @return\r
+ */\r
+ public double[] getCameraFrustumRH() {\r
+ // 既に値がキャッシュされていたらそれを使う\r
+ if (m_projection != null) {\r
+ return m_projection;\r
+ }\r
+ // 無ければ計算\r
+ m_projection = new double[16];\r
+ NyARMat trans_mat = new NyARMat(3, 4);\r
+ NyARMat icpara_mat = new NyARMat(3, 4);\r
+ double[][] p = new double[3][3], q = new double[4][4];\r
+ int width, height;\r
+ int i, j;\r
+\r
+ width = xsize;\r
+ height = ysize;\r
+\r
+ decompMat(icpara_mat, trans_mat);\r
+\r
+ double[][] icpara = icpara_mat.getArray();\r
+ double[][] trans = trans_mat.getArray();\r
+ for (i = 0; i < 4; i++) {\r
+ icpara[1][i] = (height - 1) * (icpara[2][i]) - icpara[1][i];\r
+ }\r
+\r
+ for (i = 0; i < 3; i++) {\r
+ for (j = 0; j < 3; j++) {\r
+ p[i][j] = icpara[i][j] / icpara[2][2];\r
+ }\r
+ }\r
+ q[0][0] = (2.0 * p[0][0] / (width - 1));\r
+ q[0][1] = (2.0 * p[0][1] / (width - 1));\r
+ q[0][2] = -((2.0 * p[0][2] / (width - 1)) - 1.0);\r
+ q[0][3] = 0.0;\r
+\r
+ q[1][0] = 0.0;\r
+ q[1][1] = -(2.0 * p[1][1] / (height - 1));\r
+ q[1][2] = -((2.0 * p[1][2] / (height - 1)) - 1.0);\r
+ q[1][3] = 0.0;\r
+\r
+ q[2][0] = 0.0;\r
+ q[2][1] = 0.0;\r
+ q[2][2] = (view_distance_max + view_distance_min)\r
+ / (view_distance_min - view_distance_max);\r
+ q[2][3] = 2.0 * view_distance_max * view_distance_min\r
+ / (view_distance_min - view_distance_max);\r
+\r
+ q[3][0] = 0.0;\r
+ q[3][1] = 0.0;\r
+ q[3][2] = -1.0;\r
+ q[3][3] = 0.0;\r
+\r
+ for (i = 0; i < 4; i++) { // Row.\r
+ // First 3 columns of the current row.\r
+ for (j = 0; j < 3; j++) { // Column.\r
+ m_projection[i + j * 4] = q[i][0] * trans[0][j] + q[i][1]\r
+ * trans[1][j] + q[i][2] * trans[2][j];\r
+ }\r
+ // Fourth column of the current row.\r
+ m_projection[i + 3 * 4] = q[i][0] * trans[0][3] + q[i][1]\r
+ * trans[1][3] + q[i][2] * trans[2][3] + q[i][3];\r
+ }\r
+ return m_projection;\r
+ }\r
+\r
+ public float[] getCameraFrustumRHf() {\r
+ // 既に値がキャッシュされていたらそれを使う\r
+ if (m_projectionF == null) {\r
+ double[] mf = getCameraFrustumRH();\r
+ m_projectionF = new float[mf.length];\r
+ for (int i = 0; i < mf.length; i++) {\r
+ m_projectionF[i] = (float) mf[i];\r
+ }\r
+ }\r
+ return m_projectionF;\r
+ }\r
+}\r
--- /dev/null
+/**\r
+ * NyARSingleDetectMarkerにOpenGL向け関数を追加したもの\r
+ * (c)2008 A虎@nyatla.jp\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/\r
+ */\r
+package jp.nyatla.nyartoolkit.jogl.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+import jp.nyatla.nyartoolkit.core.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+\r
+public class GLNyARSingleDetectMarker extends NyARSingleDetectMarker {\r
+ private NyARTransMatResult trans_mat_result = new NyARTransMatResult();\r
+ private double view_scale_factor = 0.025;// #define VIEW_SCALEFACTOR\r
+\r
+ // 0.025 // 1.0 ARToolKit unit\r
+ // becomes 0.025 of my OpenGL\r
+ // units.\r
+\r
+ public GLNyARSingleDetectMarker(NyARParam i_param, NyARCode i_code,\r
+ double i_marker_width) throws NyARException {\r
+ super(i_param, i_code, i_marker_width);\r
+ }\r
+\r
+ public void setScaleFactor(double i_new_value) {\r
+ view_scale_factor = i_new_value;\r
+ }\r
+\r
+ // public static void arglCameraViewRH(const double para[3][4], GLdouble\r
+ // m_modelview[16], const double scale)\r
+ public double[] getCameraViewRH() throws NyARException {\r
+ double[] result = new double[16];\r
+ getCameraViewRH(result);\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @param o_result\r
+ * 結果値を格納する配列を指定してください。double[16]以上が必要です。\r
+ * @throws NyARException\r
+ */\r
+ public void getCameraViewRH(double[] o_result) throws NyARException {\r
+ // 座標を計算\r
+ this.getTransmationMatrix(this.trans_mat_result);\r
+ // 行列変換\r
+ double[][] para = this.trans_mat_result.getArray();\r
+ o_result[0 + 0 * 4] = para[0][0]; // R1C1\r
+ o_result[0 + 1 * 4] = para[0][1]; // R1C2\r
+ o_result[0 + 2 * 4] = para[0][2];\r
+ o_result[0 + 3 * 4] = para[0][3];\r
+ o_result[1 + 0 * 4] = -para[1][0]; // R2\r
+ o_result[1 + 1 * 4] = -para[1][1];\r
+ o_result[1 + 2 * 4] = -para[1][2];\r
+ o_result[1 + 3 * 4] = -para[1][3];\r
+ o_result[2 + 0 * 4] = -para[2][0]; // R3\r
+ o_result[2 + 1 * 4] = -para[2][1];\r
+ o_result[2 + 2 * 4] = -para[2][2];\r
+ o_result[2 + 3 * 4] = -para[2][3];\r
+ o_result[3 + 0 * 4] = 0.0;\r
+ o_result[3 + 1 * 4] = 0.0;\r
+ o_result[3 + 2 * 4] = 0.0;\r
+ o_result[3 + 3 * 4] = 1.0;\r
+ if (view_scale_factor != 0.0) {\r
+ o_result[12] *= view_scale_factor;\r
+ o_result[13] *= view_scale_factor;\r
+ o_result[14] *= view_scale_factor;\r
+ }\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @param o_result\r
+ * 結果値を格納する配列を指定してください。double[16]以上が必要です。\r
+ * @throws NyARException\r
+ */\r
+ public void getCameraViewRH(float[] o_result) throws NyARException {\r
+ // 座標を計算\r
+ this.getTransmationMatrix(this.trans_mat_result);\r
+ // 行列変換\r
+ double[][] para = this.trans_mat_result.getArray();\r
+ o_result[0 + 0 * 4] = (float) para[0][0]; // R1C1\r
+ o_result[0 + 1 * 4] = (float) para[0][1]; // R1C2\r
+ o_result[0 + 2 * 4] = (float) para[0][2];\r
+ o_result[0 + 3 * 4] = (float) para[0][3];\r
+ o_result[1 + 0 * 4] = (float) -para[1][0]; // R2\r
+ o_result[1 + 1 * 4] = (float) -para[1][1];\r
+ o_result[1 + 2 * 4] = (float) -para[1][2];\r
+ o_result[1 + 3 * 4] = (float) -para[1][3];\r
+ o_result[2 + 0 * 4] = (float) -para[2][0]; // R3\r
+ o_result[2 + 1 * 4] = (float) -para[2][1];\r
+ o_result[2 + 2 * 4] = (float) -para[2][2];\r
+ o_result[2 + 3 * 4] = (float) -para[2][3];\r
+ o_result[3 + 0 * 4] = (float) 0.0;\r
+ o_result[3 + 1 * 4] = (float) 0.0;\r
+ o_result[3 + 2 * 4] = (float) 0.0;\r
+ o_result[3 + 3 * 4] = (float) 1.0;\r
+ if (view_scale_factor != 0.0) {\r
+ o_result[12] *= view_scale_factor;\r
+ o_result[13] *= view_scale_factor;\r
+ o_result[14] *= view_scale_factor;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sample;\r
+\r
+\r
+import java.io.*;\r
+import java.util.*;\r
+\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+\r
+/**\r
+ * 320x240のBGRA32で記録されたRAWイメージから、1種類のパターンを認識し、\r
+ * その変換行列を1000回求め、それにかかったミリ秒時間を表示します。\r
+ *\r
+ */\r
+public class RawFileTest {\r
+ private final String code_file ="../Data/patt.hiro";\r
+ private final String data_file ="../Data/320x240ABGR.raw";\r
+ private final String camera_file="../Data/camera_para.dat";\r
+ public RawFileTest()\r
+ {\r
+ }\r
+ public void Test_arDetectMarkerLite() throws Exception\r
+ {\r
+ //AR用カメラパラメタファイルをロード\r
+ NyARParam ap =new NyARParam();\r
+ ap.loadFromARFile(camera_file);\r
+ ap.changeSize(320,240);\r
+\r
+ //AR用のパターンコードを読み出し \r
+ NyARCode code=new NyARCode(16,16);\r
+ code.loadFromARFile(code_file);\r
+\r
+ //試験イメージの読み出し(320x240 BGRAのRAWデータ)\r
+ File f=new File(data_file);\r
+ FileInputStream fs=new FileInputStream(data_file);\r
+ byte[] buf=new byte[(int)f.length()];\r
+ fs.read(buf);\r
+ NyARRaster_BGRA ra=NyARRaster_BGRA.wrap(buf, 320, 240);\r
+ // Blank_Raster ra=new Blank_Raster(320, 240);\r
+\r
+ //1パターンのみを追跡するクラスを作成\r
+ NyARSingleDetectMarker ar=new NyARSingleDetectMarker(ap,code,80.0);\r
+ NyARTransMatResult result_mat=new NyARTransMatResult();\r
+ ar.setContinueMode(false);\r
+ ar.detectMarkerLite(ra,100);\r
+ ar.getTransmationMatrix(result_mat);\r
+\r
+ //マーカーを検出\r
+ Date d2=new Date();\r
+ for(int i=0;i<1000;i++){\r
+ //変換行列を取得\r
+ ar.detectMarkerLite(ra,100);\r
+ ar.getTransmationMatrix(result_mat);\r
+ }\r
+ Date d=new Date();\r
+ System.out.println(d.getTime()-d2.getTime()); \r
+ }\r
+ public static void main(String[] args)\r
+ {\r
+\r
+ try{\r
+ RawFileTest t=new RawFileTest();\r
+ //t.Test_arGetVersion();\r
+ t.Test_arDetectMarkerLite();\r
+ }catch(Exception e){\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package jp.nyatla.util;\r
+\r
+public class BytePointer {\r
+ private byte[] array_ref; //配列\r
+ private int array_offset; //配列に対する基準値\r
+ private int position; //array_offsetに対する現在位置\r
+ public static BytePointer wrap(byte[] i_array_ref,int i_offset)\r
+ {\r
+ return new BytePointer(i_array_ref,i_offset);\r
+ }\r
+ public void set(byte i_value)\r
+ {\r
+ array_ref[array_offset+position]=i_value; \r
+ }\r
+ public void set(int i_rel_positon,byte i_value)\r
+ {\r
+ array_ref[array_offset+position+i_rel_positon]=i_value;\r
+ }\r
+ /**\r
+ * カレント位置の値を取得する\r
+ * @return\r
+ */\r
+ public byte get()\r
+ {\r
+ return array_ref[array_offset+position];\r
+ }\r
+ /**\r
+ * カレント位置から+i_slideの位置にある値を取得する。\r
+ * @param i_step\r
+ * @return\r
+ */\r
+ public byte get(int i_slide)\r
+ {\r
+ return array_ref[array_offset+position+i_slide];\r
+ }\r
+ public void incPtr()\r
+ {\r
+ position++;\r
+ }\r
+ public void addPtr(int v)\r
+ {\r
+ position+=v;\r
+ }\r
+ private BytePointer(byte[] i_array_ref,int i_base_point)\r
+ {\r
+ array_offset =i_base_point;\r
+ array_ref =i_array_ref;\r
+ position =0;\r
+ }\r
+// public BytePointer()\r
+// {\r
+// array_offset =0;\r
+// array_ref =new int[1];\r
+// position =0;\r
+// }\r
+}\r
--- /dev/null
+package jp.nyatla.util;\r
+/**\r
+ * double型ポインタのエミュレートクラス\r
+ * 対象のdouble配列を基点を基準に参照する。\r
+ *\r
+ */\r
+public class DoublePointer\r
+{\r
+ private double[] array_ref; //配列\r
+ private int array_offset; //配列に対する基準値\r
+ private int position; //array_offsetに対する現在位置\r
+ public static DoublePointer wrap(double[] i_array_ref,int i_offset)\r
+ {\r
+ return new DoublePointer(i_array_ref,i_offset);\r
+ }\r
+ public static DoublePointer wrap(DoublePointer i_inst)\r
+ {\r
+ return new DoublePointer(i_inst.array_ref,i_inst.getPtrArrayOffset());\r
+ }\r
+ //現在位置からのサブシーケンスを返す。\r
+ public DoublePointer slice(int i_offset)\r
+ {\r
+ return DoublePointer.wrap(array_ref,array_offset+position+i_offset);\r
+ }\r
+ public void set(double i_value)\r
+ {\r
+ array_ref[array_offset+position]=i_value; \r
+ }\r
+ public void set(int i_rel_positon,double i_value)\r
+ {\r
+ array_ref[array_offset+position+i_rel_positon]=i_value;\r
+ }\r
+ /**\r
+ * カレント位置の値を取得する\r
+ * @return\r
+ */\r
+ public double get()\r
+ {\r
+ return array_ref[array_offset+position];\r
+ }\r
+ /**\r
+ * カレント位置から+i_slideの位置にある値を取得する。\r
+ * @param i_step\r
+ * @return\r
+ */\r
+ public double get(int i_slide)\r
+ {\r
+ return array_ref[array_offset+position+i_slide];\r
+ }\r
+ public void incPtr()\r
+ {\r
+ position++;\r
+ }\r
+ public void addPtr(int v)\r
+ {\r
+ position+=v;\r
+ }\r
+ public double[] array()\r
+ {\r
+ return array_ref;\r
+ }\r
+ public void subValue(double i_val)\r
+ {\r
+ array_ref[array_offset+position]-=i_val;\r
+ }\r
+ public void subValue(int i_step,double i_val)\r
+ {\r
+ array_ref[array_offset+position+i_step]-=i_val;\r
+ }\r
+ public void addValue(double i_val)\r
+ {\r
+ array_ref[array_offset+position]+=i_val;\r
+ }\r
+ public void addValue(int i_step,double i_val)\r
+ {\r
+ array_ref[array_offset+position+i_step]+=i_val;\r
+ }\r
+\r
+ /**\r
+ * 現在位置のオフセット位置を返す。\r
+ * @return\r
+ */\r
+ public int getPtrArrayOffset()\r
+ {\r
+ return array_offset+position;\r
+ }\r
+ private DoublePointer(double[] i_array_ref,int i_base_point)\r
+ {\r
+ array_offset =i_base_point;\r
+ array_ref =i_array_ref;\r
+ position =0;\r
+ }\r
+ public DoublePointer(int i_length)\r
+ {\r
+ array_offset =0;\r
+ array_ref =new double[i_length];\r
+ position =0; \r
+ }\r
+ public DoublePointer()\r
+ {\r
+ array_offset =0;\r
+ array_ref =new double[1];\r
+ position =0; \r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package jp.nyatla.util;\r
+\r
+public class DoubleValue {\r
+ public double value;\r
+}
\ No newline at end of file
--- /dev/null
+package jp.nyatla.util;\r
+\r
+public class IntPointer {\r
+ private int[] array_ref; //配列\r
+ private int array_offset; //配列に対する基準値\r
+ private int position; //array_offsetに対する現在位置\r
+ public static IntPointer wrap(int[] i_array_ref,int i_offset)\r
+ {\r
+ return new IntPointer(i_array_ref,i_offset);\r
+ }\r
+ public void set(int i_value)\r
+ {\r
+ array_ref[array_offset+position]=i_value; \r
+ }\r
+ public void set(int i_rel_positon,int i_value)\r
+ {\r
+ array_ref[array_offset+position+i_rel_positon]=i_value;\r
+ }\r
+ /**\r
+ * カレント位置の値を取得する\r
+ * @return\r
+ */\r
+ public int get()\r
+ {\r
+ return array_ref[array_offset+position];\r
+ }\r
+ /**\r
+ * カレント位置から+i_slideの位置にある値を取得する。\r
+ * @param i_step\r
+ * @return\r
+ */\r
+ public int get(int i_slide)\r
+ {\r
+ return array_ref[array_offset+position+i_slide];\r
+ }\r
+ public void incPtr()\r
+ {\r
+ position++;\r
+ }\r
+ public void addPtr(int v)\r
+ {\r
+ position+=v;\r
+ }\r
+ public void addValue(int i_val)\r
+ {\r
+ array_ref[array_offset+position]+=i_val;\r
+ }\r
+ public void addValue(int i_step,int i_val)\r
+ {\r
+ array_ref[array_offset+position+i_step]+=i_val;\r
+ }\r
+ private IntPointer(int[] i_array_ref,int i_base_point)\r
+ {\r
+ array_offset =i_base_point;\r
+ array_ref =i_array_ref;\r
+ position =0;\r
+ }\r
+ public IntPointer()\r
+ {\r
+ array_offset =0;\r
+ array_ref =new int[1];\r
+ position =0;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.util;\r
+\r
+public class IntValue {\r
+ public int value;\r
+/* public void set(int i_v){\r
+ v=i_v;\r
+ }\r
+ public int get(){\r
+ return v;\r
+ }\r
+ public void inc(){\r
+ v++;\r
+ }\r
+ public void add(int i_v){\r
+ v+=i_v;\r
+ }*/\r
+}\r
--- /dev/null
+package jp.nyatla.util;\r
+\r
+public class ShortPointer {\r
+ private short[] array_ref; //配列\r
+ private int array_offset; //配列に対する基準値\r
+ private int position; //array_offsetに対する現在位置\r
+ public static ShortPointer wrap(short[] i_array_ref,int i_offset)\r
+ {\r
+ return new ShortPointer(i_array_ref,i_offset);\r
+ }\r
+ public static ShortPointer wrap(ShortPointer i_inst,int i_offset)\r
+ {\r
+ return new ShortPointer(i_inst.array_ref,i_inst.array_offset+i_inst.position+i_offset);\r
+ }\r
+ public void set(short i_value)\r
+ {\r
+ array_ref[array_offset+position]=i_value; \r
+ }\r
+ public void set(int i_rel_positon,short i_value)\r
+ {\r
+ array_ref[array_offset+position+i_rel_positon]=i_value;\r
+ }\r
+ /**\r
+ * カレント位置の値を取得する\r
+ * @return\r
+ */\r
+ public short get()\r
+ {\r
+ return array_ref[array_offset+position];\r
+ }\r
+ /**\r
+ * カレント位置から+i_slideの位置にある値を取得する。\r
+ * @param i_step\r
+ * @return\r
+ */\r
+ public short get(int i_slide)\r
+ {\r
+ return array_ref[array_offset+position+i_slide];\r
+ }\r
+ public void incPtr()\r
+ {\r
+ position++;\r
+ }\r
+ public void addPtr(int v)\r
+ {\r
+ position+=v;\r
+ }\r
+ private ShortPointer(short[] i_array_ref,int i_base_point)\r
+ {\r
+ array_offset =i_base_point;\r
+ array_ref =i_array_ref;\r
+ position =0;\r
+ }\r
+// public BytePointer()\r
+// {\r
+// array_offset =0;\r
+// array_ref =new int[1];\r
+// position =0;\r
+// }\r
+}\r
--- /dev/null
+package jp.nyatla.util;\r
+\r
+public class StringPointer {\r
+ private String[] array_ref;//配列\r
+ private int array_offset; //配列に対する基準値\r
+ private int position; //array_offsetに対する現在位置\r
+ public void set(String i_value)\r
+ {\r
+ array_ref[array_offset+position]=i_value;\r
+ }\r
+ public String get()\r
+ {\r
+ return array_ref[array_offset+position];\r
+ }\r
+ public String toString()\r
+ {\r
+ return get();\r
+ }\r
+ public StringPointer()\r
+ {\r
+ array_ref=new String[1];\r
+ array_offset=0;\r
+ position=0;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.util;\r
+\r
+public class StringValue {\r
+ private String v;\r
+ public StringValue()\r
+ {\r
+ v="";\r
+ }\r
+ public StringValue(String i_v)\r
+ {\r
+ v=i_v;\r
+ }\r
+ public void set(String i_v)\r
+ {\r
+ v=i_v;\r
+ }\r
+ public String get()\r
+ {\r
+ return v;\r
+ }\r
+ public String toString()\r
+ {\r
+ return v;\r
+ }\r
+}\r