OSDN Git Service

git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@768 7cac0...
authornyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Fri, 31 Dec 2010 06:13:25 +0000 (06:13 +0000)
committerAtsuo Igarashi <atsuoigarashi@ubuntu.(none)>
Tue, 5 Apr 2011 09:08:48 +0000 (18:08 +0900)
148 files changed:
lib/src/jp/nyatla/nyartoolkit/NyARException.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/INyARDisposable.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/NyARCode.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/NyARMat.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/NyARVec.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/INyARHistogramAnalyzer_Threshold.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/NyARHistogramAnalyzer_DiscriminantThreshold.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/NyARHistogramAnalyzer_KittlerThreshold.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/NyARHistogramAnalyzer_SlidePTile.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/analyzer/raster/NyARRasterAnalyzer_Histogram.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/analyzer/raster/threshold/INyARRasterThresholdAnalyzer.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/analyzer/raster/threshold/NyARRasterThresholdAnalyzer_SlidePTile.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelInfo.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelOverlapChecker.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingImage.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingLabel.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingLabelStack.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabeling_ARToolKit.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARLabeling_Rle.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARRleLabelFragmentInfo.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARRleLabelFragmentInfoPtrStack.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/match/INyARMatchPatt.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPattDeviationBlackWhiteData.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPattDeviationColorData.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPattResult.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPatt_BlackWhite.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPatt_Color_WITHOUT_PCA.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPatt_Color_WITH_PCA.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/param/NyARCameraDistortionFactor.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/param/NyARFrustum.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/param/NyARParam.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/param/NyARPerspectiveProjectionMatrix.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/pca2d/INyARPca2d.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA_O2.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/pickup/INyARColorPatt.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_O1.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_O3.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_Perspective.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_Perspective_O2.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_PseudoAffine.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/INyARRaster.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/NyARBinRaster.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/NyARGrayscaleRaster.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/NyARHsvRaster.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/NyARRaster.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/NyARRaster_BasicClass.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/INyARRgbRaster.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_BGRA.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_BasicClass.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_Blank.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_RGB.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/INyARRasterFilter.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_CustomToneTable.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_EqualizeHist.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_GaussianSmooth.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Reverse.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Rgb2Hsv.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Roberts.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_SimpleSmooth.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_ToneTable.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/gs2bin/INyARRasterFilter_Gs2Bin.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/gs2bin/NyARRasterFilter_ConstantThreshold.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2bin/INyARRasterFilter_Rgb2Bin.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2bin/NyARRasterFilter_ARToolkitThreshold.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/INyARRasterFilter_Rgb2Gs.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_RgbAve192.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_RgbCube.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_YCbCr.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterreader/INyARRgbPixelReader.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARPerspectiveRasterReader.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_B8G8R8X8_32.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_B8G8R8_24.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_R8G8B8_24.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_X8R8G8B8_32.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_GRAY_8.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_X8R8G8B8_32.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_WORD1D_R5G6B5_16LE.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARContourPickup.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARContourPickup_ARToolKit.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARCoord2Linear.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARCoord2SquareVertexIndexes.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquare.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareContourDetector.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareContourDetector_ARToolKit.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareContourDetector_Rle.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareStack.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/INyARTransMat.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARRectOffset.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMatResult.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat_ARToolKit.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARPartialDifferentiationOptimize.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/INyARRotMatrixOptimize.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/NyARRotMatrixOptimize.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/NyARRotMatrixOptimize_Base.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/NyARRotMatrixOptimize_O2.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit_O2.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotVector.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/solver/INyARTransportVectorSolver.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/solver/NyARTransportVectorSolver.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/transmat/solver/NyARTransportVectorSolver_ARToolKit.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARBufferType.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARDoublePoint2d.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARDoublePoint3d.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARHistogram.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntCoordinates.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint2d.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntRect.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntSize.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/NyARVecLinear2d.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/matrix/INyARDoubleMatrix.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix22.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix33.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix34.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix44.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARIntPointStack.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARIntRectStack.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARObjectStack.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARPointerStack.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyARDistMap.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyAREquationSolver.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyARManagedObject.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyARManagedObjectPool.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyARMath.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyARObjectPool.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator_O1.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator_Reference.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/core/utils/NyARSystemOfLinearEquationsProcessor.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/detector/NyARCustomSingleDetectMarker.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/detector/NyARDetectMarker.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/detector/NyARSingleDetectMarker.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/nyidmarker/NyIdMarkerParam.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/nyidmarker/NyIdMarkerPattern.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/nyidmarker/NyIdMarkerPickup.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerData.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerDataEncoder.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerDataEncoder_RawBit.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerData_RawBit.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/processor/SingleARMarkerProcesser.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/processor/SingleNyIdMarkerProcesser.java [new file with mode: 0644]
lib/src/jp/nyatla/nyartoolkit/utils/TransformedBitmapPickup.java [new file with mode: 0644]

diff --git a/lib/src/jp/nyatla/nyartoolkit/NyARException.java b/lib/src/jp/nyatla/nyartoolkit/NyARException.java
new file mode 100644 (file)
index 0000000..8956074
--- /dev/null
@@ -0,0 +1,94 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit;\r
+\r
+/**\r
+ * NyARToolkitライブラリが生成するExceptionのクラスです。\r
+ * このクラスは、NyARToolkitライブラリ内でのみ使用します。\r
+ *\r
+ */\r
+public class NyARException extends Exception\r
+{\r
+       private static final long serialVersionUID = 1L;\r
+\r
+       /**\r
+        * コンストラクタです。例外オブジェクトを生成します。\r
+        */\r
+       public NyARException()\r
+       {\r
+               super();\r
+       }\r
+       /**\r
+        * コンストラクタです。例外オブジェクト継承して、例外を生成します。\r
+        * @param e\r
+        * 継承する例外オブジェクト\r
+        */\r
+       public NyARException(Exception e)\r
+       {\r
+               super(e);\r
+       }\r
+       /**\r
+        * コンストラクタです。メッセージを指定して、例外を生成します。\r
+        * @param m\r
+        */\r
+       public NyARException(String m)\r
+       {\r
+               super(m);\r
+       }\r
+       /**\r
+        * ライブラリ開発者向けの関数です。メッセージを指定して、例外をスローします。\r
+        * この関数は、NyARToolkitの仕様外動作を補足するために使います。\r
+        * @param m\r
+        * @throws NyARException\r
+        */\r
+\r
+       public static void trap(String m) throws NyARException\r
+       {\r
+               throw new NyARException("トラップ:" + m);\r
+       }\r
+       /**\r
+        * ライブラリ開発者向けの関数です。"Not Implement!"メッセージを指定して、例外をスローします。\r
+        * この関数は、NyARToolkitの未実装部分に記述して使います。\r
+        * @throws NyARException\r
+        */\r
+       public static void notImplement() throws NyARException\r
+       {\r
+               throw new NyARException("Not Implement!");\r
+       }\r
+       /**\r
+        * この関数は使用不能です。(別の関数を使用してください。)\r
+        * @throws NyARException\r
+        */\r
+       public static void unavailability() throws NyARException\r
+       {\r
+               throw new NyARException("unavailability!");\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/INyARDisposable.java b/lib/src/jp/nyatla/nyartoolkit/core/INyARDisposable.java
new file mode 100644 (file)
index 0000000..dbdf9e5
--- /dev/null
@@ -0,0 +1,13 @@
+package jp.nyatla.nyartoolkit.core;\r
+\r
+/**\r
+ * オブジェクトの破棄タイミングを受け取るインタフェイスです。\r
+ *\r
+ */\r
+public interface INyARDisposable\r
+{\r
+       /**\r
+        * オブジェクトの終期化のタイミングを与えます。オブジェクトの終期化に必要な処理を実装します。\r
+        */\r
+       public void dispose();\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/NyARCode.java b/lib/src/jp/nyatla/nyartoolkit/core/NyARCode.java
new file mode 100644 (file)
index 0000000..5fc15a7
--- /dev/null
@@ -0,0 +1,264 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\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.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+\r
+/**\r
+ * NyARCodeクラスの支援クラスです。このクラスは、NyARCodeのマーカファイル読み取り機能を担当します。\r
+ * InputStreamからARToolkit形式のマーカデータを読み取って配列に格納する手順を実装します。\r
+ */\r
+class NyARCodeFileReader\r
+{\r
+\r
+       /**\r
+        * ImputStreamからARToolKit形式のマーカデータを読み込んでo_raster[4]に格納します。\r
+        * @param i_stream\r
+        * 読出し元のストリームです。\r
+        * @param o_raster\r
+        * 出力先のラスタ配列です。バッファ形式は形式はINT1D_X8R8G8B8_32であり、全て同一なサイズである必要があります。\r
+        * @throws NyARException\r
+        */\r
+       public static void loadFromARToolKitFormFile(InputStream i_stream,NyARRaster[] o_raster) throws NyARException\r
+       {\r
+               assert o_raster.length==4;\r
+               //4個の要素をラスタにセットする。\r
+               try {\r
+                       StreamTokenizer st = new StreamTokenizer(new InputStreamReader(i_stream));\r
+                       //GBRAで一度読みだす。\r
+                       for (int h = 0; h < 4; h++) {\r
+                               assert o_raster[h].isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32);\r
+                               final NyARRaster ra=o_raster[h];\r
+                               readBlock(st,ra.getWidth(),ra.getHeight(),(int[])ra.getBuffer());\r
+                       }\r
+               } catch (Exception e) {\r
+                       throw new NyARException(e);\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * ImputStreamからARToolKit形式のマーカデータを読み込んでo_codeに格納します。\r
+        * @param i_stream\r
+        * 読出し元のストリームです。\r
+        * @param o_code\r
+        * 出力先のNyARCodeオブジェクトです。\r
+        * @throws NyARException\r
+        */\r
+       public static void loadFromARToolKitFormFile(InputStream i_stream,NyARCode o_code) throws NyARException\r
+       {\r
+               int width=o_code.getWidth();\r
+               int height=o_code.getHeight();\r
+               NyARRgbRaster tmp_raster=new NyARRgbRaster(width,height, NyARBufferType.INT1D_X8R8G8B8_32);\r
+               //4個の要素をラスタにセットする。\r
+               try {\r
+                       StreamTokenizer st = new StreamTokenizer(new InputStreamReader(i_stream));\r
+                       int[] buf=(int[])tmp_raster.getBuffer();\r
+                       //GBRAで一度読みだす。\r
+                       for (int h = 0; h < 4; h++){\r
+                               readBlock(st,width,height,buf);\r
+                               //ARCodeにセット(カラー)\r
+                               o_code.getColorData(h).setRaster(tmp_raster);\r
+                               o_code.getBlackWhiteData(h).setRaster(tmp_raster);\r
+                       }\r
+               } catch (Exception e) {\r
+                       throw new NyARException(e);\r
+               }\r
+               tmp_raster=null;//ポイ\r
+               return;\r
+       }\r
+       /**\r
+        * 1ブロック分のXRGBデータをi_stからo_bufへ読みだします。\r
+        * @param i_st\r
+        * 入力元のStreamTokenizerを指定します。関数実行後、読み取り位置は更新されます。\r
+        * @param i_width\r
+        * パターンの横幅です。\r
+        * @param i_height\r
+        * パターンの縦幅です。\r
+        * @param o_buf\r
+        * 読み取った値を格納する配列です。\r
+        * @throws NyARException\r
+        */\r
+       private static void readBlock(StreamTokenizer i_st,int i_width,int i_height,int[] o_buf) throws NyARException\r
+       {\r
+               try {\r
+                       final int pixels=i_width*i_height;\r
+                       for (int i3 = 0; i3 < 3; i3++) {\r
+                               for (int i2 = 0; i2 < pixels; i2++){\r
+                                       // 数値のみ読み出す\r
+                                       switch (i_st.nextToken()){\r
+                                       case StreamTokenizer.TT_NUMBER:\r
+                                               break;\r
+                                       default:\r
+                                               throw new NyARException();\r
+                                       }\r
+                                       o_buf[i2]=(o_buf[i2]<<8)|((0x000000ff&(int)i_st.nval));\r
+                               }\r
+                       }\r
+                       //GBR→RGB\r
+                       for(int i3=0;i3<pixels;i3++){\r
+                               o_buf[i3]=((o_buf[i3]<<16)&0xff0000)|(o_buf[i3]&0x00ff00)|((o_buf[i3]>>16)&0x0000ff);\r
+                       }\r
+               } catch (Exception e) {\r
+                       throw new NyARException(e);\r
+               }               \r
+               return;\r
+       }\r
+}\r
+\r
+/**\r
+ * ARToolKitのマーカーパターン1個のデータに相当するクラスです。\r
+ * マーカーパターンに対する、ARToolKit相当のプロパティ値を提供します。\r
+ */\r
+public class NyARCode\r
+{\r
+       private NyARMatchPattDeviationColorData[] _color_pat=new NyARMatchPattDeviationColorData[4];\r
+       private NyARMatchPattDeviationBlackWhiteData[] _bw_pat=new NyARMatchPattDeviationBlackWhiteData[4];\r
+       private int _width;\r
+       private int _height;\r
+       \r
+       /**\r
+        * directionを指定して、NyARMatchPattDeviationColorDataオブジェクトを取得します。\r
+        * @param i_index\r
+        * 0<=n<4の数値\r
+        * @return\r
+        * NyARMatchPattDeviationColorDataオブジェクト\r
+        */\r
+       public NyARMatchPattDeviationColorData getColorData(int i_index)\r
+       {\r
+               return this._color_pat[i_index];\r
+       }\r
+       public NyARMatchPattDeviationBlackWhiteData getBlackWhiteData(int i_index)\r
+       {\r
+               return this._bw_pat[i_index];\r
+       }       \r
+       public int getWidth()\r
+       {\r
+               return _width;\r
+       }\r
+\r
+       /**\r
+        * パターンデータの高さを取得します。\r
+        * @return\r
+        */\r
+       public int getHeight()\r
+       {\r
+               return _height;\r
+       }\r
+       /**\r
+        * コンストラクタです。空のNyARCodeオブジェクトを作成します。\r
+        * @param i_width\r
+        * 作成するマーカパターンの幅\r
+        * @param i_height\r
+        * 作成するマーカパターンの高さ\r
+        * @throws NyARException\r
+        */\r
+       public NyARCode(int i_width, int i_height) throws NyARException\r
+       {\r
+               this._width = i_width;\r
+               this._height = i_height;\r
+               //空のラスタを4個作成\r
+               for(int i=0;i<4;i++){\r
+                       this._color_pat[i]=new NyARMatchPattDeviationColorData(i_width,i_height);\r
+                       this._bw_pat[i]=new NyARMatchPattDeviationBlackWhiteData(i_width,i_height);\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * ファイル名を指定して、パターンデータをロードします。\r
+        * ロードするパターンデータのサイズは、現在の値と同じである必要があります。\r
+        * @param filename\r
+        * ARToolKit形式のパターンデータファイルの名前\r
+        * @throws NyARException\r
+        */\r
+       public void loadARPattFromFile(String filename) throws NyARException\r
+       {\r
+               try {\r
+                       loadARPatt(new FileInputStream(filename));\r
+               } catch (Exception e) {\r
+                       throw new NyARException(e);\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * 4枚のラスタから、マーカーパターンを生成して格納します。\r
+        * @param i_raster\r
+        * direction毎のパターンを格納したラスタ配列を指定します。\r
+        * ラスタは同一なサイズ、かつマーカーパターンと同じサイズである必要があります。\r
+        * 格納順は、パターンの右上が、1,2,3,4象限になる順番です。\r
+        * @throws NyARException\r
+        */\r
+       public void setRaster(INyARRgbRaster[] i_raster) throws NyARException\r
+       {\r
+               assert(i_raster.length!=4);\r
+               //ラスタにパターンをロードする。\r
+               for(int i=0;i<4;i++){\r
+                       this._color_pat[i].setRaster(i_raster[i]);\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * 1枚のラスタから、マーカーパターンを生成して格納します。\r
+        * @param i_raster\r
+        * 基準となるラスタを指定します。ラスタの解像度は、ARマーカコードと同じである必要があります。\r
+        * @throws NyARException\r
+        */     \r
+       public void setRaster(INyARRgbRaster i_raster) throws NyARException\r
+       {\r
+               //ラスタにパターンをロードする。\r
+               for(int i=0;i<4;i++){\r
+                       this._color_pat[i].setRaster(i_raster,i);\r
+               }\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * inputStreamから、パターンデータをロードします。\r
+        * ロードするパターンのサイズは、現在の値と同じである必要があります。\r
+        * @param i_stream\r
+        * @throws NyARException\r
+        */\r
+       public void loadARPatt(InputStream i_stream) throws NyARException\r
+       {\r
+               //ラスタにパターンをロードする。\r
+               NyARCodeFileReader.loadFromARToolKitFormFile(i_stream,this);\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/NyARMat.java b/lib/src/jp/nyatla/nyartoolkit/core/NyARMat.java
new file mode 100644 (file)
index 0000000..49da105
--- /dev/null
@@ -0,0 +1,1000 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * ARToolKit由来の、可変サイズの行列計算クラスです。\r
+ * ARToolKitのARMat構造体と、その処理関数に相当する機能があります。\r
+ * 2x2,3x3,4x4行列については、NyAToolKitの行列計算クラスの方が高速な場合がありますので、必要に応じて選択して下さい。\r
+ * @note\r
+ * このクラスは、今後統合・削除する可能性があります。\r
+ */\r
+public class NyARMat\r
+{\r
+       /**\r
+        * 配列値を格納するバッファ\r
+        * 配列サイズと行列サイズは必ずしも一致しないことに注意。\r
+        * 配列のサイズを行列の大きさとして使わないこと!\r
+        */\r
+       protected double[][] _m;\r
+       private int[] __matrixSelfInv_nos;\r
+\r
+       protected int clm;\r
+       protected int row;\r
+\r
+       /**\r
+        * デフォルトコンストラクタは機能しません。\r
+        * @throws NyARException\r
+        */\r
+       protected NyARMat() throws NyARException\r
+       {\r
+               throw new NyARException();\r
+       }\r
+       /**\r
+        * コンストラクタです。サイズを指定して、NyARMatオブジェクトを作成します。\r
+        * @param i_row\r
+        * @param i_clm\r
+        */\r
+       public NyARMat(int i_row, int i_clm)\r
+       {\r
+               this._m = new double[i_row][i_clm];\r
+               this.clm = i_clm;\r
+               this.row = i_row;\r
+               this.__matrixSelfInv_nos=new int[i_row];\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * 行列の列数を返します。\r
+        * @return\r
+        */\r
+       public int getClm()\r
+       {\r
+               return clm;\r
+       }\r
+       /**\r
+        * 行列の行数を返します。\r
+        * @return\r
+        */\r
+       public int getRow()\r
+       {\r
+               return row;\r
+       }       \r
+       \r
+       /**\r
+        * 行列のサイズを変更します。\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
+               } else {\r
+                       // 不十分なら取り直す。\r
+                       this._m = new double[i_row][i_clm];\r
+                       this.__matrixSelfInv_nos=new int[i_row];\r
+               }\r
+               this.clm = i_clm;\r
+               this.row = i_row;\r
+               return;\r
+       }\r
+       \r
+       \r
+       \r
+       /**\r
+        * 行列同士の掛け算を実行します。\r
+        * i_mat_aとi_mat_bの積を計算して、thisへ格納します。\r
+        * @param i_mat_a\r
+        * 計算元の行列A\r
+        * @param i_mat_b\r
+        * 計算元の行列B\r
+        * @throws NyARException\r
+        */\r
+       public void matrixMul(NyARMat i_mat_a, NyARMat i_mat_b) throws NyARException\r
+       {\r
+               assert i_mat_a.clm == i_mat_b.row && this.row==i_mat_a.row && this.clm==i_mat_b.clm;\r
+\r
+               double w;\r
+               int r, c, i;\r
+               double[][] am = i_mat_a._m, bm = i_mat_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;\r
+                               for (i = 0; i < i_mat_a.clm; i++) {\r
+                                       w += am[r][i] * bm[i][c];\r
+                               }\r
+                               dm[r][c] = w;\r
+                       }\r
+               }\r
+               return;\r
+       }       \r
+       \r
+       /**\r
+        * 逆行列を計算して、thisへ格納します。\r
+        * @return\r
+        * 逆行列が計算できたかの、真偽値を返します。trueなら、逆行列が存在します。falseなら、逆行列はありません。\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 = __matrixSelfInv_nos;//ワーク変数\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
+               /*\r
+                * nyatla memo ipが定まらないで計算が行われる場合があるので挿入。 ループ内で0初期化していいかが判らない。\r
+                */\r
+               ip = 0;\r
+               // For順変更禁止\r
+               for (int n = 0; n < dimen; n++) {\r
+                       ap_n = ap[n];// wcp = ap + n * rowa;\r
+                       p = 0.0;\r
+                       for (int i = n; i < dimen; i++) {\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,\r
+                                                                                       // 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++) {\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
+                                       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++) {\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
+       /**\r
+        * 行列の要素を、全て0にします。\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
+       /**\r
+        * i_copy_fromの内容を、thisへコピーします。 \r
+        * @param i_copy_from\r
+        * コピー元の行列です。\r
+        * この行列のサイズは、thisと同じでなければなりません。\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
+                       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
+        * 行列のバッファを返します。\r
+        * @return\r
+        */\r
+       public double[][] getArray()\r
+       {\r
+               return _m;\r
+       }\r
+\r
+\r
+       /**\r
+        * ARToolKitのarMatrixTrans関数と同等な関数です。\r
+        * sourceの転置行列をdestに得ます。\r
+        * @param dest\r
+        * 出力先のオブジェクト\r
+        * @param source\r
+        * 入力元のオブジェクト\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
+       /**\r
+        * ARToolKitの、arMatrixUnit関数と同等な関数です。\r
+        * unitを単位行列に初期化します。\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
+       /**\r
+        * i_sourceの内容を、thisへコピーします。\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
+                               dest_m[r][c] = src_m[r][c];\r
+                       }\r
+               }\r
+       }\r
+       /**\r
+        * オブジェクトを複製します。\r
+        * @return\r
+        * @throws NyARException\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
+                               dest_m[r][c] = src_m[r][c];\r
+                       }\r
+               }\r
+               return result;\r
+       }\r
+\r
+\r
+       private static final double PCA_EPS = 1e-6; // #define EPS 1e-6\r
+\r
+       private static final int PCA_MAX_ITER = 100; // #define MAX_ITER 100\r
+\r
+       private static final double PCA_VZERO = 1e-16; // #define VZERO 1e-16\r
+\r
+       /**\r
+        * ARToolKitのEX関数と同等な関数です。\r
+        * 詳細は不明です。\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
+       /**\r
+        * ARToolKitのCENTER関数と同等な関数です。\r
+        * 詳細は不明です。\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.row;\r
+               clm = inout.clm;\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
+                       break;\r
+               }\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * ARToolKitのx_by_xtと同等な関数です。詳細は不明です。\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 =\r
+                                                                                                       // 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++)\r
+                                                                                                                       // * *(in2++);\r
+                                       }\r
+                               }\r
+                               // out.incPtr();\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * ARToolKitのxt_by_x関数と同等な関数です。\r
+        * 詳細は不明です。\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
+\r
+       private final NyARVec wk_PCA_QRM_ev = new NyARVec(1);\r
+\r
+       /**\r
+        * ARToolKitのQRM関数と同等な関数です。\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])))\r
+                               // 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
+                                               {\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
+                                               {\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\r
+                                       * (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
+       /**\r
+        * 行列のうち、指定した2列の値を入れ替えます。\r
+        * @param i_row_1\r
+        * 入れ替える行番号1\r
+        * @param i_row_2\r
+        * 入れ替える行番号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
+       /**\r
+        * ARToolKitのEV_create関数と同等な関数です。\r
+        * 詳細は不明です。\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 !=\r
+                                                                                       // row ){\r
+                       throw new NyARException();\r
+               }\r
+               if (output.row != row || output.clm != clm) {// if( output->row !=\r
+                                                                                                               // row || output->clm !=\r
+                                                                                                               // 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 /\r
+                                                                                                               // 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
+\r
+       private NyARMat wk_PCA_PCA_u = null;\r
+\r
+       /**\r
+        * ARToolKitのPCA関数と同等な関数です。\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
+               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
+       /**\r
+        * 現在の行列に主成分分析を実行して、結果をthisと引数へ格納します。\r
+        * 詳細は不明です。\r
+        * @param o_evec\r
+        * @param o_ev\r
+        * @param o_mean\r
+        * @throws NyARException\r
+        */\r
+       public void pca(NyARMat o_evec, NyARVec o_ev, NyARVec o_mean)throws NyARException\r
+       {\r
+               final double l_row = this.row;// row = input->row;\r
+               final double l_clm = this.clm;// clm = input->clm;\r
+               final double check=(l_row < l_clm) ? l_row : l_clm;\r
+               \r
+               assert l_row >= 2 || l_clm >= 2;\r
+               assert o_evec.clm == l_clm && o_evec.row == check;\r
+               assert o_ev.getClm() == check;\r
+               assert o_mean.getClm() == l_clm;\r
+               \r
+               final double srow = Math.sqrt((double) l_row);\r
+               PCA_EX(o_mean);\r
+\r
+               PCA_CENTER(this, o_mean);\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
+                               this._m[i][j] /= srow;// work->m[i] /= srow;\r
+                       }\r
+               }\r
+\r
+               PCA_PCA(o_evec, o_ev);\r
+\r
+               double 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
+               return;\r
+       }\r
+       \r
+\r
+\r
+       private final NyARVec wk_vecTridiagonalize_vec = new NyARVec(0);\r
+\r
+       private final NyARVec wk_vecTridiagonalize_vec2 = new NyARVec(0);\r
+\r
+       /**\r
+        * ARToolKitの、arVecTridiagonalize関数と同等な関数です。\r
+        * 詳細は不明です。\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[]\r
+                                                                                       // 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));\r
+                                                                       // //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
+                       // 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;\r
+                               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
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/NyARVec.java b/lib/src/jp/nyatla/nyartoolkit/core/NyARVec.java
new file mode 100644 (file)
index 0000000..a38a0a6
--- /dev/null
@@ -0,0 +1,148 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.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
+\r
+       public NyARVec(int i_clm)\r
+       {\r
+               v = new double[i_clm];\r
+               clm = i_clm;\r
+       }\r
+\r
+       private double[] v;\r
+\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
+               } else {\r
+                       // 不十分なら取り直す。\r
+                       v = new double[i_clm];\r
+               }\r
+               this.clm = i_clm;\r
+       }\r
+\r
+       public int getClm()\r
+       {\r
+               return clm;\r
+       }\r
+\r
+       public double[] getArray()\r
+       {\r
+               return v;\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * arVecInnerproduct関数の代替品\r
+        * \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
+       /**\r
+        * double arVecHousehold関数の代替品\r
+        * \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
+                       {\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
+       /**\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
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/INyARHistogramAnalyzer_Threshold.java b/lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/INyARHistogramAnalyzer_Threshold.java
new file mode 100644 (file)
index 0000000..6b9a5a2
--- /dev/null
@@ -0,0 +1,19 @@
+package jp.nyatla.nyartoolkit.core.analyzer.histogram;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistogram;\r
+\r
+/**\r
+ * 敷居値判別ヒストグラム分析器の、標準的なインタフェイスを定義します。\r
+ *\r
+ */\r
+public interface INyARHistogramAnalyzer_Threshold\r
+{\r
+       /**\r
+        * ヒストグラムから閾値探索をします。\r
+        * @param i_histogram\r
+        * 分析するヒストグラムオブジェクト\r
+        * @return\r
+        * 敷居値を返します。\r
+        */\r
+       public int getThreshold(NyARHistogram i_histogram);\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/NyARHistogramAnalyzer_DiscriminantThreshold.java b/lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/NyARHistogramAnalyzer_DiscriminantThreshold.java
new file mode 100644 (file)
index 0000000..af81ed3
--- /dev/null
@@ -0,0 +1,93 @@
+package jp.nyatla.nyartoolkit.core.analyzer.histogram;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistogram;\r
+\r
+/**\r
+ * 敷居値を求めるヒストグラム分析器です。\r
+ * 判別法で閾値を求めます。\r
+ * @note\r
+ * 画素数が2048^2に満たない場合は、fixedint(24-8)で計算できます。\r
+ */\r
+public class NyARHistogramAnalyzer_DiscriminantThreshold implements INyARHistogramAnalyzer_Threshold\r
+{\r
+       private double _score;\r
+       /**\r
+        * @override\r
+        */\r
+       public int getThreshold(NyARHistogram i_histogram)\r
+       {\r
+               int[] hist=i_histogram.data;\r
+               int n=i_histogram.length;\r
+               int da,sa,db,sb,dt,pt,st;\r
+               int i;          \r
+               int th=0;\r
+               //後で使う\r
+               dt=pt=0;\r
+               for(i=0;i<n;i++){\r
+                       int h=hist[i];\r
+                       dt+=h*i;\r
+                       pt+=h*i*i;//正規化の時に使う定数\r
+               }\r
+               st=i_histogram.total_of_data;\r
+               //Low側(0<=i<=n-2)\r
+               da=dt;\r
+               sa=st;\r
+               //High側(i=n-1)\r
+               db=sb=0;                \r
+               \r
+               double max=-1;\r
+               double max_mt=0;\r
+               //各ヒストグラムの分離度を計算する(1<=i<=n-1の範囲で評価)\r
+               for(i=n-1;i>0;i--){\r
+                       //次のヒストグラムを計算\r
+                       int hist_count=hist[i];\r
+                       int hist_val=hist_count*i;\r
+                       da-=hist_val;\r
+                       sa-=hist_count;\r
+                       db+=hist_val;\r
+                       sb+=hist_count;\r
+                       \r
+                       //クラス間分散を計算\r
+                       double dv=(sa+sb);\r
+                       double mt=(double)(da+db)/dv;\r
+                       double ma=(sa!=0?((double)da/(double)sa):0)-mt;\r
+                       double mb=(sb!=0?((double)db/(double)sb):0)-mt;\r
+                       double kai=((double)(sa*(ma*ma)+sb*(mb*mb)))/dv;\r
+                       if(max<kai){\r
+                               max_mt=mt;\r
+                               max=kai;\r
+                               th=i;\r
+                       }\r
+                       //System.out.println(kai);\r
+               }\r
+               //max_mtを元に正規化\r
+               this._score=max/((double)(pt+max_mt*max_mt*st-2*max_mt*dt)/st);//129,0.8888888888888887\r
+               return th;\r
+       }\r
+       /**\r
+        * 最後に実行したgetThresholdのスコアを返します。\r
+        * スコアは正規化された分離度です。1.0>n>0.0の値を取ります。\r
+        * 0.7以上なら概ね双峰的で有ることを示します。\r
+        * @return\r
+        * 分離度\r
+        */\r
+       public final double getLastScore()\r
+       {\r
+               return this._score;\r
+       }\r
+       /**\r
+        * Debug\r
+        */\r
+       public static void main(String[] args)\r
+       {\r
+               NyARHistogram data=new NyARHistogram(256);\r
+               for(int i=0;i<256;i++){\r
+                       data.data[i]=128-i>0?128-i:i-128;\r
+               }\r
+               data.total_of_data=data.getTotal(0,255);\r
+               NyARHistogramAnalyzer_DiscriminantThreshold an=new NyARHistogramAnalyzer_DiscriminantThreshold();\r
+               int th=an.getThreshold(data);\r
+               System.out.print(th);\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/NyARHistogramAnalyzer_KittlerThreshold.java b/lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/NyARHistogramAnalyzer_KittlerThreshold.java
new file mode 100644 (file)
index 0000000..fd99fda
--- /dev/null
@@ -0,0 +1,89 @@
+package jp.nyatla.nyartoolkit.core.analyzer.histogram;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistogram;\r
+\r
+\r
+/**\r
+ * kittlerThresholdの方式で閾値を求めます。\r
+ */\r
+public class NyARHistogramAnalyzer_KittlerThreshold implements INyARHistogramAnalyzer_Threshold\r
+{\r
+       /**\r
+        * @override\r
+        */\r
+       public int getThreshold(NyARHistogram i_histogram)\r
+       {\r
+               int i;          \r
+               double min=Double.MAX_VALUE;\r
+               int th=0;\r
+               int da,sa,db,sb,pa,pb;\r
+               double oa,ob;\r
+               \r
+               int[] hist=i_histogram.data;\r
+               int n=i_histogram.length;\r
+               //Low側\r
+               da=pa=0;\r
+               int h;\r
+               for(i=0;i<n;i++){\r
+                       h=hist[i];\r
+                       da+=h*i;        //i*h[i]\r
+                       pa+=h*i*i;      //i*i*h[i]\r
+               }\r
+               sa=i_histogram.total_of_data;\r
+               //High側(i=n-1)\r
+               db=0;\r
+               sb=0;\r
+               pb=0;\r
+               \r
+               \r
+               for(i=n-1;i>0;i--){\r
+                       //次のヒストグラムを計算\r
+                       int hist_count=hist[i];//h[i]\r
+                       int hist_val =hist_count*i;  //h[i]*i\r
+                       int hist_val2=hist_val*i;    //h[i]*i*i\r
+                       da-=hist_val;\r
+                       sa-=hist_count;\r
+                       pa-=hist_val2;\r
+                       db+=hist_val;\r
+                       sb+=hist_count;                 \r
+                       pb+=hist_val2;\r
+\r
+                       //初期化\r
+                       double wa=(double)sa/(sa+sb);\r
+                       double wb=(double)sb/(sa+sb);\r
+                       if(wa==0 || wb==0){\r
+                               continue;\r
+                       }\r
+\r
+                       oa=ob=0;\r
+                       double ma=sa!=0?(double)da/sa:0;\r
+                       //Σ(i-ma)^2*h[i]=Σ(i^2*h[i])+Σ(ma^2*h[i])-Σ(2*i*ma*h[i])\r
+                       oa=((double)(pa+ma*ma*sa-2*ma*da))/sa;\r
+\r
+                       double mb=sb!=0?(double)db/sb:0;\r
+                       //Σ(i-mb)^2*h[i]=Σ(i^2*h[i])+Σ(mb^2*h[i])-Σ(2*i*mb*h[i])\r
+                       ob=((double)(pb+mb*mb*sb-2*mb*db))/sb;\r
+\r
+                       double kai=wa*Math.log(oa/wa)+wb*Math.log(ob/wb);\r
+                       if(kai>0 && min>kai){\r
+                               min=kai;\r
+                               th=i;\r
+                       }\r
+                       //System.out.println(kai);\r
+\r
+               }\r
+               return th;//129//7.506713872738873\r
+       }\r
+       public static void main(String[] args)\r
+       {\r
+               NyARHistogram data=new NyARHistogram(256);\r
+               for(int i=0;i<256;i++){\r
+                       data.data[i]=128-i>0?128-i:i-128;\r
+               }\r
+               data.total_of_data=data.getTotal(0,255);\r
+               NyARHistogramAnalyzer_KittlerThreshold an=new NyARHistogramAnalyzer_KittlerThreshold();\r
+               int th=an.getThreshold(data);\r
+               System.out.print(th);\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/NyARHistogramAnalyzer_SlidePTile.java b/lib/src/jp/nyatla/nyartoolkit/core/analyzer/histogram/NyARHistogramAnalyzer_SlidePTile.java
new file mode 100644 (file)
index 0000000..369b12b
--- /dev/null
@@ -0,0 +1,57 @@
+package jp.nyatla.nyartoolkit.core.analyzer.histogram;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistogram;\r
+\r
+\r
+\r
+/**\r
+ * PTileを使った敷居値決定クラスです。\r
+ * 明点と暗点を双方向からPTile法で敷居値を計算し、その中央値を閾値とします。\r
+ * \r
+ * \r
+ */\r
+public class NyARHistogramAnalyzer_SlidePTile implements INyARHistogramAnalyzer_Threshold\r
+{\r
+       private int _persentage;\r
+       /**\r
+        * コンストラクタです。\r
+        * @param i_persentage\r
+        * 敷居値とする、PTileのパーセンテージ値を指定します。\r
+        */\r
+       public NyARHistogramAnalyzer_SlidePTile(int i_persentage)\r
+       {\r
+               assert (0 <= i_persentage && i_persentage <= 50);\r
+               //初期化\r
+               this._persentage=i_persentage;\r
+       }       \r
+       public int getThreshold(NyARHistogram i_histogram)\r
+       {\r
+               //総ピクセル数を計算\r
+               int n=i_histogram.length;\r
+               int sum_of_pixel=i_histogram.total_of_data;\r
+               int[] hist=i_histogram.data;\r
+               // 閾値ピクセル数確定\r
+               final int th_pixcels = sum_of_pixel * this._persentage / 100;\r
+               int th_wk;\r
+               int th_w, th_b;\r
+\r
+               // 黒点基準\r
+               th_wk = th_pixcels;\r
+               for (th_b = 0; th_b < n-2; th_b++) {\r
+                       th_wk -= hist[th_b];\r
+                       if (th_wk <= 0) {\r
+                               break;\r
+                       }\r
+               }\r
+               // 白点基準\r
+               th_wk = th_pixcels;\r
+               for (th_w = n-1; th_w > 1; th_w--) {\r
+                       th_wk -= hist[th_w];\r
+                       if (th_wk <= 0) {\r
+                               break;\r
+                       }\r
+               }\r
+               // 閾値の保存\r
+               return (th_w + th_b) / 2;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/analyzer/raster/NyARRasterAnalyzer_Histogram.java b/lib/src/jp/nyatla/nyartoolkit/core/analyzer/raster/NyARRasterAnalyzer_Histogram.java
new file mode 100644 (file)
index 0000000..a4540d0
--- /dev/null
@@ -0,0 +1,364 @@
+package jp.nyatla.nyartoolkit.core.analyzer.raster;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * 画像のヒストグラムを計算します。\r
+ * RGBの場合、(R+G+B)/3のヒストグラムを計算します。\r
+ * \r
+ * \r
+ */\r
+public class NyARRasterAnalyzer_Histogram\r
+{\r
+       protected ICreateHistogramImpl _histImpl;\r
+       /**\r
+        * ヒストグラム解析の縦方向スキップ数。継承クラスはこのライン数づつ\r
+        * スキップしながらヒストグラム計算を行うこと。\r
+        */\r
+       protected int _vertical_skip;\r
+       \r
+       \r
+       public NyARRasterAnalyzer_Histogram(int i_raster_format,int i_vertical_interval) throws NyARException\r
+       {\r
+               if(!initInstance(i_raster_format,i_vertical_interval)){\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       protected boolean initInstance(int i_raster_format,int i_vertical_interval)\r
+       {\r
+               switch (i_raster_format) {\r
+               case  NyARBufferType.BYTE1D_B8G8R8_24:\r
+               case  NyARBufferType.BYTE1D_R8G8B8_24:\r
+                       this._histImpl = new NyARRasterThresholdAnalyzer_Histogram_BYTE1D_RGB_24();\r
+                       break;\r
+               case  NyARBufferType.INT1D_GRAY_8:\r
+                       this._histImpl = new NyARRasterThresholdAnalyzer_Histogram_INT1D_GRAY_8();\r
+                       break;\r
+               case  NyARBufferType.BYTE1D_B8G8R8X8_32:\r
+                       this._histImpl = new NyARRasterThresholdAnalyzer_Histogram_BYTE1D_B8G8R8X8_32();\r
+                       break;\r
+               case  NyARBufferType.BYTE1D_X8R8G8B8_32:\r
+                       this._histImpl = new NyARRasterThresholdAnalyzer_Histogram_BYTE1D_X8R8G8B8_32();\r
+                       break;\r
+               case  NyARBufferType.WORD1D_R5G6B5_16LE:\r
+                       this._histImpl = new NyARRasterThresholdAnalyzer_Histogram_WORD1D_R5G6B5_16LE();\r
+                       break;\r
+               case  NyARBufferType.INT1D_X8R8G8B8_32:\r
+                       this._histImpl = new NyARRasterThresholdAnalyzer_Histogram_INT1D_X8R8G8B8_32();\r
+                       break;\r
+               default:\r
+                       return false;\r
+               }\r
+               //初期化\r
+               this._vertical_skip=i_vertical_interval;\r
+               return true;\r
+       }       \r
+       \r
+       \r
+       public void setVerticalInterval(int i_step)\r
+       {\r
+               assert(this._vertical_skip>0);\r
+               this._vertical_skip=i_step;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * o_histogramにヒストグラムを出力します。\r
+        * @param i_input\r
+        * @param o_histogram\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public void analyzeRaster(INyARRaster i_input,NyARHistogram o_histogram) throws NyARException\r
+       {\r
+               \r
+               final NyARIntSize size=i_input.getSize();\r
+               //最大画像サイズの制限\r
+               assert(size.w*size.h<0x40000000);\r
+               assert(o_histogram.length==256);//現在は固定\r
+\r
+               int[] h=o_histogram.data;\r
+               //ヒストグラム初期化\r
+               for (int i = o_histogram.length-1; i >=0; i--){\r
+                       h[i] = 0;\r
+               }\r
+               o_histogram.total_of_data=size.w*size.h/this._vertical_skip;\r
+               this._histImpl.createHistogram(i_input,0,0,size.w,size.h,o_histogram.data,this._vertical_skip);\r
+               return;\r
+       }\r
+       public void analyzeRaster(INyARRaster i_input,NyARIntRect i_area,NyARHistogram o_histogram) throws NyARException\r
+       {\r
+               \r
+               final NyARIntSize size=i_input.getSize();\r
+               //最大画像サイズの制限\r
+               assert(size.w*size.h<0x40000000);\r
+               assert(o_histogram.length==256);//現在は固定\r
+\r
+               int[] h=o_histogram.data;\r
+               //ヒストグラム初期化\r
+               for (int i = o_histogram.length-1; i >=0; i--){\r
+                       h[i] = 0;\r
+               }\r
+               o_histogram.total_of_data=i_area.w*i_area.h/this._vertical_skip;\r
+               this._histImpl.createHistogram(i_input,i_area.x,i_area.y,i_area.w,i_area.h,o_histogram.data,this._vertical_skip);\r
+               return;\r
+       }\r
+       \r
+       protected interface ICreateHistogramImpl\r
+       {\r
+               public void createHistogram(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h, int[] o_histogram,int i_skip);\r
+       }\r
+\r
+       class NyARRasterThresholdAnalyzer_Histogram_INT1D_GRAY_8 implements ICreateHistogramImpl\r
+       {\r
+               public void createHistogram(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h, int[] o_histogram,int i_skip)\r
+               {\r
+                       assert (i_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       final int[] input=(int[])i_raster.getBuffer();\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip=(i_skip*s.w-i_w);\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt=(i_t*s.w+i_l);\r
+                       for (int y = i_h-1; y >=0 ; y-=i_skip){\r
+                               int x;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       o_histogram[input[pt++]]++;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       o_histogram[input[pt++]]++;\r
+                                       o_histogram[input[pt++]]++;\r
+                                       o_histogram[input[pt++]]++;\r
+                                       o_histogram[input[pt++]]++;\r
+                                       o_histogram[input[pt++]]++;\r
+                                       o_histogram[input[pt++]]++;\r
+                                       o_histogram[input[pt++]]++;\r
+                                       o_histogram[input[pt++]]++;\r
+                               }\r
+                               //スキップ\r
+                               pt+=skip;\r
+                       }\r
+                       return;                 \r
+\r
+               }       \r
+       }\r
+       class NyARRasterThresholdAnalyzer_Histogram_INT1D_X8R8G8B8_32 implements ICreateHistogramImpl\r
+       {\r
+               public void createHistogram(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h, int[] o_histogram,int i_skip)\r
+               {\r
+                       assert (i_raster.isEqualBufferType( NyARBufferType.INT1D_X8R8G8B8_32));\r
+                       final int[] input=(int[])i_raster.getBuffer();\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip=(i_skip*s.w-i_w);\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt=(i_t*s.w+i_l);\r
+                       for (int y = i_h-1; y >=0 ; y-=i_skip){\r
+                               int x,v;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       v=input[pt++];o_histogram[((v& 0xff)+(v& 0xff)+(v& 0xff))/3]++;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       v=input[pt++];o_histogram[((v& 0xff)+(v& 0xff)+(v& 0xff))/3]++;\r
+                                       v=input[pt++];o_histogram[((v& 0xff)+(v& 0xff)+(v& 0xff))/3]++;\r
+                                       v=input[pt++];o_histogram[((v& 0xff)+(v& 0xff)+(v& 0xff))/3]++;\r
+                                       v=input[pt++];o_histogram[((v& 0xff)+(v& 0xff)+(v& 0xff))/3]++;\r
+                                       v=input[pt++];o_histogram[((v& 0xff)+(v& 0xff)+(v& 0xff))/3]++;\r
+                                       v=input[pt++];o_histogram[((v& 0xff)+(v& 0xff)+(v& 0xff))/3]++;\r
+                                       v=input[pt++];o_histogram[((v& 0xff)+(v& 0xff)+(v& 0xff))/3]++;\r
+                                       v=input[pt++];o_histogram[((v& 0xff)+(v& 0xff)+(v& 0xff))/3]++;\r
+                               }\r
+                               //スキップ\r
+                               pt+=skip;\r
+                       }\r
+                       return;                 \r
+               }       \r
+       }\r
+\r
+       \r
+       class NyARRasterThresholdAnalyzer_Histogram_BYTE1D_RGB_24 implements ICreateHistogramImpl\r
+       {\r
+               public void createHistogram(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h, int[] o_histogram,int i_skip)\r
+               {\r
+                       assert (\r
+                                       i_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24)||\r
+                                       i_raster.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));\r
+                       final byte[] input=(byte[])i_raster.getBuffer();\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip=(i_skip*s.w-i_w)*3;\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt=(i_t*s.w+i_l)*3;\r
+                       for (int y = i_h-1; y >=0 ; y-=i_skip){\r
+                               int x;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=3;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=3*8;\r
+                               }\r
+                               //スキップ\r
+                               pt+=skip;\r
+                       }\r
+                       return; \r
+               }\r
+       }\r
+\r
+       class NyARRasterThresholdAnalyzer_Histogram_BYTE1D_B8G8R8X8_32 implements ICreateHistogramImpl\r
+       {\r
+               public void createHistogram(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h, int[] o_histogram,int i_skip)\r
+               {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8X8_32));\r
+                       final byte[] input=(byte[])i_raster.getBuffer();\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip=(i_skip*s.w-i_w)*4;\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt=(i_t*s.w+i_l)*4;\r
+                       for (int y = i_h-1; y >=0 ; y-=i_skip){\r
+                               int x;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                               }\r
+                               //スキップ\r
+                               pt+=skip;\r
+                       }\r
+                       return; \r
+           }\r
+       }\r
+\r
+       class NyARRasterThresholdAnalyzer_Histogram_BYTE1D_X8R8G8B8_32 implements ICreateHistogramImpl\r
+       {\r
+               public void createHistogram(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h, int[] o_histogram,int i_skip)\r
+               {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.BYTE1D_X8R8G8B8_32));\r
+                       final byte[] input=(byte[])i_raster.getBuffer();\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip=(i_skip*s.w-i_w)*4;\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt=(i_t*s.w+i_l)*4;\r
+                       for (int y = i_h-1; y >=0 ; y-=i_skip){\r
+                               int x;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       o_histogram[((input[pt+1]& 0xff)+(input[pt+2]& 0xff)+(input[pt+ 3]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       o_histogram[((input[pt+1]& 0xff)+(input[pt+2]& 0xff)+(input[pt+3]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+1]& 0xff)+(input[pt+2]& 0xff)+(input[pt+3]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+1]& 0xff)+(input[pt+2]& 0xff)+(input[pt+3]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+1]& 0xff)+(input[pt+2]& 0xff)+(input[pt+3]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+1]& 0xff)+(input[pt+2]& 0xff)+(input[pt+3]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+1]& 0xff)+(input[pt+2]& 0xff)+(input[pt+3]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+1]& 0xff)+(input[pt+2]& 0xff)+(input[pt+3]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                                       o_histogram[((input[pt+1]& 0xff)+(input[pt+2]& 0xff)+(input[pt+3]& 0xff))/3]++;\r
+                                       pt+=4;\r
+                               }\r
+                               //スキップ\r
+                               pt+=skip;\r
+                       }\r
+                       return; \r
+           }\r
+       }\r
+\r
+       class NyARRasterThresholdAnalyzer_Histogram_WORD1D_R5G6B5_16LE implements ICreateHistogramImpl\r
+       {\r
+               public void createHistogram(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h, int[] o_histogram,int i_skip)\r
+               {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.WORD1D_R5G6B5_16LE));\r
+                       final short[] input=(short[])i_raster.getBuffer();\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip=(i_skip*s.w-i_w);\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt=(i_t*s.w+i_l);\r
+                       for (int y = i_h-1; y >=0 ; y-=i_skip){\r
+                               int x,v;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       v =(int)input[pt++]; o_histogram[(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3]++;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       v =(int)input[pt++]; o_histogram[(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3]++;\r
+                                       v =(int)input[pt++]; o_histogram[(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3]++;\r
+                                       v =(int)input[pt++]; o_histogram[(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3]++;\r
+                                       v =(int)input[pt++]; o_histogram[(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3]++;\r
+                                       v =(int)input[pt++]; o_histogram[(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3]++;\r
+                                       v =(int)input[pt++]; o_histogram[(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3]++;\r
+                                       v =(int)input[pt++]; o_histogram[(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3]++;\r
+                                       v =(int)input[pt++]; o_histogram[(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3]++;\r
+                               }\r
+                               //スキップ\r
+                               pt+=skip;\r
+                       }\r
+                       return; \r
+           }\r
+       }\r
+\r
+       public static void main(String[] args)\r
+       {\r
+               try{\r
+                       NyARRgbRaster raster=new NyARRgbRaster(100,100,NyARBufferType.WORD1D_R5G6B5_16LE);\r
+                       short[] buf=(short[])raster.getBuffer();\r
+                       for(int i=0;i<100;i++){\r
+                               for(int i2=0;i2<100;i2++){\r
+                                       buf[(i*100+i2)+0]=(short)(3); //buf[(i*100+i2)*3+1]=buf[(i*100+i2)*3+2]=(byte)i2;\r
+                               }\r
+                       }\r
+                       NyARIntRect rect=new NyARIntRect();\r
+                       rect.x=2;rect.y=2;rect.h=10;rect.w=10;\r
+                       NyARRasterAnalyzer_Histogram ha=new NyARRasterAnalyzer_Histogram(raster.getBufferType(),1);\r
+                       NyARHistogram h=new NyARHistogram(256);\r
+                       ha.analyzeRaster(raster,rect, h);\r
+//                     ha.analyzeRaster(raster, h);\r
+                       return;\r
+                       \r
+               }catch(Exception e){\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/analyzer/raster/threshold/INyARRasterThresholdAnalyzer.java b/lib/src/jp/nyatla/nyartoolkit/core/analyzer/raster/threshold/INyARRasterThresholdAnalyzer.java
new file mode 100644 (file)
index 0000000..f316616
--- /dev/null
@@ -0,0 +1,36 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.analyzer.raster.threshold;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public interface INyARRasterThresholdAnalyzer\r
+{\r
+       public int analyzeRaster(INyARRaster i_input) throws NyARException;\r
+       public int analyzeRaster(INyARRaster i_input,NyARIntRect i_area) throws NyARException;\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/analyzer/raster/threshold/NyARRasterThresholdAnalyzer_SlidePTile.java b/lib/src/jp/nyatla/nyartoolkit/core/analyzer/raster/threshold/NyARRasterThresholdAnalyzer_SlidePTile.java
new file mode 100644 (file)
index 0000000..1dce534
--- /dev/null
@@ -0,0 +1,49 @@
+package jp.nyatla.nyartoolkit.core.analyzer.raster.threshold;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.analyzer.histogram.*;\r
+import jp.nyatla.nyartoolkit.core.analyzer.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistogram;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntRect;\r
+/**\r
+ * 明点と暗点をPタイル法で検出して、その中央値を閾値とする。\r
+ * \r
+ * \r
+ */\r
+public class NyARRasterThresholdAnalyzer_SlidePTile implements INyARRasterThresholdAnalyzer\r
+{\r
+       protected NyARRasterAnalyzer_Histogram _raster_analyzer;\r
+       private NyARHistogramAnalyzer_SlidePTile _sptile;\r
+       private NyARHistogram _histogram;\r
+       public void setVerticalInterval(int i_step)\r
+       {\r
+               this._raster_analyzer.setVerticalInterval(i_step);\r
+               return;\r
+       }\r
+       public NyARRasterThresholdAnalyzer_SlidePTile(int i_persentage,int i_raster_format,int i_vertical_interval) throws NyARException\r
+       {\r
+               assert (0 <= i_persentage && i_persentage <= 50);\r
+               //初期化\r
+               if(!initInstance(i_raster_format,i_vertical_interval)){\r
+                       throw new NyARException();\r
+               }\r
+               this._sptile=new NyARHistogramAnalyzer_SlidePTile(i_persentage);\r
+               this._histogram=new NyARHistogram(256);\r
+       }\r
+       protected boolean initInstance(int i_raster_format,int i_vertical_interval) throws NyARException\r
+       {\r
+               this._raster_analyzer=new NyARRasterAnalyzer_Histogram(i_raster_format,i_vertical_interval);\r
+               return true;\r
+       }\r
+       public int analyzeRaster(INyARRaster i_input) throws NyARException\r
+       {\r
+               this._raster_analyzer.analyzeRaster(i_input, this._histogram);\r
+               return this._sptile.getThreshold(this._histogram);\r
+       }\r
+       public int analyzeRaster(INyARRaster i_input,NyARIntRect i_area) throws NyARException\r
+       {\r
+               throw new NyARException();\r
+       }\r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelInfo.java b/lib/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelInfo.java
new file mode 100644 (file)
index 0000000..74a85cd
--- /dev/null
@@ -0,0 +1,48 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling;\r
+\r
+
+/**\r
+ * \r
+ *\r
+ */\r
+public class NyARLabelInfo\r
+{\r
+       public int area;\r
+       public int clip_r;\r
+       public int clip_l;\r
+       public int clip_b;\r
+       public int clip_t;\r
+       public double pos_x;\r
+       public double pos_y;\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelOverlapChecker.java b/lib/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelOverlapChecker.java
new file mode 100644 (file)
index 0000000..7e4b033
--- /dev/null
@@ -0,0 +1,104 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling;\r
+\r
+import java.lang.reflect.Array;\r
+\r
+\r
+/**\r
+ * ラベル同士の重なり(内包関係)を調べるクラスです。 \r
+ * ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。\r
+ */\r
+public class NyARLabelOverlapChecker<T extends NyARLabelInfo>\r
+{\r
+       private T[] _labels;\r
+       private int _length;\r
+       private Class<T> _element_type;\r
+       /*\r
+       */\r
+       @SuppressWarnings("unchecked")\r
+       public NyARLabelOverlapChecker(int i_max_label,Class<T> i_element_type)\r
+       {\r
+               this._element_type=i_element_type;\r
+               this._labels = (T[])Array.newInstance(i_element_type, i_max_label);\r
+       }\r
+\r
+       /**\r
+        * チェック対象のラベルを追加する。\r
+        * \r
+        * @param i_label_ref\r
+        */\r
+       public void push(T i_label_ref)\r
+       {\r
+               this._labels[this._length] = i_label_ref;\r
+               this._length++;\r
+       }\r
+\r
+       /**\r
+        * 現在リストにあるラベルと重なっているかを返す。\r
+        * \r
+        * @param i_label\r
+        * @return 何れかのラベルの内側にあるならばfalse,独立したラベルである可能性が高ければtrueです.\r
+        */\r
+       public boolean check(T i_label)\r
+       {\r
+               // 重なり処理かな?\r
+               final T[] label_pt = this._labels;\r
+               final int px1 = (int) i_label.pos_x;\r
+               final int py1 = (int) i_label.pos_y;\r
+               for (int i = this._length - 1; i >= 0; i--) {\r
+                       final int px2 = (int) label_pt[i].pos_x;\r
+                       final int py2 = (int) label_pt[i].pos_y;\r
+                       final int d = (px1 - px2) * (px1 - px2) + (py1 - py2) * (py1 - py2);\r
+                       if (d < label_pt[i].area / 4) {\r
+                               // 対象外\r
+                               return false;\r
+                       }\r
+               }\r
+               // 対象\r
+               return true;\r
+       }\r
+       /**\r
+        * 最大i_max_label個のラベルを蓄積できるようにオブジェクトをリセットする\r
+        * \r
+        * @param i_max_label\r
+        */\r
+       @SuppressWarnings("unchecked")\r
+       public void setMaxLabels(int i_max_label)\r
+       {\r
+               if (i_max_label > this._labels.length) {\r
+                       this._labels = (T[])Array.newInstance(this._element_type, i_max_label);\r
+               }\r
+               this._length = 0;\r
+       }       \r
+       \r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingImage.java b/lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingImage.java
new file mode 100644 (file)
index 0000000..79c7b81
--- /dev/null
@@ -0,0 +1,142 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ *\r
+ */\r
+public class NyARLabelingImage extends NyARRaster_BasicClass\r
+{\r
+       private final static int MAX_LABELS = 1024*32;\r
+\r
+       protected int[] _ref_buf;\r
+       protected NyARLabelingLabelStack _label_list;\r
+       protected int[] _index_table;\r
+       protected boolean _is_index_table_enable;\r
+       public NyARLabelingImage(int i_width, int i_height) throws NyARException\r
+       {\r
+               super(i_width,i_height,NyARBufferType.INT1D);\r
+               this._ref_buf =new int[i_height*i_width];\r
+               this._label_list = new NyARLabelingLabelStack(MAX_LABELS);\r
+               this._index_table=new int[MAX_LABELS];\r
+               this._is_index_table_enable=false;\r
+               //生成時に枠を書きます。\r
+               drawFrameEdge();\r
+               return;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._ref_buf;\r
+       }\r
+       public boolean hasBuffer()\r
+       {\r
+               return this._ref_buf!=null;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               NyARException.notImplement();\r
+       }       \r
+       /**\r
+        * エッジを書きます。\r
+        */\r
+       public void drawFrameEdge()\r
+       {\r
+               int w=this._size.w;\r
+               int h=this._size.h;\r
+               // NyLabelingImageのイメージ初期化(枠書き)\r
+               int[] img = (int[]) this._ref_buf;\r
+               int bottom_ptr = (h - 1) * w;\r
+               for (int i = 0; i < w; i++) {\r
+                       img[i] = 0;\r
+                       img[bottom_ptr + i] = 0;\r
+               }\r
+               for (int i = 0; i < h; i++) {\r
+                       img[i * w] = 0;\r
+                       img[(i + 1) * w - 1] = 0;\r
+               }\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * ラベリング結果がインデックステーブルを持つ場合、その配列を返します。\r
+        * 持たない場合、nullを返します。\r
+        * \r
+        * 値がnullの時はラベル番号そのものがラスタに格納されていますが、\r
+        * null以外の時はラスタに格納されているのはインデクス番号です。\r
+        * \r
+        * インデクス番号とラベル番号の関係は、以下の式で表されます。\r
+        * ラベル番号:=value[インデクス番号]\r
+        * \r
+        */\r
+       public int[] getIndexArray()\r
+       {\r
+               return this._is_index_table_enable?this._index_table:null;\r
+       }\r
+       \r
+       public NyARLabelingLabelStack getLabelStack()\r
+       {\r
+               return this._label_list;\r
+       }\r
+       public void reset(boolean i_label_index_enable)\r
+       {\r
+               assert(i_label_index_enable==true);//非ラベルモードは未実装\r
+               this._label_list.clear();\r
+               this._is_index_table_enable=i_label_index_enable;\r
+               return;\r
+       }\r
+       /**\r
+        * i_labelのラベルの、クリップ領域が上辺に接しているx座標を返します。\r
+        * @param i_index\r
+        * @return\r
+        */\r
+       public int getTopClipTangentX(NyARLabelingLabel i_label) throws NyARException\r
+       {\r
+               int pix;\r
+               int i_label_id=i_label.id;\r
+               int[] index_table=this._index_table;\r
+               int[] limage=this._ref_buf;\r
+               int limage_ptr=i_label.clip_t*this._size.w;\r
+               final int clip1 = i_label.clip_r;\r
+               // p1=ShortPointer.wrap(limage,j*xsize+clip.get());//p1 =&(limage[j*xsize+clip[0]]);\r
+               for (int i = i_label.clip_l; i <= clip1; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {\r
+                       pix = limage[limage_ptr+i];\r
+                       if (pix > 0 && index_table[pix-1] == i_label_id){\r
+                               return i;\r
+                       }\r
+               }\r
+               //あれ?見つからないよ?\r
+               throw new NyARException();\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingLabel.java b/lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingLabel.java
new file mode 100644 (file)
index 0000000..3caa05c
--- /dev/null
@@ -0,0 +1,42 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
+/**\r
+ * [[Strage class]]\r
+ *\r
+ */\r
+public class NyARLabelingLabel extends NyARLabelInfo\r
+{\r
+       public int id; // フラグメントラベルのインデクス\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingLabelStack.java b/lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingLabelStack.java
new file mode 100644 (file)
index 0000000..6bba376
--- /dev/null
@@ -0,0 +1,86 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.artoolkit;\r
+\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.stack.NyARObjectStack;\r
+\r
+/**\r
+ * NyLabelの予約型動的配列\r
+ * \r
+ */\r
+public class NyARLabelingLabelStack extends NyARObjectStack<NyARLabelingLabel>\r
+{\r
+       public NyARLabelingLabelStack(int i_max_array_size) throws NyARException\r
+       {\r
+               super();\r
+               super.initInstance(i_max_array_size,NyARLabelingLabel.class);\r
+       }\r
+       protected NyARLabelingLabel createElement()\r
+       {\r
+               return new NyARLabelingLabel();\r
+       }\r
+       /**\r
+        * 配列をエリアでソートする。\r
+        * @param i_array\r
+        * @param i_length\r
+        */\r
+       final public void sortByArea()\r
+       {\r
+               int len=this._length;\r
+               if(len<1){\r
+                       return;\r
+               }\r
+               int h = len *13/10;\r
+               NyARLabelingLabel[] item=this._items;\r
+               for(;;){\r
+                   int swaps = 0;\r
+                   for (int i = 0; i + h < len; i++) {\r
+                       if (item[i + h].area > item[i].area) {\r
+                           final NyARLabelingLabel temp = item[i + h];\r
+                           item[i + h] = item[i];\r
+                           item[i] = temp;\r
+                           swaps++;\r
+                       }\r
+                   }\r
+                   if (h == 1) {\r
+                       if (swaps == 0){\r
+                               break;\r
+                       }\r
+                   }else{\r
+                       h=h*10/13;\r
+                   }\r
+               }               \r
+       }       \r
+}\r
+       \r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabeling_ARToolKit.java b/lib/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabeling_ARToolKit.java
new file mode 100644 (file)
index 0000000..860ad86
--- /dev/null
@@ -0,0 +1,318 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * ARToolKit互換のラベリングクラスです。 ARToolKitと同一な評価結果を返します。\r
+ * \r
+ */\r
+final public class NyARLabeling_ARToolKit\r
+{\r
+       private static final int WORK_SIZE = 1024 * 32;// #define WORK_SIZE 1024*32\r
+\r
+       private final NyARWorkHolder work_holder = new NyARWorkHolder(WORK_SIZE);\r
+\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
+        * ラスタimageをラベリングして、結果を保存します。 Optimize:STEP[1514->1493]\r
+        * \r
+        * @param i_raster\r
+        * @throws NyARException\r
+        */\r
+       public int labeling(NyARBinRaster i_raster,NyARLabelingImage o_destination) throws NyARException\r
+       {\r
+               assert(i_raster.getBufferType()==NyARBufferType.INT1D_BIN_8);\r
+               int label_img_ptr1, label_pixel;\r
+               int i, j;\r
+               int n, k; /* work */\r
+               \r
+               // サイズチェック\r
+               NyARIntSize in_size = i_raster.getSize();\r
+               assert(o_destination.getSize().isEqualSize(in_size));\r
+\r
+               final int lxsize = in_size.w;// lxsize = arUtil_c.arImXsize;\r
+               final int lysize = in_size.h;// lysize = arUtil_c.arImYsize;\r
+               final int[] label_img = (int[]) o_destination.getBuffer();\r
+\r
+               // 枠作成はインスタンスを作った直後にやってしまう。\r
+\r
+               // ラベリング情報のリセット(ラベリングインデックスを使用)\r
+               o_destination.reset(true);\r
+\r
+               int[] label_idxtbl = o_destination.getIndexArray();\r
+               int[] raster_buf = (int[]) i_raster.getBuffer();\r
+\r
+               int[] work2_pt;\r
+               int wk_max = 0;\r
+\r
+               int pixel_index;\r
+               int[][] work2 = this.work_holder.work2;\r
+\r
+               // [1,1](ptr0)と、[0,1](ptr1)のインデクス値を計算する。\r
+               for (j = 1; j < lysize - 1; j++) {// for (int j = 1; j < lysize - 1;j++, pnt += poff*2, pnt2 += 2) {\r
+                       pixel_index = j * lxsize + 1;\r
+                       label_img_ptr1 = pixel_index - lxsize;// label_img_pt1 = label_img[j - 1];\r
+                       for (i = 1; i < lxsize - 1; i++, pixel_index++, label_img_ptr1++) {// for(int i = 1; i < lxsize-1;i++, pnt+=poff, pnt2++) {\r
+                               // RGBの合計値が閾値より小さいかな?\r
+                               if (raster_buf[pixel_index] != 0) {\r
+                                       label_img[pixel_index] = 0;// label_img_pt0[i] = 0;// *pnt2 = 0;\r
+                               } else {\r
+                                       // pnt1 = ShortPointer.wrap(pnt2, -lxsize);//pnt1 =&(pnt2[-lxsize]);\r
+                                       if (label_img[label_img_ptr1] > 0) {// if (label_img_pt1[i] > 0) {// if( *pnt1 > 0 ) {\r
+                                               label_pixel = label_img[label_img_ptr1];// label_pixel = label_img_pt1[i];// *pnt2 = *pnt1;\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[label_img_ptr1 + 1] > 0) {// } else if (label_img_pt1[i + 1] > 0) {// }else if(*(pnt1+1) > 0 ) {\r
+                                               if (label_img[label_img_ptr1 - 1] > 0) {// if (label_img_pt1[i - 1] > 0) {// if( *(pnt1-1) > 0 ) {\r
+                                                       label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1];// m = label_idxtbl[label_img_pt1[i + 1] - 1];// m\r
+                                                                                                                                                                                       // =work[*(pnt1+1)-1];\r
+                                                       n = label_idxtbl[label_img[label_img_ptr1 - 1] - 1];// n = label_idxtbl[label_img_pt1[i - 1] - 1];// n =work[*(pnt1-1)-1];\r
+                                                       if (label_pixel > n) {\r
+                                                               // wk=IntPointer.wrap(work, 0);//wk = &(work[0]);\r
+                                                               for (k = 0; k < wk_max; k++) {\r
+                                                                       if (label_idxtbl[k] == label_pixel) {// if( *wk == m )\r
+                                                                               label_idxtbl[k] = n;// *wk = n;\r
+                                                                       }\r
+                                                               }\r
+                                                               label_pixel = n;// *pnt2 = n;\r
+                                                       } else if (label_pixel < n) {\r
+                                                               // wk=IntPointer.wrap(work,0);//wk = &(work[0]);\r
+                                                               for (k = 0; k < wk_max; k++) {\r
+                                                                       if (label_idxtbl[k] == n) {// if( *wk == n ){\r
+                                                                               label_idxtbl[k] = label_pixel;// *wk = m;\r
+                                                                       }\r
+                                                               }\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[pixel_index - 1]) > 0) {// } else if ((label_img_pt0[i - 1]) > 0) {// }else if(*(pnt2-1) > 0) {\r
+                                                       label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1];// m = label_idxtbl[label_img_pt1[i + 1] - 1];// m =work[*(pnt1+1)-1];\r
+                                                       n = label_idxtbl[label_img[pixel_index - 1] - 1];// n = label_idxtbl[label_img_pt0[i - 1] - 1];// n =work[*(pnt2-1)-1];\r
+                                                       if (label_pixel > n) {\r
+                                                               for (k = 0; k < wk_max; k++) {\r
+                                                                       if (label_idxtbl[k] == label_pixel) {// if( *wk == m ){\r
+                                                                               label_idxtbl[k] = n;// *wk = n;\r
+                                                                       }\r
+                                                               }\r
+                                                               label_pixel = n;// *pnt2 = n;\r
+                                                       } else if (label_pixel < n) {\r
+                                                               for (k = 0; k < wk_max; k++) {\r
+                                                                       if (label_idxtbl[k] == n) {// if( *wk == n ){\r
+                                                                               label_idxtbl[k] = label_pixel;// *wk = m;\r
+                                                                       }\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
+                                               } else {\r
+\r
+                                                       label_pixel = label_img[label_img_ptr1 + 1];// label_pixel = label_img_pt1[i + 1];// *pnt2 =\r
+                                                       // *(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[label_img_ptr1 - 1]) > 0) {// } else if ((label_img_pt1[i - 1]) > 0) {// }else if(\r
+                                               // *(pnt1-1) > 0 ) {\r
+                                               label_pixel = label_img[label_img_ptr1 - 1];// label_pixel = label_img_pt1[i - 1];// *pnt2 =\r
+                                               // *(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[pixel_index - 1] > 0) {// } else if (label_img_pt0[i - 1] > 0) {// }else if(*(pnt2-1) > 0) {\r
+                                               label_pixel = label_img[pixel_index - 1];// 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
+                                               label_idxtbl[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[pixel_index] = label_pixel;// label_img_pt0[i] = label_pixel;\r
+                               }\r
+                       }\r
+\r
+               }\r
+               // インデックステーブルとラベル数の計算\r
+               int wlabel_num = 1;// *label_num = *wlabel_num = j - 1;\r
+\r
+               for (i = 0; i < wk_max; i++) {// for(int i = 1; i <= wk_max; i++,wk++) {\r
+                       label_idxtbl[i] = (label_idxtbl[i] == i + 1) ? wlabel_num++ : label_idxtbl[label_idxtbl[i] - 1];// *wk=(*wk==i)?j++:work[(*wk)-1];\r
+               }\r
+               wlabel_num -= 1;// *label_num = *wlabel_num = j - 1;\r
+               if (wlabel_num == 0) {// if( *label_num == 0 ) {\r
+                       // 発見数0\r
+                       o_destination.getLabelStack().clear();\r
+                       return 0;\r
+               }\r
+               // ラベル情報の保存等\r
+               NyARLabelingLabelStack label_list = o_destination.getLabelStack();\r
+\r
+               // ラベルバッファを予約\r
+               label_list.init(wlabel_num);\r
+\r
+               // エリアと重心、クリップ領域を計算\r
+               NyARLabelingLabel label_pt;\r
+               NyARLabelingLabel[] labels =label_list.getArray();\r
+               for (i = 0; i < wlabel_num; i++) {\r
+                       label_pt = labels[i];\r
+                       label_pt.id = (short)(i + 1);\r
+                       label_pt.area = 0;\r
+                       label_pt.pos_x = label_pt.pos_y = 0;\r
+                       label_pt.clip_l = lxsize;// wclip[i*4+0] = lxsize;\r
+                       label_pt.clip_t = lysize;// wclip[i*4+2] = lysize;\r
+                       label_pt.clip_r = label_pt.clip_b = 0;// wclip[i*4+3] = 0;\r
+               }\r
+\r
+               for (i = 0; i < wk_max; i++) {\r
+                       label_pt = labels[label_idxtbl[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.clip_l > work2_pt[3]) {\r
+                               label_pt.clip_l = work2_pt[3];\r
+                       }\r
+                       if (label_pt.clip_r < work2_pt[4]) {\r
+                               label_pt.clip_r = work2_pt[4];\r
+                       }\r
+                       if (label_pt.clip_t > work2_pt[5]) {\r
+                               label_pt.clip_t = work2_pt[5];\r
+                       }\r
+                       if (label_pt.clip_b < work2_pt[6]) {\r
+                               label_pt.clip_b = 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
+               return wlabel_num;\r
+       }\r
+\r
+}\r
+\r
+/**\r
+ * NyARLabeling_O2のworkとwork2を可変長にするためのクラス\r
+ * \r
+ * \r
+ */\r
+final class NyARWorkHolder\r
+{\r
+       private final static int ARRAY_APPEND_STEP = 256;\r
+\r
+       public final int[][] work2;\r
+\r
+       private int allocate_size;\r
+\r
+       /**\r
+        * 最大i_holder_size個の動的割り当てバッファを準備する。\r
+        * \r
+        * @param i_holder_size\r
+        */\r
+       public NyARWorkHolder(int i_holder_size)\r
+       {\r
+               // ポインタだけははじめに確保しておく\r
+               this.work2 = new int[i_holder_size][];\r
+               this.allocate_size = 0;\r
+       }\r
+\r
+       /**\r
+        * i_indexで指定した番号までのバッファを準備する。\r
+        * \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.work2.length) {\r
+                       throw new NyARException();\r
+               }\r
+               // 追加アロケート範囲を計算\r
+               int range = i_index + ARRAY_APPEND_STEP;\r
+               if (range >= this.work2.length) {\r
+                       range = this.work2.length;\r
+               }\r
+               // アロケート\r
+               for (int i = this.allocate_size; i < range; i++) {\r
+                       this.work2[i] = new int[7];\r
+               }\r
+               this.allocate_size = range;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARLabeling_Rle.java b/lib/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARLabeling_Rle.java
new file mode 100644 (file)
index 0000000..4144ad8
--- /dev/null
@@ -0,0 +1,448 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.rlelabeling;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.stack.NyARObjectStack;\r
+\r
+class RleInfoStack extends NyARObjectStack<NyARRleLabelFragmentInfo>\r
+{      \r
+       public RleInfoStack(int i_length) throws NyARException\r
+       {\r
+               super();\r
+               super.initInstance(i_length, NyARRleLabelFragmentInfo.class);\r
+               return;\r
+       }\r
+\r
+       protected NyARRleLabelFragmentInfo createElement()\r
+       {\r
+               return new NyARRleLabelFragmentInfo();\r
+       }\r
+}\r
+/**\r
+ * [strage class]\r
+ */\r
+\r
+\r
+class RleElement\r
+{\r
+       int l;\r
+       int r;\r
+       int fid;\r
+       public static RleElement[] createArray(int i_length)\r
+       {\r
+               RleElement[] ret = new RleElement[i_length];\r
+               for (int i = 0; i < i_length; i++) {\r
+                       ret[i] = new RleElement();\r
+               }\r
+               return ret;\r
+       }\r
+}\r
+\r
+\r
+/**\r
+ * ラべリングクラスです。入力画像をラべリングして、そのエントリポイントと情報を、ハンドラ関数を介して返します。\r
+ * \r
+ *\r
+ */\r
+public abstract class NyARLabeling_Rle\r
+{\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 RleInfoStack _rlestack;\r
+       private RleElement[] _rle1;\r
+       private RleElement[] _rle2;\r
+       private int _max_area;\r
+       private int _min_area;\r
+       /**\r
+        * 処理対象のラスタサイズ\r
+        */\r
+       protected NyARIntSize _raster_size=new NyARIntSize();\r
+\r
+       public NyARLabeling_Rle(int i_width,int i_height) throws NyARException\r
+       {\r
+               this._raster_size.setValue(i_width,i_height);\r
+               this._rlestack=new RleInfoStack(i_width*i_height*2048/(320*240)+32);\r
+               this._rle1 = RleElement.createArray(i_width/2+1);\r
+               this._rle2 = RleElement.createArray(i_width/2+1);\r
+               this._max_area=AR_AREA_MAX;\r
+               this._min_area=AR_AREA_MIN;\r
+\r
+               return;\r
+       }\r
+       /**\r
+        * 対象サイズ\r
+        * @param i_max\r
+        * @param i_min\r
+        */\r
+       public void setAreaRange(int i_max,int i_min)\r
+       {\r
+               assert(i_min>0 && i_max>i_min);\r
+               this._max_area=i_max;\r
+               this._min_area=i_min;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * i_bin_bufのgsイメージをREL圧縮する。\r
+        * @param i_bin_buf\r
+        * @param i_st\r
+        * @param i_len\r
+        * @param i_out\r
+        * @param i_th\r
+        * BINラスタのときは0,GSラスタの時は閾値を指定する。\r
+        * この関数は、閾値を暗点と認識します。\r
+        * 暗点<=th<明点\r
+        * @return\r
+        */\r
+       private final int toRel(int[] i_bin_buf, int i_st, int i_len, RleElement[] i_out,int i_th)\r
+       {\r
+               int current = 0;\r
+               int r = -1;\r
+               // 行確定開始\r
+               int x = i_st;\r
+               final int right_edge = i_st + i_len - 1;\r
+               while (x < right_edge) {\r
+                       // 暗点(0)スキャン\r
+                       if (i_bin_buf[x] > i_th) {\r
+                               x++;//明点\r
+                               continue;\r
+                       }\r
+                       // 暗点発見→暗点長を調べる\r
+                       r = (x - i_st);\r
+                       i_out[current].l = r;\r
+                       r++;// 暗点+1\r
+                       x++;\r
+                       while (x < right_edge) {\r
+                               if (i_bin_buf[x] > i_th) {\r
+                                       // 明点(1)→暗点(0)配列終了>登録\r
+                                       i_out[current].r = r;\r
+                                       current++;\r
+                                       x++;// 次点の確認。\r
+                                       r = -1;// 右端の位置を0に。\r
+                                       break;\r
+                               } else {\r
+                                       // 暗点(0)長追加\r
+                                       r++;\r
+                                       x++;\r
+                               }\r
+                       }\r
+               }\r
+               // 最後の1点だけ判定方法が少し違うの。\r
+               if (i_bin_buf[x] > i_th) {\r
+                       // 明点→rカウント中なら暗点配列終了>登録\r
+                       if (r >= 0) {\r
+                               i_out[current].r = r;\r
+                               current++;\r
+                       }\r
+               } else {\r
+                       // 暗点→カウント中でなければl1で追加\r
+                       if (r >= 0) {\r
+                               i_out[current].r = (r + 1);\r
+                       } else {\r
+                               // 最後の1点の場合\r
+                               i_out[current].l = (i_len - 1);\r
+                               i_out[current].r = (i_len);\r
+                       }\r
+                       current++;\r
+               }\r
+               // 行確定\r
+               return current;\r
+       }\r
+\r
+       private final boolean addFragment(RleElement i_rel_img, int i_nof, int i_row_index,RleInfoStack o_stack) throws NyARException\r
+       {\r
+               int l=i_rel_img.l;\r
+               final int len=i_rel_img.r - l;\r
+               i_rel_img.fid = i_nof;// REL毎の固有ID\r
+               NyARRleLabelFragmentInfo v = o_stack.prePush();\r
+               if(o_stack==null){\r
+                       System.err.println("addFragment force recover!");\r
+                       return false;\r
+               }\r
+               v.entry_x = l;\r
+               v.area =len;\r
+               v.clip_l=l;\r
+               v.clip_r=i_rel_img.r-1;\r
+               v.clip_t=i_row_index;\r
+               v.clip_b=i_row_index;\r
+               v.pos_x=(len*(2*l+(len-1)))/2;\r
+               v.pos_y=i_row_index*len;\r
+\r
+               return true;\r
+       }\r
+       /**\r
+        * BINラスタをラベリングします。\r
+        * @param i_bin_raster\r
+        * @param o_stack\r
+        * 結果を蓄積するスタックオブジェクトを指定します。\r
+        * 関数は、このオブジェクトに結果を追記します。\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public void labeling(NyARBinRaster i_bin_raster) throws NyARException\r
+       {\r
+               assert(i_bin_raster.isEqualBufferType(NyARBufferType.INT1D_BIN_8));\r
+               NyARIntSize size=i_bin_raster.getSize();\r
+               this.imple_labeling(i_bin_raster,0,0,0,size.w,size.h);\r
+       }\r
+       public void labeling(NyARBinRaster i_bin_raster,NyARIntRect i_area) throws NyARException\r
+       {\r
+               assert(i_bin_raster.isEqualBufferType(NyARBufferType.INT1D_BIN_8));\r
+               this.imple_labeling(i_bin_raster,0,i_area.x,i_area.y,i_area.w,i_area.h);\r
+       }\r
+       /**\r
+        * GSラスタの2値ラべリングを実行します。\r
+        * @param i_gs_raster\r
+        * @param i_th\r
+        * 二値化の敷居値を指定します。\r
+        * @param o_stack\r
+        * 結果を蓄積するスタックオブジェクトを指定します。\r
+        * 関数は、このオブジェクトに結果を追記します。\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public void labeling(NyARGrayscaleRaster i_gs_raster,int i_th) throws NyARException\r
+       {\r
+               assert(i_gs_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+               NyARIntSize size=i_gs_raster.getSize();\r
+               this.imple_labeling(i_gs_raster,i_th,0,0,size.w,size.h);\r
+       }\r
+       /**\r
+        * 範囲付きでGSラスタの2値ラべリングを実行します。\r
+        * @param i_gs_raster\r
+        * @param i_area\r
+        * @param i_th\r
+        * @param o_stack\r
+        * 結果を蓄積するスタックオブジェクトを指定します。\r
+        * 関数は、このオブジェクトに結果を追記します。\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public void labeling(NyARGrayscaleRaster i_gs_raster,NyARIntRect i_area,int i_th) throws NyARException\r
+       {\r
+               assert(i_gs_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+               this.imple_labeling(i_gs_raster,i_th,i_area.x,i_area.y,i_area.w,i_area.h);\r
+       }\r
+       private void imple_labeling(INyARRaster i_raster,int i_th,int i_left,int i_top,int i_width, int i_height) throws NyARException\r
+       {\r
+               //ラスタのサイズを確認\r
+               assert(i_raster.getSize().isEqualSize(this._raster_size));\r
+               \r
+               RleElement[] rle_prev = this._rle1;\r
+               RleElement[] rle_current = this._rle2;\r
+               // リセット処理\r
+               final RleInfoStack rlestack=this._rlestack;\r
+               rlestack.clear();\r
+\r
+               //\r
+               int len_prev = 0;\r
+               int len_current = 0;\r
+               final int bottom=i_top+i_height;\r
+               final int row_stride=this._raster_size.w;\r
+               int[] in_buf = (int[]) i_raster.getBuffer();\r
+\r
+               int id_max = 0;\r
+               int label_count=0;\r
+               int rle_top_index=i_left+row_stride*i_top;\r
+               // 初段登録\r
+\r
+               len_prev = toRel(in_buf, rle_top_index, i_width, rle_prev,i_th);\r
+               for (int i = 0; i < len_prev; i++) {\r
+                       // フラグメントID=フラグメント初期値、POS=Y値、RELインデクス=行\r
+                       if(addFragment(rle_prev[i], id_max, i_top,rlestack)){\r
+                               id_max++;\r
+                               // nofの最大値チェック\r
+                               label_count++;\r
+                       }\r
+               }\r
+               NyARRleLabelFragmentInfo[] f_array = rlestack.getArray();\r
+               // 次段結合\r
+               for (int y = i_top + 1; y < bottom; y++) {\r
+                       // カレント行の読込\r
+                       rle_top_index+=row_stride;\r
+                       len_current = toRel(in_buf,rle_top_index, i_width, rle_current,i_th);\r
+                       int index_prev = 0;\r
+\r
+                       SCAN_CUR: for (int i = 0; i < len_current; i++) {\r
+                               // index_prev,len_prevの位置を調整する\r
+                               int id = -1;\r
+                               // チェックすべきprevがあれば確認\r
+                               SCAN_PREV: while (index_prev < len_prev) {\r
+                                       if (rle_current[i].l - rle_prev[index_prev].r > 0) {// 0なら8方位ラベリング\r
+                                               // prevがcurの左方にある→次のフラグメントを探索\r
+                                               index_prev++;\r
+                                               continue;\r
+                                       } else if (rle_prev[index_prev].l - rle_current[i].r > 0) {// 0なら8方位ラベリングになる\r
+                                               // prevがcur右方にある→独立フラグメント\r
+                                               if(addFragment(rle_current[i], id_max, y,rlestack)){\r
+                                                       id_max++;\r
+                                                       label_count++;\r
+                                               }\r
+                                               // 次のindexをしらべる\r
+                                               continue SCAN_CUR;\r
+                                       }\r
+                                       id=rle_prev[index_prev].fid;//ルートフラグメントid\r
+                                       NyARRleLabelFragmentInfo id_ptr = f_array[id];\r
+                                       //結合対象(初回)->prevのIDをコピーして、ルートフラグメントの情報を更新\r
+                                       rle_current[i].fid = id;//フラグメントIDを保存\r
+                                       //\r
+                                       final int l= rle_current[i].l;\r
+                                       final int r= rle_current[i].r;\r
+                                       final int len=r-l;\r
+                                       //結合先フラグメントの情報を更新する。\r
+                                       id_ptr.area += len;\r
+                                       //tとentry_xは、結合先のを使うので更新しない。\r
+                                       id_ptr.clip_l=l<id_ptr.clip_l?l:id_ptr.clip_l;\r
+                                       id_ptr.clip_r=r>id_ptr.clip_r?r-1:id_ptr.clip_r;\r
+                                       id_ptr.clip_b=y;\r
+                                       id_ptr.pos_x+=(len*(2*l+(len-1)))/2;\r
+                                       id_ptr.pos_y+=y*len;\r
+                                       //多重結合の確認(2個目以降)\r
+                                       index_prev++;\r
+                                       while (index_prev < len_prev) {\r
+                                               if (rle_current[i].l - rle_prev[index_prev].r > 0) {// 0なら8方位ラベリング\r
+                                                       // prevがcurの左方にある→prevはcurに連結していない。\r
+                                                       break SCAN_PREV;\r
+                                               } else if (rle_prev[index_prev].l - rle_current[i].r > 0) {// 0なら8方位ラベリングになる\r
+                                                       // prevがcurの右方にある→prevはcurに連結していない。\r
+                                                       index_prev--;\r
+                                                       continue SCAN_CUR;\r
+                                               }\r
+                                               // prevとcurは連結している→ルートフラグメントの統合\r
+                                               \r
+                                               //結合するルートフラグメントを取得\r
+                                               final int prev_id =rle_prev[index_prev].fid;\r
+                                               NyARRleLabelFragmentInfo prev_ptr = f_array[prev_id];\r
+                                               if (id != prev_id){\r
+                                                       label_count--;\r
+                                                       //prevとcurrentのフラグメントidを書き換える。\r
+                                                       for(int i2=index_prev;i2<len_prev;i2++){\r
+                                                               //prevは現在のidから最後まで\r
+                                                               if(rle_prev[i2].fid==prev_id){\r
+                                                                       rle_prev[i2].fid=id;\r
+                                                               }\r
+                                                       }\r
+                                                       for(int i2=0;i2<i;i2++){\r
+                                                               //currentは0から現在-1まで\r
+                                                               if(rle_current[i2].fid==prev_id){\r
+                                                                       rle_current[i2].fid=id;\r
+                                                               }\r
+                                                       }\r
+                                                       \r
+                                                       //現在のルートフラグメントに情報を集約\r
+                                                       id_ptr.area +=prev_ptr.area;\r
+                                                       id_ptr.pos_x+=prev_ptr.pos_x;\r
+                                                       id_ptr.pos_y+=prev_ptr.pos_y;\r
+                                                       //tとentry_xの決定\r
+                                                       if (id_ptr.clip_t > prev_ptr.clip_t) {\r
+                                                               // 現在の方が下にある。\r
+                                                               id_ptr.clip_t = prev_ptr.clip_t;\r
+                                                               id_ptr.entry_x = prev_ptr.entry_x;\r
+                                                       }else if (id_ptr.clip_t < prev_ptr.clip_t) {\r
+                                                               // 現在の方が上にある。prevにフィードバック\r
+                                                       } else {\r
+                                                               // 水平方向で小さい方がエントリポイント。\r
+                                                               if (id_ptr.entry_x > prev_ptr.entry_x) {\r
+                                                                       id_ptr.entry_x = prev_ptr.entry_x;\r
+                                                               }else{\r
+                                                               }\r
+                                                       }\r
+                                                       //lの決定\r
+                                                       if (id_ptr.clip_l > prev_ptr.clip_l) {\r
+                                                               id_ptr.clip_l=prev_ptr.clip_l;\r
+                                                       }else{\r
+                                                       }\r
+                                                       //rの決定\r
+                                                       if (id_ptr.clip_r < prev_ptr.clip_r) {\r
+                                                               id_ptr.clip_r=prev_ptr.clip_r;\r
+                                                       }else{\r
+                                                       }\r
+                                                       //bの決定\r
+\r
+                                                       //結合済のルートフラグメントを無効化する。\r
+                                                       prev_ptr.area=0;\r
+                                               }\r
+\r
+\r
+                                               index_prev++;\r
+                                       }\r
+                                       index_prev--;\r
+                                       break;\r
+                               }\r
+                               // curにidが割り当てられたかを確認\r
+                               // 右端独立フラグメントを追加\r
+                               if (id < 0){\r
+                                       if(addFragment(rle_current[i], id_max, y,rlestack)){\r
+                                               id_max++;\r
+                                               label_count++;\r
+                                       }\r
+                               }\r
+                       }\r
+                       // prevとrelの交換\r
+                       RleElement[] tmp = rle_prev;\r
+                       rle_prev = rle_current;\r
+                       len_prev = len_current;\r
+                       rle_current = tmp;\r
+               }\r
+               //対象のラベルだけを追記\r
+               final int max=this._max_area;\r
+               final int min=this._min_area;\r
+               for(int i=id_max-1;i>=0;i--){\r
+                       final NyARRleLabelFragmentInfo src_info=f_array[i];\r
+                       final int area=src_info.area;\r
+                       if(area<min || area>max){//対象外のエリア0のもminではじく\r
+                               continue;\r
+                       }\r
+                       //値を相対位置に補正\r
+                       src_info.clip_l+=i_left;\r
+                       src_info.clip_r+=i_left;\r
+                       src_info.entry_x+=i_left;\r
+                       src_info.pos_x/=area;\r
+                       src_info.pos_y/=area;\r
+                       //コールバック関数コール\r
+                       this.onLabelFound(src_info);\r
+               }\r
+       }\r
+       /**\r
+        * ハンドラ関数です。継承先クラスでオーバライドしてください。\r
+        * i_labelのインスタンスは、次のラべリング実行まで保証されていますが、将来にわたり保証されないかもしれません。(恐らく保証されますが)\r
+        * コールバック関数から参照を使用する場合は、互換性を確認するために、念のため、assertで_af_label_array_safe_referenceフラグをチェックしてください。\r
+        * @param i_label\r
+        */\r
+       protected abstract void onLabelFound(NyARRleLabelFragmentInfo i_ref_label) throws NyARException;\r
+       \r
+       /**\r
+        * クラスの仕様確認フラグです。ラベル配列の参照アクセスが可能かを返します。\r
+        * \r
+        */\r
+       public final static boolean _sf_label_array_safe_reference=true;\r
+}\r
+\r
+\r
+\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARRleLabelFragmentInfo.java b/lib/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARRleLabelFragmentInfo.java
new file mode 100644 (file)
index 0000000..4bd3a8a
--- /dev/null
@@ -0,0 +1,32 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.rlelabeling;\r
+\r
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelInfo;\r
+\r
+public class NyARRleLabelFragmentInfo extends NyARLabelInfo\r
+{\r
+       public int entry_x;  // フラグメントラベルの位置\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARRleLabelFragmentInfoPtrStack.java b/lib/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARRleLabelFragmentInfoPtrStack.java
new file mode 100644 (file)
index 0000000..6a2f9ce
--- /dev/null
@@ -0,0 +1,70 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.rlelabeling;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.stack.NyARPointerStack;\r
+\r
+\r
+public class NyARRleLabelFragmentInfoPtrStack  extends NyARPointerStack<NyARRleLabelFragmentInfo>\r
+{\r
+       public NyARRleLabelFragmentInfoPtrStack(int i_length) throws NyARException\r
+       {\r
+               this.initInstance(i_length, NyARRleLabelFragmentInfo.class);\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * エリアの大きい順にラベルをソートします。\r
+        */\r
+       final public void sortByArea()\r
+       {\r
+               int len=this._length;\r
+               if(len<1){\r
+                       return;\r
+               }\r
+               int h = len *13/10;\r
+               NyARRleLabelFragmentInfo[] item=this._items;\r
+               for(;;){\r
+                   int swaps = 0;\r
+                   for (int i = 0; i + h < len; i++) {\r
+                       if (item[i + h].area > item[i].area) {\r
+                           final NyARRleLabelFragmentInfo temp = item[i + h];\r
+                           item[i + h] = item[i];\r
+                           item[i] = temp;\r
+                           swaps++;\r
+                       }\r
+                   }\r
+                   if (h == 1) {\r
+                       if (swaps == 0){\r
+                               break;\r
+                       }\r
+                   }else{\r
+                       h=h*10/13;\r
+                   }\r
+               }               \r
+       }       \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/match/INyARMatchPatt.java b/lib/src/jp/nyatla/nyartoolkit/core/match/INyARMatchPatt.java
new file mode 100644 (file)
index 0000000..1684f54
--- /dev/null
@@ -0,0 +1,41 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+\r
+/**\r
+ * ARCodeとINyARColorPattの間で一致計算をするインタフェイスです。\r
+ */\r
+public interface INyARMatchPatt\r
+{\r
+       public void setARCode(NyARCode i_code);\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPattDeviationBlackWhiteData.java b/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPattDeviationBlackWhiteData.java
new file mode 100644 (file)
index 0000000..65cf3c1
--- /dev/null
@@ -0,0 +1,99 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+\r
+/**\r
+ * INyARMatchPattのColor差分ラスタを格納するクラスです。\r
+ *\r
+ */\r
+public class NyARMatchPattDeviationBlackWhiteData\r
+{\r
+       private int[] _data;\r
+       private double _pow;\r
+       //\r
+       private int _number_of_pixels;\r
+       public int[] refData()\r
+       {\r
+               return this._data;\r
+       }\r
+       public double getPow()\r
+       {\r
+               return this._pow;\r
+       }\r
+                         \r
+       public NyARMatchPattDeviationBlackWhiteData(int i_width,int i_height)\r
+       {\r
+               this._number_of_pixels=i_height*i_width;\r
+               this._data=new int[this._number_of_pixels];\r
+               return;\r
+       }\r
+       /**\r
+        * XRGB[width*height]の配列から、パターンデータを構築。\r
+        * @param i_buffer\r
+        */\r
+       public void setRaster(INyARRaster i_raster)\r
+       {\r
+               //i_buffer[XRGB]→差分[BW]変換                     \r
+               int i;\r
+               int ave;//<PV/>\r
+               int rgb;//<PV/>\r
+               final int[] linput=this._data;//<PV/>\r
+               final int[] buf=(int[])i_raster.getBuffer();\r
+\r
+               // input配列のサイズとwhも更新// input=new int[height][width][3];\r
+               final int number_of_pixels=this._number_of_pixels;\r
+\r
+               //<平均値計算(FORの1/8展開)/>\r
+               ave = 0;\r
+               for(i=number_of_pixels-1;i>=0;i--){\r
+                       rgb = buf[i];\r
+                       ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);\r
+               }\r
+               ave=(number_of_pixels*255*3-ave)/(3*number_of_pixels);\r
+               //\r
+               int sum = 0,w_sum;\r
+               \r
+               //<差分値計算/>\r
+               for (i = number_of_pixels-1; i >= 0;i--) {\r
+                       rgb = buf[i];\r
+                       w_sum =((255*3-(rgb & 0xff)-((rgb >> 8) & 0xff)-((rgb >> 16) & 0xff))/3)-ave;\r
+                       linput[i] = w_sum;\r
+                       sum += w_sum * w_sum;\r
+               }\r
+               final double p=Math.sqrt((double) sum);\r
+               this._pow=p!=0.0?p:0.0000001;\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPattDeviationColorData.java b/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPattDeviationColorData.java
new file mode 100644 (file)
index 0000000..4c5995b
--- /dev/null
@@ -0,0 +1,297 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * INyARMatchPattのRGBColor差分データを格納するクラスです。\r
+ *\r
+ */\r
+public class NyARMatchPattDeviationColorData\r
+{\r
+       private int[] _data;\r
+       private double _pow;\r
+       private NyARIntSize _size;\r
+       //\r
+       private int _optimize_for_mod;\r
+       public int[] refData()\r
+       {\r
+               return this._data;\r
+       }\r
+       public double getPow()\r
+       {\r
+               return this._pow;\r
+       }\r
+                         \r
+       public NyARMatchPattDeviationColorData(int i_width,int i_height)\r
+       {\r
+               this._size=new NyARIntSize(i_width,i_height);\r
+               int number_of_pix=this._size.w*this._size.h;\r
+               this._data=new int[number_of_pix*3];\r
+               this._optimize_for_mod=number_of_pix-(number_of_pix%8); \r
+               return;\r
+       }\r
+\r
+       \r
+       /**\r
+        * NyARRasterからパターンデータをセットします。\r
+        * この関数は、データを元に所有するデータ領域を更新します。\r
+        * @param i_buffer\r
+        * @throws NyARException \r
+        */\r
+       public void setRaster(INyARRgbRaster i_raster) throws NyARException\r
+       {\r
+               assert(i_raster.getSize().isEqualSize(this._size));\r
+               switch(i_raster.getBufferType())\r
+               {\r
+               case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                       this._pow=setRaster_INT1D_X8R8G8B8_32((int[])i_raster.getBuffer(),this._size.w*this._size.h,this._optimize_for_mod,this._data);\r
+                       break;\r
+               default:\r
+                       this._pow=setRaster_ANY(i_raster.getRgbPixelReader(),this._size,this._size.w*this._size.h,this._data);\r
+                       break;\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * 回転方向を指定してラスタをセットします。\r
+        * @param i_reader\r
+        * @param i_direction\r
+        * 右上の位置です。0=1象限、1=2象限、、2=3象限、、3=4象限の位置に対応します。\r
+        * @throws NyARException\r
+        */\r
+       public final void setRaster(INyARRgbRaster i_raster,int i_direction) throws NyARException\r
+       {\r
+               int width=this._size.w;\r
+               int height=this._size.h;\r
+               int i_number_of_pix=width*height;\r
+               INyARRgbPixelReader reader=i_raster.getRgbPixelReader();\r
+               int[] rgb=new int[3];\r
+               int[] dout=this._data;\r
+               int ave;//<PV/>\r
+               //<平均値計算>\r
+               ave = 0;\r
+               for(int y=height-1;y>=0;y--){\r
+                       for(int x=width-1;x>=0;x--){\r
+                               reader.getPixel(x,y,rgb);\r
+                               ave += rgb[0]+rgb[1]+rgb[2];\r
+                       }\r
+               }\r
+               //<平均値計算>\r
+               ave=i_number_of_pix*255*3-ave;\r
+               ave =255-(ave/ (i_number_of_pix * 3));//(255-R)-ave を分解するための事前計算\r
+\r
+               int sum = 0,w_sum;\r
+               int input_ptr=i_number_of_pix*3-1;\r
+               switch(i_direction)\r
+               {\r
+               case 0:\r
+                       for(int y=height-1;y>=0;y--){\r
+                               for(int x=width-1;x>=0;x--){\r
+                                       reader.getPixel(x,y,rgb);\r
+                                       w_sum = (ave - rgb[2]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                                       w_sum = (ave - rgb[1]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                                       w_sum = (ave - rgb[0]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                               }\r
+                       }\r
+                       break;\r
+               case 1:\r
+                       for(int x=0;x<width;x++){\r
+                               for(int y=height-1;y>=0;y--){\r
+                                       reader.getPixel(x,y,rgb);\r
+                                       w_sum = (ave - rgb[2]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                                       w_sum = (ave - rgb[1]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                                       w_sum = (ave - rgb[0]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                               }\r
+                       }\r
+                       break;\r
+               case 2:\r
+                       for(int y=0;y<height;y++){\r
+                               for(int x=0;x<width;x++){\r
+                                       reader.getPixel(x,y,rgb);\r
+                                       w_sum = (ave - rgb[2]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                                       w_sum = (ave - rgb[1]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                                       w_sum = (ave - rgb[0]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                               }\r
+                       }\r
+                       break;\r
+               case 3:\r
+                       for(int x=width-1;x>=0;x--){\r
+                               for(int y=0;y<height;y++){\r
+                                       reader.getPixel(x,y,rgb);\r
+                                       w_sum = (ave - rgb[2]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                                       w_sum = (ave - rgb[1]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                                       w_sum = (ave - rgb[0]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                               }\r
+                       }\r
+                       break;\r
+                       \r
+               }\r
+               //<差分値計算>\r
+               //<差分値計算(FORの1/8展開)/>\r
+               final double p=Math.sqrt((double) sum);\r
+               this._pow=(p!=0.0?p:0.0000001);\r
+       }       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       /**\r
+        * INT1D_X8R8G8B8_32形式の入力ドライバ。\r
+        * @param i_buf\r
+        * @param i_number_of_pix\r
+        * @param i_for_mod\r
+        * @param o_out\r
+        * pow値\r
+        * @return\r
+        */\r
+       private static final double setRaster_INT1D_X8R8G8B8_32(int[] i_buf,int i_number_of_pix,int i_for_mod,int[] o_out)\r
+       {\r
+               //i_buffer[XRGB]→差分[R,G,B]変換                  \r
+               int i;\r
+               int ave;//<PV/>\r
+               int rgb;//<PV/>\r
+               //<平均値計算(FORの1/8展開)>\r
+               ave = 0;\r
+               for(i=i_number_of_pix-1;i>=i_for_mod;i--){\r
+                       rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);\r
+               }\r
+               for (;i>=0;) {\r
+                       rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+                       rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+                       rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+                       rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+                       rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+                       rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+                       rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+                       rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+               }\r
+               //<平均値計算(FORの1/8展開)/>\r
+               ave=i_number_of_pix*255*3-ave;\r
+               ave =255-(ave/ (i_number_of_pix * 3));//(255-R)-ave を分解するための事前計算\r
+\r
+               int sum = 0,w_sum;\r
+               int input_ptr=i_number_of_pix*3-1;\r
+               //<差分値計算(FORの1/8展開)>\r
+               for (i = i_number_of_pix-1; i >= i_for_mod;i--) {\r
+                       rgb = i_buf[i];\r
+                       w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                       w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                       w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+               }\r
+               for (; i >=0;) {\r
+                       rgb = i_buf[i];i--;\r
+                       w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                       w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                       w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                       rgb = i_buf[i];i--;\r
+                       w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                       w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                       w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                       rgb = i_buf[i];i--;\r
+                       w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                       w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                       w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                       rgb = i_buf[i];i--;\r
+                       w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                       w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                       w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                       rgb = i_buf[i];i--;\r
+                       w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                       w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                       w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                       rgb = i_buf[i];i--;\r
+                       w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                       w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                       w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                       rgb = i_buf[i];i--;\r
+                       w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                       w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                       w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                       rgb = i_buf[i];i--;\r
+                       w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                       w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                       w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+               }\r
+               //<差分値計算(FORの1/8展開)/>\r
+               final double p=Math.sqrt((double) sum);\r
+               return p!=0.0?p:0.0000001;\r
+       }\r
+       /**\r
+        * ANY形式の入力ドライバ。\r
+        * @param i_buf\r
+        * @param i_number_of_pix\r
+        * @param i_for_mod\r
+        * @param o_out\r
+        * pow値\r
+        * @return\r
+        * @throws NyARException \r
+        */\r
+       private static final double setRaster_ANY(INyARRgbPixelReader i_reader,NyARIntSize i_size,int i_number_of_pix,int[] o_out) throws NyARException\r
+       {\r
+               int width=i_size.w;\r
+               int[] rgb=new int[3];\r
+               int ave;//<PV/>\r
+               //<平均値計算>\r
+               ave = 0;\r
+               for(int y=i_size.h-1;y>=0;y--){\r
+                       for(int x=width-1;x>=0;x--){\r
+                               i_reader.getPixel(x,y,rgb);\r
+                               ave += rgb[0]+rgb[1]+rgb[2];\r
+                       }\r
+               }\r
+               //<平均値計算>\r
+               ave=i_number_of_pix*255*3-ave;\r
+               ave =255-(ave/ (i_number_of_pix * 3));//(255-R)-ave を分解するための事前計算\r
+\r
+               int sum = 0,w_sum;\r
+               int input_ptr=i_number_of_pix*3-1;\r
+               //<差分値計算>\r
+               for(int y=i_size.h-1;y>=0;y--){\r
+                       for(int x=width-1;x>=0;x--){\r
+                               i_reader.getPixel(x,y,rgb);\r
+                               w_sum = (ave - rgb[2]) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+                               w_sum = (ave - rgb[1]) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+                               w_sum = (ave - rgb[0]) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+                       }\r
+               }\r
+               //<差分値計算(FORの1/8展開)/>\r
+               final double p=Math.sqrt((double) sum);\r
+               return p!=0.0?p:0.0000001;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPattResult.java b/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPattResult.java
new file mode 100644 (file)
index 0000000..4c9064a
--- /dev/null
@@ -0,0 +1,44 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+\r
+\r
+/**\r
+ * [[Strage class]]\r
+ *\r
+ */\r
+public class NyARMatchPattResult\r
+{\r
+       public static final int DIRECTION_UNKNOWN=-1;\r
+       public double confidence;\r
+       public int direction;\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPatt_BlackWhite.java b/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPatt_BlackWhite.java
new file mode 100644 (file)
index 0000000..6b38912
--- /dev/null
@@ -0,0 +1,102 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.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
+public class NyARMatchPatt_BlackWhite implements INyARMatchPatt\r
+{\r
+       protected NyARCode _code_patt;  \r
+       protected int _pixels;\r
+       \r
+       public NyARMatchPatt_BlackWhite(int i_width, int i_height)\r
+       {\r
+               //最適化定数の計算\r
+               this._pixels=i_height*i_width;\r
+               return;\r
+       }\r
+       public NyARMatchPatt_BlackWhite(NyARCode i_code_ref)\r
+       {\r
+               //最適化定数の計算\r
+               this._pixels=i_code_ref.getWidth()*i_code_ref.getHeight();\r
+               this._code_patt=i_code_ref;\r
+               return;\r
+       }       \r
+       /**\r
+        * 比較対象のARCodeをセットします。\r
+        * @throws NyARException\r
+        */\r
+       public void setARCode(NyARCode i_code_ref)\r
+       {\r
+               this._code_patt=i_code_ref;\r
+               return;\r
+       }\r
+       /**\r
+        * 現在セットされているコードとパターンを比較して、結果値o_resultを更新します。\r
+        * 比較部分はFor文を16倍展開してあります。\r
+        */\r
+       public boolean evaluate(NyARMatchPattDeviationBlackWhiteData i_patt,NyARMatchPattResult o_result) throws NyARException\r
+       {\r
+               assert this._code_patt!=null;\r
+\r
+               final int[] linput = i_patt.refData();\r
+               int sum;\r
+               double max = 0.0;\r
+               int res = NyARMatchPattResult.DIRECTION_UNKNOWN;\r
+               \r
+\r
+               for (int j = 0; j < 4; j++) {\r
+                       //合計値初期化\r
+                       sum=0;\r
+                       final NyARMatchPattDeviationBlackWhiteData code_patt=this._code_patt.getBlackWhiteData(j);\r
+                       final int[] pat_j = code_patt.refData();\r
+                       //<全画素について、比較(FORの1/16展開)/>\r
+                       int i;\r
+                       for(i=this._pixels-1;i>=0;i--){\r
+                               sum += linput[i] * pat_j[i];\r
+                       }\r
+                       //0.7776737688877927がでればOK\r
+                       final double sum2 = sum / code_patt.getPow() / i_patt.getPow();// sum2 = sum / patpow[k][j]/ datapow;\r
+                       if (sum2 > max) {\r
+                               max = sum2;\r
+                               res = j;\r
+                       }\r
+               }\r
+               o_result.direction = res;\r
+               o_result.confidence= max;\r
+               return true;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPatt_Color_WITHOUT_PCA.java b/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPatt_Color_WITHOUT_PCA.java
new file mode 100644 (file)
index 0000000..19b8a9d
--- /dev/null
@@ -0,0 +1,123 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.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
+public class NyARMatchPatt_Color_WITHOUT_PCA implements INyARMatchPatt\r
+{\r
+       protected NyARCode _code_patt;\r
+\r
+       protected int _optimize_for_mod;\r
+       protected int _rgbpixels;\r
+       public NyARMatchPatt_Color_WITHOUT_PCA(NyARCode i_code_ref)\r
+       {\r
+               int w=i_code_ref.getWidth();\r
+               int h=i_code_ref.getHeight();\r
+               //最適化定数の計算\r
+               this._rgbpixels=w*h*3;\r
+               this._optimize_for_mod=this._rgbpixels-(this._rgbpixels%16);\r
+               this.setARCode(i_code_ref);\r
+               return;\r
+       }\r
+       public NyARMatchPatt_Color_WITHOUT_PCA(int i_width, int i_height)\r
+       {\r
+               //最適化定数の計算\r
+               this._rgbpixels=i_height*i_width*3;\r
+               this._optimize_for_mod=this._rgbpixels-(this._rgbpixels%16);            \r
+               return;\r
+       }\r
+       /**\r
+        * 比較対象のARCodeをセットします。\r
+        * @throws NyARException\r
+        */\r
+       public void setARCode(NyARCode i_code_ref)\r
+       {\r
+               this._code_patt=i_code_ref;\r
+               return;\r
+       }\r
+       /**\r
+        * 現在セットされているARコードとi_pattを比較します。\r
+        */\r
+       public boolean evaluate(NyARMatchPattDeviationColorData i_patt,NyARMatchPattResult o_result) throws NyARException\r
+       {\r
+               assert this._code_patt!=null;\r
+               //\r
+               final int[] linput = i_patt.refData();\r
+               int sum;\r
+               double max = Double.MIN_VALUE;\r
+               int res = NyARMatchPattResult.DIRECTION_UNKNOWN;\r
+               final int for_mod=this._optimize_for_mod;\r
+               for (int j = 0; j < 4; j++) {\r
+                       //合計値初期化\r
+                       sum=0;\r
+                       final NyARMatchPattDeviationColorData code_patt=this._code_patt.getColorData(j);\r
+                       final int[] pat_j = code_patt.refData();\r
+                       //<全画素について、比較(FORの1/16展開)>\r
+                       int i;\r
+                       for(i=this._rgbpixels-1;i>=for_mod;i--){\r
+                               sum += linput[i] * pat_j[i];\r
+                       }\r
+                       for (;i>=0;) {\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                               sum += linput[i] * pat_j[i];i--;\r
+                       }\r
+                       //<全画素について、比較(FORの1/16展開)/>\r
+                       final double sum2 = sum / code_patt.getPow();// sum2 = sum / patpow[k][j]/ datapow;\r
+                       if (sum2 > max) {\r
+                               max = sum2;\r
+                               res = j;\r
+                       }\r
+               }\r
+               o_result.direction = res;\r
+               o_result.confidence= max/i_patt.getPow();\r
+               return true;            \r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPatt_Color_WITH_PCA.java b/lib/src/jp/nyatla/nyartoolkit/core/match/NyARMatchPatt_Color_WITH_PCA.java
new file mode 100644 (file)
index 0000000..73f6eb7
--- /dev/null
@@ -0,0 +1,101 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.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
+\r
+/**\r
+ * AR_TEMPLATE_MATCHING_COLORかつAR_MATCHING_WITH_PCAと同等のルールで マーカーを評価します。\r
+ * \r
+ */\r
+public class NyARMatchPatt_Color_WITH_PCA extends NyARMatchPatt_Color_WITHOUT_PCA\r
+{\r
+       private final int EVEC_MAX = 10;// #define EVEC_MAX 10\r
+\r
+       private int evec_dim;// static int evec_dim;\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
+\r
+\r
+       public NyARMatchPatt_Color_WITH_PCA(int i_width, int i_height)\r
+       {\r
+               super(i_width,i_height);\r
+               return;\r
+       }\r
+       public NyARMatchPatt_Color_WITH_PCA(NyARCode i_code_ref)\r
+       {\r
+               super(i_code_ref);\r
+               return;\r
+       }       \r
+       public boolean evaluate(NyARMatchPattDeviationColorData i_patt,NyARMatchPattResult o_result) throws NyARException\r
+       {\r
+               final int[] linput = i_patt.refData();\r
+               int sum;\r
+               double max = 0.0;\r
+               int res = NyARMatchPattResult.DIRECTION_UNKNOWN;\r
+/*             \r
+               NyARException.trap(\r
+                       "NyARMatchPatt_Color_WITH_PCA\n"+\r
+                       "この箇所の移植は不完全です!"+\r
+                       "ARToolKitの移植条件を完全に再現できていないため、evec,epatの計算が無視されています。"+\r
+                       "gen_evec(void)も含めて移植の必要があるはずですが、まだ未解析です。");\r
+*/             double[] invec = new double[EVEC_MAX];\r
+               for (int i = 0; i < this.evec_dim; i++) {\r
+                       invec[i] = 0.0;\r
+                       for(int j=0;j<this._rgbpixels;i++){\r
+                               invec[i] += this.evec[i][j] * linput[j];\r
+                       }\r
+                       invec[i] /= i_patt.getPow();\r
+               }\r
+               double min = 10000.0;\r
+               for (int j = 0; j < 4; j++) {\r
+                       double sum2 = 0;\r
+                       for (int i = 0; i < this.evec_dim; i++) {\r
+                               sum2 += (invec[i] - this.epat[j][i]) * (invec[i] - this.epat[j][i]);\r
+                       }\r
+                       if (sum2 < min) {\r
+                               min = sum2;\r
+                               res = j;\r
+                               // res2 = k;//kは常にインスタンスを刺すから、省略可能\r
+                       }\r
+               }\r
+               sum=0;\r
+               final int[] code_data=this._code_patt.getColorData(res).refData();\r
+               for (int i = 0; i < this._rgbpixels; i++) {// for(int\r
+                       sum += linput[i] * code_data[i];// sum +=input[i][i2][i3]*pat[res2][res][i][i2][i3];\r
+               }\r
+               max = sum /  this._code_patt.getColorData(res).getPow() / i_patt.getPow();\r
+               o_result.direction = res;\r
+               o_result.confidence = max;\r
+               return true;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/param/NyARCameraDistortionFactor.java b/lib/src/jp/nyatla/nyartoolkit/core/param/NyARCameraDistortionFactor.java
new file mode 100644 (file)
index 0000000..ba2d6da
--- /dev/null
@@ -0,0 +1,305 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * ARToolKitの樽型歪みパラメータを使う、歪み設定/解除クラスです。\r
+ * パラメータと理論については、以下の資料、11pageを参照。\r
+ * http://www.hitl.washington.edu/artoolkit/Papers/ART02-Tutorial.pdf\r
+ * \r
+ * このクラスでは、歪み矯正前の座標を観察座標系、歪み矯正後の座標を理想座標系とします。\r
+ * \r
+ * x=x(xi-x0),y=s(yi-y0)\r
+ * d^2=x^2+y^2\r
+ * p=(1-fd^2)\r
+ * xd=px+x0,yd=py+y0\r
+ */\r
+public class NyARCameraDistortionFactor\r
+{\r
+       \r
+       private static final int PD_LOOP = 3;\r
+       private double _f0;//x0\r
+       private double _f1;//y0\r
+       private double _f2;//100000000.0*f\r
+       private double _f3;//s\r
+       \r
+       \r
+       /**\r
+        * 参照元から値をコピーします。\r
+        * @param i_ref\r
+        */\r
+       public void copyFrom(NyARCameraDistortionFactor i_ref)\r
+       {\r
+               this._f0=i_ref._f0;\r
+               this._f1=i_ref._f1;\r
+               this._f2=i_ref._f2;\r
+               this._f3=i_ref._f3;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * 配列の値をファクタ値としてセットします。\r
+        * @param i_factor\r
+        * 4要素以上の配列\r
+        */\r
+       public void setValue(double[] i_factor)\r
+       {\r
+               this._f0=i_factor[0];\r
+               this._f1=i_factor[1];\r
+               this._f2=i_factor[2];\r
+               this._f3=i_factor[3];\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * ファクタ値を配列に返します。\r
+        * @param o_factor\r
+        */\r
+       public void getValue(double[] o_factor)\r
+       {\r
+               o_factor[0]=this._f0;\r
+               o_factor[1]=this._f1;\r
+               o_factor[2]=this._f2;\r
+               o_factor[3]=this._f3;\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * 歪みパラメータのスケールを変更します。\r
+        * @param i_scale\r
+        */\r
+       public void changeScale(double i_scale)\r
+       {\r
+               this._f0=this._f0*i_scale;// newparam->dist_factor[0] =source->dist_factor[0] *scale;\r
+               this._f1=this._f1*i_scale;// newparam->dist_factor[1] =source->dist_factor[1] *scale;\r
+               this._f2=this._f2/ (i_scale * i_scale);// newparam->dist_factor[2]=source->dist_factor[2]/ (scale*scale);\r
+               //this.f3=this.f3;// newparam->dist_factor[3] =source->dist_factor[3];\r
+               return;\r
+       }\r
+       /*********\r
+        * override\r
+        *********/\r
+       \r
+       /**\r
+        * 理想座標から、観察座標系へ変換します。\r
+        * @param i_in\r
+        * @param o_out\r
+        */\r
+       public final void ideal2Observ(NyARDoublePoint2d i_in, NyARDoublePoint2d o_out)\r
+       {\r
+               final double x = (i_in.x - this._f0) * this._f3;\r
+               final double y = (i_in.y - this._f1) * this._f3;\r
+               if (x == 0.0 && y == 0.0) {\r
+                       o_out.x = this._f0;\r
+                       o_out.y = this._f1;\r
+               } else {\r
+                       final double d = 1.0 - this._f2 / 100000000.0 * (x * x + y * y);\r
+                       o_out.x = x * d + this._f0;\r
+                       o_out.y = y * d + this._f1;\r
+               }\r
+               return;\r
+       }\r
+       \r
+\r
+       /**\r
+        * 理想座標から、観察座標系へ変換します。\r
+        * @param i_in\r
+        * @param o_out\r
+        */\r
+       public final void ideal2Observ(NyARDoublePoint2d i_in, NyARIntPoint2d o_out)\r
+       {\r
+               this.ideal2Observ(i_in.x,i_in.y,o_out);\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * 理想座標から、観察座標系へ変換します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param o_out\r
+        */\r
+       public final void ideal2Observ(double i_x,double i_y, NyARIntPoint2d o_out)\r
+       {\r
+               final double x = (i_x - this._f0) * this._f3;\r
+               final double y = (i_y - this._f1) * this._f3;\r
+               if (x == 0.0 && y == 0.0) {\r
+                       o_out.x = (int)(this._f0);\r
+                       o_out.y = (int)(this._f1);\r
+               } else {\r
+                       final double d = 1.0 - this._f2 / 100000000.0 * (x * x + y * y);\r
+                       o_out.x = (int)(x * d + this._f0);\r
+                       o_out.y = (int)(y * d + this._f1);\r
+               }\r
+               return;\r
+       }\r
+       \r
+\r
+       /**\r
+        * 理想座標から、観察座標系へ変換します。\r
+        * @param i_in\r
+        * @param o_out\r
+        * @param i_size\r
+        */\r
+       public final void ideal2ObservBatch(NyARDoublePoint2d[] i_in, NyARDoublePoint2d[] o_out, int i_size)\r
+       {\r
+               double x, y;\r
+               final double d0 = this._f0;\r
+               final double d1 = this._f1;\r
+               final double d3 = this._f3;\r
+               final double d2_w = this._f2 / 100000000.0;\r
+               for (int i = 0; i < i_size; i++) {\r
+                       x = (i_in[i].x - d0) * d3;\r
+                       y = (i_in[i].y - d1) * d3;\r
+                       if (x == 0.0 && y == 0.0) {\r
+                               o_out[i].x = d0;\r
+                               o_out[i].y = d1;\r
+                       } else {\r
+                               final double d = 1.0 - d2_w * (x * x + y * y);\r
+                               o_out[i].x = x * d + d0;\r
+                               o_out[i].y = y * d + d1;\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * 複数の座標点について、観察座標から、理想座標系へ変換します。\r
+        * @param i_in\r
+        * @param o_out\r
+        * @param i_size\r
+        */\r
+       public final void ideal2ObservBatch(NyARDoublePoint2d[] i_in, NyARIntPoint2d[] o_out, int i_size)\r
+       {\r
+               double x, y;\r
+               final double d0 = this._f0;\r
+               final double d1 = this._f1;\r
+               final double d3 = this._f3;\r
+               final double d2_w = this._f2 / 100000000.0;\r
+               for (int i = 0; i < i_size; i++) {\r
+                       x = (i_in[i].x - d0) * d3;\r
+                       y = (i_in[i].y - d1) * d3;\r
+                       if (x == 0.0 && y == 0.0) {\r
+                               o_out[i].x = (int)d0;\r
+                               o_out[i].y = (int)d1;\r
+                       } else {\r
+                               final double d = 1.0 - d2_w * (x * x + y * y);\r
+                               o_out[i].x = (int)(x * d + d0);\r
+                               o_out[i].y = (int)(y * d + d1);\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * ARToolKitの観察座標から、理想座標系への変換です。\r
+        * 樽型歪みを解除します。\r
+        * @param ix\r
+        * @param iy\r
+        * @param o_point\r
+        */\r
+       public final void observ2Ideal(double ix, double iy, NyARDoublePoint2d o_point)\r
+       {\r
+               double z02, z0, p, q, z, px, py, opttmp_1;\r
+               final double d0 = this._f0;\r
+               final double d1 = this._f1;\r
+\r
+               px = ix - d0;\r
+               py = iy - d1;\r
+               p = this._f2 / 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
+               o_point.x = px / this._f3 + d0;\r
+               o_point.y = py / this._f3 + d1;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * {@link #observ2Ideal(double, double, NyARDoublePoint2d)}の出力型違い。o_veclinearのx,yフィールドに値を出力する。\r
+        * @param ix\r
+        * @param iy\r
+        * @param o_point\r
+        */\r
+       public void observ2Ideal(double ix, double iy, NyARVecLinear2d o_veclinear)\r
+       {\r
+               double z02, z0, p, q, z, px, py, opttmp_1;\r
+               final double d0 = this._f0;\r
+               final double d1 = this._f1;\r
+\r
+               px = ix - d0;\r
+               py = iy - d1;\r
+               p = this._f2 / 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
+               o_veclinear.x = px / this._f3 + d0;\r
+               o_veclinear.y = py / this._f3 + d1;\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/param/NyARFrustum.java b/lib/src/jp/nyatla/nyartoolkit/core/param/NyARFrustum.java
new file mode 100644 (file)
index 0000000..2194a95
--- /dev/null
@@ -0,0 +1,191 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix44;\r
+\r
+/**\r
+ * 視錐台と、これを使った演算関数を定義します。\r
+ * @author nyatla\r
+ *\r
+ */\r
+public class NyARFrustum\r
+{\r
+       /** frastum行列*/\r
+       protected NyARDoubleMatrix44 _frustum_rh=new NyARDoubleMatrix44();\r
+       /** frastum逆行列*/\r
+       protected NyARDoubleMatrix44 _inv_frustum_rh=new NyARDoubleMatrix44();  \r
+       protected NyARIntSize _screen_size=new NyARIntSize();\r
+       /**\r
+        * コンストラクタです。ARToolkitの射影変換行列から、インスタンスを作ります。\r
+        * @param i_projection\r
+        * @param i_width\r
+        * スクリーンサイズです。\r
+        * @param i_height\r
+        * スクリーンサイズです。\r
+        * @param i_near\r
+        * 近平面までの距離です。単位はmm\r
+        * @param i_far\r
+        * 遠平面までの距離です。単位はmm\r
+        */\r
+       public NyARFrustum(NyARPerspectiveProjectionMatrix i_projection,int i_width,int i_height,double i_near,double i_far)\r
+       {\r
+               this.setValue(i_projection, i_width, i_height, i_near, i_far);\r
+       }\r
+       /**\r
+        * ARToolKitスタイルの射影変換行列から、視錐台をセットします。\r
+        * @param i_projection\r
+        * @param i_width\r
+        * @param i_height\r
+        * @param i_near\r
+        * nearポイントをmm単位で指定します。\r
+        * @param i_far\r
+        * farポイントをmm単位で指定します。\r
+        */\r
+       public void setValue(NyARPerspectiveProjectionMatrix i_projection,int i_width,int i_height,double i_near,double i_far)\r
+       {\r
+               i_projection.makeCameraFrustumRH(i_width, i_height, i_near, i_far,this._frustum_rh);\r
+               this._inv_frustum_rh.inverse(this._frustum_rh);\r
+               this._screen_size.setValue(i_width,i_height);\r
+       }\r
+       /**\r
+        * 画像上の座標を、撮像点座標に変換します。\r
+        * この座標は、カメラ座標系です。\r
+        * @param ix\r
+        * 画像上の座標\r
+        * @param iy\r
+        * 画像上の座標\r
+        * @param o_point_on_screen\r
+        * 撮像点座標\r
+        * <p>\r
+        * この関数は、gluUnprojectのビューポートとモデルビュー行列を固定したものです。\r
+        * 公式は、以下の物使用。\r
+        * http://www.opengl.org/sdk/docs/man/xhtml/gluUnProject.xml\r
+        * ARToolKitの座標系に合せて計算するため、OpenGLのunProjectとはix,iyの与え方が違います。画面上の座標をそのまま与えてください。\r
+        * </p>\r
+        */\r
+       public final void unProject(double ix,double iy,NyARDoublePoint3d o_point_on_screen)\r
+       {\r
+               double n=(this._frustum_rh.m23/(this._frustum_rh.m22-1));\r
+               NyARDoubleMatrix44 m44=this._inv_frustum_rh;\r
+               double v1=(this._screen_size.w-ix-1)*2/this._screen_size.w-1.0;//ARToolKitのFrustramに合せてる。\r
+               double v2=(this._screen_size.h-iy-1)*2/this._screen_size.h-1.0;\r
+               double v3=2*n-1.0;\r
+               double b=1/(m44.m30*v1+m44.m31*v2+m44.m32*v3+m44.m33);\r
+               o_point_on_screen.x=(m44.m00*v1+m44.m01*v2+m44.m02*v3+m44.m03)*b;\r
+               o_point_on_screen.y=(m44.m10*v1+m44.m11*v2+m44.m12*v3+m44.m13)*b;\r
+               o_point_on_screen.z=(m44.m20*v1+m44.m21*v2+m44.m22*v3+m44.m23)*b;\r
+               return;\r
+       }\r
+       /**\r
+        * 画面上の点と原点を結ぶ直線と任意姿勢の平面の交差点を、カメラの座標系で取得します。\r
+        * この座標は、カメラ座標系です。\r
+        * @param ix\r
+        * @param iy\r
+        * @param i_mat\r
+        * 平面の姿勢行列です。\r
+        * @param o_pos\r
+        */\r
+       public final void unProjectOnCamera(double ix,double iy,NyARDoubleMatrix44 i_mat,NyARDoublePoint3d o_pos)\r
+       {\r
+               //画面→撮像点\r
+               this.unProject(ix,iy,o_pos);\r
+               //撮像点→カメラ座標系\r
+               double nx=i_mat.m02;\r
+               double ny=i_mat.m12;\r
+               double nz=i_mat.m22;\r
+               double mx=i_mat.m03;\r
+               double my=i_mat.m13;\r
+               double mz=i_mat.m23;\r
+               double t=(nx*mx+ny*my+nz*mz)/(nx*o_pos.x+ny*o_pos.y+nz*o_pos.z);\r
+               o_pos.x=t*o_pos.x;\r
+               o_pos.y=t*o_pos.y;\r
+               o_pos.z=t*o_pos.z;\r
+       }       \r
+       /**\r
+        * 画面上の点と原点を結ぶ直線と任意姿勢の平面の交差点を、平面の座標系で取得します。\r
+        * ARToolKitの本P175周辺の実装と同じです。\r
+        * @param ix\r
+        * @param iy\r
+        * @param i_mat\r
+        * 平面の姿勢行列です。\r
+        * @param o_pos\r
+        * @return\r
+        * <p>\r
+        * このAPIは繰り返し使用には最適化されていません。同一なi_matに繰り返しアクセスするときは、展開してください。\r
+        * </p>\r
+        */\r
+       public final boolean unProjectOnMatrix(double ix,double iy,NyARDoubleMatrix44 i_mat,NyARDoublePoint3d o_pos)\r
+       {\r
+               //交点をカメラ座標系で計算\r
+               unProjectOnCamera(ix,iy,i_mat,o_pos);\r
+               //座標系の変換\r
+               NyARDoubleMatrix44 m=new NyARDoubleMatrix44();\r
+               if(!m.inverse(i_mat)){\r
+                       return false;\r
+               }\r
+               m.transform3d(o_pos, o_pos);\r
+               return true;\r
+       }\r
+       /**\r
+        * カメラ座標系を、画面座標へ変換します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_z\r
+        * @param o_pos2d\r
+        */\r
+       public final void project(double i_x,double i_y,double i_z,NyARDoublePoint2d o_pos2d)\r
+       {\r
+               NyARDoubleMatrix44 m=this._frustum_rh;\r
+               double v3_1=1/i_z*m.m32;\r
+               double w=this._screen_size.w;\r
+               double h=this._screen_size.h;\r
+               o_pos2d.x=w-(1+(i_x*m.m00+i_z*m.m02)*v3_1)*w/2;\r
+               o_pos2d.y=h-(1+(i_y*m.m11+i_z*m.m12)*v3_1)*h/2;\r
+               return;\r
+       }\r
+       /**\r
+        * 透視変換行列の参照値を返します。\r
+        * この値は読出し専用です。変更しないでください。\r
+        * @return\r
+        */\r
+       public final NyARDoubleMatrix44 refMatrix()\r
+       {\r
+               return this._frustum_rh;\r
+       }\r
+       /**\r
+        * 透視変換行列の逆行列を返します。\r
+        * この値は読出し専用です。変更しないでください。\r
+        * @return\r
+        */\r
+       public final NyARDoubleMatrix44 refInvMatrix()\r
+       {\r
+               return this._inv_frustum_rh;\r
+       }\r
+       \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java b/lib/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java
new file mode 100644 (file)
index 0000000..166afd9
--- /dev/null
@@ -0,0 +1,96 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 歪み矯正した座標系を格納したクラスです。\r
+ * 2次元ラスタを1次元配列で表現します。\r
+ *\r
+ */\r
+public class NyARObserv2IdealMap\r
+{\r
+       protected int _stride;\r
+       protected double[] _mapx;\r
+       protected double[] _mapy;\r
+       public NyARObserv2IdealMap(NyARCameraDistortionFactor i_distfactor,NyARIntSize i_screen_size)\r
+       {\r
+               NyARDoublePoint2d opoint=new NyARDoublePoint2d();\r
+               this._mapx=new double[i_screen_size.w*i_screen_size.h];\r
+               this._mapy=new double[i_screen_size.w*i_screen_size.h];\r
+               this._stride=i_screen_size.w;\r
+               int ptr=i_screen_size.h*i_screen_size.w-1;\r
+               //歪みマップを構築\r
+               for(int i=i_screen_size.h-1;i>=0;i--)\r
+               {\r
+                       for(int i2=i_screen_size.w-1;i2>=0;i2--)\r
+                       {\r
+                               i_distfactor.observ2Ideal(i2,i, opoint);\r
+                               this._mapx[ptr]=opoint.x;\r
+                               this._mapy[ptr]=opoint.y;\r
+                               ptr--;\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+       public void observ2Ideal(int ix, int iy, NyARIntPoint2d o_point)\r
+       {\r
+               int idx=ix+iy*this._stride;\r
+               o_point.x=(int)this._mapx[idx];\r
+               o_point.y=(int)this._mapy[idx];\r
+               return;\r
+       }       \r
+       public void observ2Ideal(int ix, int iy, NyARDoublePoint2d o_point)\r
+       {\r
+               int idx=ix+iy*this._stride;\r
+               o_point.x=this._mapx[idx];\r
+               o_point.y=this._mapy[idx];\r
+               return;\r
+       }\r
+       \r
+       public void observ2IdealBatch(NyARIntPoint2d[] i_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord,int i_out_start_index)\r
+       {\r
+               int idx;\r
+               int ptr=i_out_start_index;\r
+               final double[] mapx=this._mapx;\r
+               final double[] mapy=this._mapy;\r
+               final int stride=this._stride;\r
+               for (int j = 0; j < i_num; j++){\r
+                       idx=i_coord[i_start + j].x+i_coord[i_start + j].y*stride;\r
+                       o_x_coord[ptr]=mapx[idx];\r
+                       o_y_coord[ptr]=mapy[idx];\r
+                       ptr++;\r
+               }\r
+               return;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/param/NyARParam.java b/lib/src/jp/nyatla/nyartoolkit/core/param/NyARParam.java
new file mode 100644 (file)
index 0000000..7b44e1b
--- /dev/null
@@ -0,0 +1,202 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import java.io.*;\r
+import java.nio.*;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix44;\r
+\r
+/**\r
+ * typedef struct { int xsize, ysize; double mat[3][4]; double dist_factor[4]; } ARParam;\r
+ * NyARの動作パラメータを格納するクラス\r
+ *\r
+ */\r
+public class NyARParam\r
+{\r
+       protected NyARIntSize _screen_size=new NyARIntSize();\r
+       private static final int SIZE_OF_PARAM_SET = 4 + 4 + (3 * 4 * 8) + (4 * 8);\r
+       private NyARCameraDistortionFactor _dist=new NyARCameraDistortionFactor();\r
+       private NyARPerspectiveProjectionMatrix _projection_matrix=new NyARPerspectiveProjectionMatrix();\r
+\r
+       public NyARIntSize getScreenSize()\r
+       {\r
+               return this._screen_size;\r
+       }\r
+\r
+       /**\r
+        * ARToolKit形式の透視変換行列を返します。\r
+        * @return\r
+        */\r
+       public NyARPerspectiveProjectionMatrix getPerspectiveProjectionMatrix()\r
+       {\r
+               return this._projection_matrix;\r
+       }\r
+       /**\r
+        * ARToolKit形式の歪み補正パラメータを返します。\r
+        * @return\r
+        */\r
+       public NyARCameraDistortionFactor getDistortionFactor()\r
+       {\r
+               return this._dist;\r
+       }\r
+       /**\r
+        * \r
+        * @param i_factor\r
+        * NyARCameraDistortionFactorにセットする配列を指定する。要素数は4であること。\r
+        * @param i_projection\r
+        * NyARPerspectiveProjectionMatrixセットする配列を指定する。要素数は12であること。\r
+        */\r
+       public void setValue(double[] i_factor,double[] i_projection)\r
+       {\r
+               this._dist.setValue(i_factor);\r
+               this._projection_matrix.setValue(i_projection);\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * ARToolKit標準ファイルから1個目の設定をロードする。\r
+        * \r
+        * @param i_filename\r
+        * @throws NyARException\r
+        */\r
+       public void loadARParamFromFile(String i_filename) throws NyARException\r
+       {\r
+               try {\r
+                       loadARParam(new FileInputStream(i_filename));\r
+               } catch (Exception e) {\r
+                       throw new NyARException(e);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * int arParamChangeSize( ARParam *source, int xsize, int ysize, ARParam *newparam );\r
+        * 関数の代替関数 サイズプロパティをi_xsize,i_ysizeに変更します。\r
+        * @param i_xsize\r
+        * @param i_ysize\r
+        * @param newparam\r
+        * @return\r
+        * \r
+        */\r
+       public void changeScreenSize(int i_xsize, int i_ysize)\r
+       {\r
+               final double scale = (double) i_xsize / (double) (this._screen_size.w);// scale = (double)xsize / (double)(source->xsize);\r
+               //スケールを変更\r
+               this._dist.changeScale(scale);\r
+               this._projection_matrix.changeScale(scale);\r
+               this._screen_size.w = i_xsize;// newparam->xsize = xsize;\r
+               this._screen_size.h = i_ysize;// newparam->ysize = ysize;\r
+               return;\r
+       }\r
+       /**\r
+        * 右手系の視錐台を作ります。\r
+        * 計算結果を多用するときは、キャッシュするようにして下さい。\r
+        * @param i_dist_min\r
+        * @param i_dist_max\r
+        * @param o_frustum\r
+        */\r
+       public void makeCameraFrustumRH(double i_dist_min,double i_dist_max,NyARDoubleMatrix44 o_frustum)\r
+       {\r
+               this._projection_matrix.makeCameraFrustumRH(this._screen_size.w, this._screen_size.h, i_dist_min, i_dist_max, o_frustum);\r
+               return;\r
+       }       \r
+\r
+\r
+       /**\r
+        * int arParamLoad( const char *filename, int num, ARParam *param, ...);\r
+        * i_streamの入力ストリームからi_num個の設定を読み込み、パラメタを配列にして返します。\r
+        * \r
+        * @param i_stream\r
+        * @throws Exception\r
+        */\r
+       public void loadARParam(InputStream i_stream)throws NyARException\r
+       {\r
+               try {\r
+                       byte[] buf = new byte[SIZE_OF_PARAM_SET];\r
+                       i_stream.read(buf);\r
+                       double[] tmp=new double[16];\r
+\r
+                       // バッファを加工\r
+                       ByteBuffer bb = ByteBuffer.wrap(buf);\r
+                       bb.order(ByteOrder.BIG_ENDIAN);\r
+                       this._screen_size.w = bb.getInt();\r
+                       this._screen_size.h = bb.getInt();\r
+                       //double値を12個読み込む\r
+                       for(int i=0;i<12;i++){\r
+                               tmp[i]=bb.getDouble();\r
+                       }\r
+                       //パディング\r
+                       tmp[12]=tmp[13]=tmp[14]=0;\r
+                       tmp[15]=1;\r
+                       //Projectionオブジェクトにセット\r
+                       this._projection_matrix.setValue(tmp);\r
+                       //double値を4個読み込む\r
+                       for (int i = 0; i < 4; i++) {\r
+                               tmp[i]=bb.getDouble();\r
+                       }\r
+                       //Factorオブジェクトにセット\r
+                       this._dist.setValue(tmp);\r
+               } catch (Exception e) {\r
+                       throw new NyARException(e);\r
+               }\r
+               return;\r
+       }\r
+\r
+       public void saveARParam(OutputStream i_stream)throws Exception\r
+       {\r
+               NyARException.trap("未チェックの関数");\r
+               byte[] buf = new byte[SIZE_OF_PARAM_SET];\r
+               // バッファをラップ\r
+               ByteBuffer bb = ByteBuffer.wrap(buf);\r
+               bb.order(ByteOrder.BIG_ENDIAN);\r
+\r
+               // 書き込み\r
+               bb.putInt(this._screen_size.w);\r
+               bb.putInt(this._screen_size.h);\r
+               double[] tmp=new double[12];\r
+               //Projectionを読み出し\r
+               this._projection_matrix.getValue(tmp);\r
+               //double値を12個書き込む\r
+               for(int i=0;i<12;i++){\r
+                       tmp[i]=bb.getDouble();\r
+               }\r
+               //Factorを読み出し\r
+               this._dist.getValue(tmp);\r
+               //double値を4個書き込む\r
+               for (int i = 0; i < 4; i++) {\r
+                       tmp[i]=bb.getDouble();\r
+               }\r
+               i_stream.write(buf);\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/param/NyARPerspectiveProjectionMatrix.java b/lib/src/jp/nyatla/nyartoolkit/core/param/NyARPerspectiveProjectionMatrix.java
new file mode 100644 (file)
index 0000000..0992d91
--- /dev/null
@@ -0,0 +1,300 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 透視変換行列を格納します。\r
+ * http://www.hitl.washington.edu/artoolkit/Papers/ART02-Tutorial.pdf\r
+ * 7ページを見るといいよ。\r
+ *\r
+ */\r
+final public class NyARPerspectiveProjectionMatrix extends NyARDoubleMatrix44\r
+{\r
+       public NyARPerspectiveProjectionMatrix()\r
+       {\r
+               this.m30=this.m31=this.m32=0;\r
+               this.m33=1;\r
+       }\r
+       /*\r
+        * static double dot( double a1, double a2, double a3,double b1, double b2,double b3 )\r
+        */\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
+\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
+       /**\r
+        * int arParamDecompMat( double source[3][4], double cpara[3][4], double trans[3][4] ); 関数の置き換え Optimize STEP[754->665]\r
+        * \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 rem1, rem2, rem3;\r
+               double c00,c01,c02,c03,c10,c11,c12,c13,c20,c21,c22,c23;\r
+               if (this.m23>= 0) {// if( source[2][3] >= 0 ) {\r
+                       c00=this.m00;\r
+                       c01=this.m01;\r
+                       c02=this.m02;\r
+                       c03=this.m03;\r
+                       c10=this.m10;\r
+                       c11=this.m11;\r
+                       c12=this.m12;\r
+                       c13=this.m13;\r
+                       c20=this.m20;\r
+                       c21=this.m21;\r
+                       c22=this.m22;\r
+                       c23=this.m23;\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
+                       c00=-this.m00;\r
+                       c01=-this.m01;\r
+                       c02=-this.m02;\r
+                       c03=-this.m03;\r
+                       c10=-this.m10;\r
+                       c11=-this.m11;\r
+                       c12=-this.m12;\r
+                       c13=-this.m13;\r
+                       c20=-this.m20;\r
+                       c21=-this.m21;\r
+                       c22=-this.m22;\r
+                       c23=-this.m23;\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(c20, c21, c22);// cpara[2][2] =norm( Cpara[2][0],Cpara[2][1],Cpara[2][2]);\r
+               trans[2][0] = c20 / cpara[2][2];// trans[2][0] = Cpara[2][0] /cpara[2][2];\r
+               trans[2][1] = c21 / cpara[2][2];// trans[2][1] = Cpara[2][1] / cpara[2][2];\r
+               trans[2][2] = c22 / cpara[2][2];// trans[2][2] =Cpara[2][2] /cpara[2][2];\r
+               trans[2][3] = c23 / 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], c10, c11, c12);// cpara[1][2]=dot(trans[2][0],trans[2][1],trans[2][2],Cpara[1][0],Cpara[1][1],Cpara[1][2]);\r
+               rem1 = c10 - cpara[1][2] * trans[2][0];// rem1 =Cpara[1][0] -cpara[1][2] *trans[2][0];\r
+               rem2 = c11 - cpara[1][2] * trans[2][1];// rem2 =Cpara[1][1] -cpara[1][2] *trans[2][1];\r
+               rem3 = c12 - 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], c00, c01, c02);// 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], c00, c01, c02);// cpara[0][1]=dot(trans[1][0],trans[1][1],trans[1][2],Cpara[0][0],Cpara[0][1],Cpara[0][2]);\r
+               rem1 = c00 - 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 = c01 - 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 = c02 - 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] = (c13 - 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] = (c03 - 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
+               return;\r
+       }\r
+       /**\r
+        * int arParamChangeSize( ARParam *source, int xsize, int ysize, ARParam *newparam );\r
+        * Matrixのスケールを変換します。\r
+        * @param i_scale\r
+        * \r
+        */\r
+       public void changeScale(double i_scale)\r
+       {\r
+               this.m00=this.m00*i_scale;\r
+               this.m10=this.m10*i_scale;\r
+               this.m01=this.m01*i_scale;\r
+               this.m11=this.m11*i_scale;\r
+               this.m02=this.m02*i_scale;\r
+               this.m12=this.m12*i_scale;\r
+               this.m03=this.m03*i_scale;\r
+               this.m13=this.m13*i_scale;\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
+               return;\r
+       }\r
+       \r
+       /**\r
+        * 3次元座標を2次元座標に変換します。\r
+        * @param i_3dvertex\r
+        * @param o_2d\r
+        */\r
+       public final void project(NyARDoublePoint3d i_3dvertex,NyARDoublePoint2d o_2d)\r
+       {\r
+               double w=1/(i_3dvertex.z*this.m22);\r
+               o_2d.x=(i_3dvertex.x*this.m00+i_3dvertex.y*this.m01+i_3dvertex.z*this.m02)*w;\r
+               o_2d.y=(i_3dvertex.y*this.m11+i_3dvertex.z*this.m12)*w;\r
+               return;\r
+       }\r
+       /**\r
+        * 3次元座標を2次元座標に変換します。\r
+        * @param i_3dvertex\r
+        * @param o_2d\r
+        */\r
+       public final void project(double i_x,double i_y,double i_z,NyARDoublePoint2d o_2d)\r
+       {\r
+               double w=1/(i_z*this.m22);\r
+               o_2d.x=(i_x*this.m00+i_y*this.m01+i_z*this.m02)*w;\r
+               o_2d.y=(i_y*this.m11+i_z*this.m12)*w;\r
+               return;\r
+       }       \r
+       /**\r
+        * 3次元座標を2次元座標に変換します。\r
+        * @param i_3dvertex\r
+        * @param o_2d\r
+        */\r
+       public final void project(NyARDoublePoint3d i_3dvertex,NyARIntPoint2d o_2d)\r
+       {\r
+               double w=1/(i_3dvertex.z*this.m22);\r
+               o_2d.x=(int)((i_3dvertex.x*this.m00+i_3dvertex.y*this.m01+i_3dvertex.z*this.m02)*w);\r
+               o_2d.y=(int)((i_3dvertex.y*this.m11+i_3dvertex.z*this.m12)*w);\r
+               return;\r
+       }       \r
+       /**\r
+        * 3次元座標を2次元座標に変換します。\r
+        * @param i_3dvertex\r
+        * @param o_2d\r
+        */\r
+       public final void project(double i_x,double i_y,double i_z,NyARIntPoint2d o_2d)\r
+       {\r
+               double w=1/(i_z*this.m22);\r
+               o_2d.x=(int)((i_x*this.m00+i_y*this.m01+i_z*this.m02)*w);\r
+               o_2d.y=(int)((i_y*this.m11+i_z*this.m12)*w);\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * 右手系の視錐台を作ります。\r
+        * @param i_screen_width\r
+        * @param i_screen_height\r
+        * @param i_dist_min\r
+        * @param i_dist_max\r
+        * @param o_frustum\r
+        */\r
+       public void makeCameraFrustumRH(double i_screen_width,double i_screen_height,double i_dist_min,double i_dist_max,NyARDoubleMatrix44 o_frustum)\r
+       {\r
+               NyARMat trans_mat = new NyARMat(3, 4);\r
+               NyARMat icpara_mat = new NyARMat(3, 4);\r
+               double[][] p = new double[3][3];\r
+               int i;\r
+               \r
+               this.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] = (i_screen_height - 1) * (icpara[2][i]) - icpara[1][i];\r
+               }\r
+               p[0][0] = icpara[0][0] / icpara[2][2];\r
+               p[0][1] = icpara[0][1] / icpara[2][2];\r
+               p[0][2] = icpara[0][2] / icpara[2][2];\r
+\r
+               p[1][0] = icpara[1][0] / icpara[2][2];\r
+               p[1][1] = icpara[1][1] / icpara[2][2];\r
+               p[1][2] = icpara[1][2] / icpara[2][2];\r
+               \r
+               p[2][0] = icpara[2][0] / icpara[2][2];\r
+               p[2][1] = icpara[2][1] / icpara[2][2];\r
+               p[2][2] = icpara[2][2] / icpara[2][2];\r
+\r
+               double q00,q01,q02,q03,q10,q11,q12,q13,q20,q21,q22,q23,q30,q31,q32,q33;\r
+               \r
+               //視錐台への変換\r
+               q00 = (2.0 * p[0][0] / (i_screen_width - 1));\r
+               q01 = (2.0 * p[0][1] / (i_screen_width - 1));\r
+               q02 = -((2.0 * p[0][2] / (i_screen_width - 1)) - 1.0);\r
+               q03 = 0.0;\r
+               o_frustum.m00 = q00 * trans[0][0] + q01 * trans[1][0] + q02 * trans[2][0];\r
+               o_frustum.m01 = q00 * trans[0][1] + q01 * trans[1][1] + q02 * trans[2][1];\r
+               o_frustum.m02 = q00 * trans[0][2] + q01 * trans[1][2] + q02 * trans[2][2];\r
+               o_frustum.m03 = q00 * trans[0][3] + q01 * trans[1][3] + q02 * trans[2][3] + q03;\r
+\r
+               q10 = 0.0;\r
+               q11 = -(2.0 * p[1][1] / (i_screen_height - 1));\r
+               q12 = -((2.0 * p[1][2] / (i_screen_height - 1)) - 1.0);\r
+               q13 = 0.0;\r
+               o_frustum.m10 = q10 * trans[0][0] + q11 * trans[1][0] + q12 * trans[2][0];\r
+               o_frustum.m11 = q10 * trans[0][1] + q11 * trans[1][1] + q12 * trans[2][1];\r
+               o_frustum.m12 = q10 * trans[0][2] + q11 * trans[1][2] + q12 * trans[2][2];\r
+               o_frustum.m13 = q10 * trans[0][3] + q11 * trans[1][3] + q12 * trans[2][3] + q13;\r
+\r
+               q20 = 0.0;\r
+               q21 = 0.0;\r
+               q22 = (i_dist_max + i_dist_min) / (i_dist_min - i_dist_max);\r
+               q23 = 2.0 * i_dist_max * i_dist_min / (i_dist_min - i_dist_max);\r
+               o_frustum.m20 = q20 * trans[0][0] + q21 * trans[1][0] + q22 * trans[2][0];\r
+               o_frustum.m21 = q20 * trans[0][1] + q21 * trans[1][1] + q22 * trans[2][1];\r
+               o_frustum.m22 = q20 * trans[0][2] + q21 * trans[1][2] + q22 * trans[2][2];\r
+               o_frustum.m23 = q20 * trans[0][3] + q21 * trans[1][3] + q22 * trans[2][3] + q23;\r
+\r
+               q30 = 0.0;\r
+               q31 = 0.0;\r
+               q32 = -1.0;\r
+               q33 = 0.0;\r
+               o_frustum.m30 = q30 * trans[0][0] + q31 * trans[1][0] + q32 * trans[2][0];\r
+               o_frustum.m31 = q30 * trans[0][1] + q31 * trans[1][1] + q32 * trans[2][1];\r
+               o_frustum.m32 = q30 * trans[0][2] + q31 * trans[1][2] + q32 * trans[2][2];\r
+               o_frustum.m33 = q30 * trans[0][3] + q31 * trans[1][3] + q32 * trans[2][3] + q33;\r
+               return;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/pca2d/INyARPca2d.java b/lib/src/jp/nyatla/nyartoolkit/core/pca2d/INyARPca2d.java
new file mode 100644 (file)
index 0000000..5f7b113
--- /dev/null
@@ -0,0 +1,65 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pca2d;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+\r
+public interface INyARPca2d\r
+{\r
+       /**\r
+        * 通常のPCA\r
+        * @param i_v1\r
+        * @param i_v2\r
+        * @param i_start\r
+        * @param i_number_of_point\r
+        * @param o_evec\r
+        * 要素2の変数を指定してください。\r
+        * @param o_ev\r
+        * 要素2の変数を指定してください。\r
+        * @param o_mean\r
+        * @throws NyARException\r
+        */\r
+       public void pca(double[] i_v1,double[] i_v2,int i_number_of_point,NyARDoubleMatrix22 o_evec, double[] o_ev,double[] o_mean) throws NyARException;\r
+       /**\r
+        * カメラ歪み補正つきのPCA\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_start\r
+        * @param i_number_of_point\r
+        * @param i_factor\r
+        * @param o_evec\r
+        * @param o_mean\r
+        * @throws NyARException\r
+        */\r
+//     public void pcaWithDistortionFactor(int[] i_x,int[] i_y,int i_start,int i_number_of_point,INyARCameraDistortionFactor i_factor,NyARDoubleMatrix22 o_evec,NyARDoublePoint2d o_ev, NyARDoublePoint2d o_mean) throws NyARException;\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java b/lib/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java
new file mode 100644 (file)
index 0000000..ec47729
--- /dev/null
@@ -0,0 +1,73 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pca2d;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.NyARVec;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+/**\r
+ * NyARMatrixを利用した主成分分析\r
+ * ARToolKitと同じ処理をします。\r
+ */\r
+public class NyARPca2d_MatrixPCA implements INyARPca2d\r
+{\r
+       private final NyARMat __pca_input = new NyARMat(1, 2);\r
+       private final NyARMat __pca_evec = new NyARMat(2, 2);\r
+       private final NyARVec __pca_ev = new NyARVec(2);\r
+       private final NyARVec __pca_mean = new NyARVec(2);      \r
+       \r
+       public void pca(double[] i_v1,double[] i_v2,int i_number_of_point,NyARDoubleMatrix22 o_evec, double[] o_ev,double[] o_mean) throws NyARException\r
+       {\r
+               final NyARMat input = this.__pca_input;// 次処理で初期化される。             \r
+               // pcaの準備\r
+               input.realloc(i_number_of_point, 2);\r
+               final double[][] input_array=input.getArray();\r
+               for(int i=0;i<i_number_of_point;i++){\r
+                       input_array[i][0]=i_v1[i];\r
+                       input_array[i][1]=i_v2[i];\r
+               }\r
+               // 主成分分析\r
+               input.pca(this.__pca_evec, this.__pca_ev, this.__pca_mean);\r
+               final double[] mean_array = this.__pca_mean.getArray();\r
+               final double[][] evec_array = this.__pca_evec.getArray();\r
+               final double[] ev_array=this.__pca_ev.getArray();\r
+               o_evec.m00=evec_array[0][0];\r
+               o_evec.m01=evec_array[0][1];\r
+               o_evec.m10=evec_array[1][0];\r
+               o_evec.m11=evec_array[1][1];\r
+               o_ev[0]=ev_array[0];\r
+               o_ev[1]=ev_array[1];\r
+               o_mean[0]=mean_array[0];\r
+               o_mean[1]=mean_array[1];\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA_O2.java b/lib/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA_O2.java
new file mode 100644 (file)
index 0000000..0ca9dd2
--- /dev/null
@@ -0,0 +1,214 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pca2d;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+\r
+/**\r
+ * ARToolkitのPCA関数を二次元に特化させて単純化したもの\r
+ *\r
+ */\r
+public class NyARPca2d_MatrixPCA_O2 implements INyARPca2d\r
+{\r
+       private static final double PCA_EPS = 1e-6; // #define EPS 1e-6\r
+\r
+       private static final int PCA_MAX_ITER = 100; // #define MAX_ITER 100\r
+\r
+       private static final double PCA_VZERO = 1e-16; // #define VZERO 1e-16\r
+\r
+       /**\r
+        * static int QRM( ARMat *a, ARVec *dv )の代替関数\r
+        * \r
+        * @param a\r
+        * @param dv\r
+        * @throws NyARException\r
+        */\r
+       private static void PCA_QRM(NyARDoubleMatrix22 o_matrix, double[] dv) throws NyARException\r
+       {\r
+               double w, t, s, x, y, c;\r
+               double ev1;\r
+               double dv_x,dv_y;\r
+               double mat00,mat01,mat10,mat11;\r
+               // <this.vecTridiagonalize2d(i_mat, dv, ev);>\r
+               dv_x = o_matrix.m00;// 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
+               ev1 = o_matrix.m01;// 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
+               dv_y = o_matrix.m11;// 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
+               mat00 = mat11 = 1;\r
+               mat01 = mat10 = 0;\r
+               // </this.vecTridiagonalize2d(i_mat, dv, ev);>\r
+\r
+               // int j = 1;\r
+               // // while(j>0 && fabs(ev->v[j])>EPS*(fabs(dv->v[j-1])+fabs(dv->v[j])))\r
+               // while (j > 0 && Math.abs(ev1) > PCA_EPS * (Math.abs(dv.x) + Math.abs(dv.y))) {\r
+               // j--;\r
+               // }\r
+               // if (j == 0) {\r
+               int iter = 0;\r
+               do {\r
+                       iter++;\r
+                       if (iter > PCA_MAX_ITER) {\r
+                               break;\r
+                       }\r
+                       w = (dv_x - dv_y) / 2;// w = (dv->v[h-1] -dv->v[h]) / 2;//ここ?\r
+                       t = ev1 * ev1;// 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_x - dv_y + t / (w + s);// x = dv->v[j] -dv->v[h] +t/(w+s);\r
+                       y = ev1;// y = ev->v[j+1];\r
+\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_x - dv_y;// w = dv->v[k] -dv->v[k+1];\r
+                       t = (w * s + 2 * c * ev1) * s;// t = (w * s +2 * c *ev->v[k+1]) *s;\r
+                       dv_x -= t;// dv->v[k] -= t;\r
+                       dv_y += t;// dv->v[k+1] += t;\r
+                       ev1 += s * (c * w - 2 * s * ev1);// ev->v[k+1]+= s * (c* w- 2* s *ev->v[k+1]);\r
+\r
+                       x = mat00;// x = a->m[k*dim+i];\r
+                       y = mat10;// y = a->m[(k+1)*dim+i];\r
+                       mat00 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;\r
+                       mat10 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;\r
+                       \r
+                       x = mat01;// x = a->m[k*dim+i];\r
+                       y = mat11;// y = a->m[(k+1)*dim+i];\r
+                       mat01 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;\r
+                       mat11 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;\r
+               } while (Math.abs(ev1) > PCA_EPS * (Math.abs(dv_x) + Math.abs(dv_y)));\r
+               // }\r
+\r
+               t = dv_x;// t = dv->v[h];\r
+               if (dv_y > t) {// if( dv->v[i] > t ) {\r
+                       t = dv_y;// t = dv->v[h];\r
+                       dv_y = dv_x;// dv->v[h] = dv->v[k];\r
+                       dv_x = t;// dv->v[k] = t;\r
+                       // 行の入れ替え\r
+                       o_matrix.m00 = mat10;\r
+                       o_matrix.m01 = mat11;\r
+                       o_matrix.m10 = mat00;           \r
+                       o_matrix.m11 = mat01;\r
+                       \r
+               } else {\r
+                       // 行の入れ替えはなし\r
+                       o_matrix.m00 = mat00;\r
+                       o_matrix.m01 = mat01;\r
+                       o_matrix.m10 = mat10;           \r
+                       o_matrix.m11 = mat11;\r
+               }\r
+               dv[0]=dv_x;\r
+               dv[1]=dv_y;\r
+               return;\r
+       }\r
+\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(double[] i_v1,double[] i_v2,int i_number_of_data,NyARDoubleMatrix22 o_matrix, double[] o_ev,double[] o_mean) throws NyARException\r
+       {\r
+               // double[] mean_array=mean.getArray();\r
+               // mean.zeroClear();\r
+\r
+               //PCA_EXの処理\r
+               double sx = 0;\r
+               double sy = 0;\r
+               for (int i = 0; i < i_number_of_data; i++) {\r
+                       sx += i_v1[i];\r
+                       sy += i_v2[i];\r
+               }\r
+               sx = sx / i_number_of_data;\r
+               sy = sy / i_number_of_data;\r
+               \r
+               //PCA_CENTERとPCA_xt_by_xを一緒に処理\r
+               final double srow = Math.sqrt((double) i_number_of_data);\r
+               double w00, w11, w10;\r
+               w00 = w11 = w10 = 0.0;// *out = 0.0;\r
+               for (int i = 0; i < i_number_of_data; i++) {\r
+                       final double x = (i_v1[i] - sx) / srow;\r
+                       final double y = (i_v2[i] - sy) / srow;\r
+                       w00 += (x * x);// *out += *in1 * *in2;\r
+                       w10 += (x * y);// *out += *in1 * *in2;\r
+                       w11 += (y * y);// *out += *in1 * *in2;\r
+               }\r
+               o_matrix.m00=w00;\r
+               o_matrix.m01=o_matrix.m10=w10;\r
+               o_matrix.m11=w11;\r
+               \r
+               //PCA_PCAの処理\r
+               PCA_QRM(o_matrix, o_ev);\r
+               // m2 = o_output.m;// m2 = output->m;\r
+               if (o_ev[0] < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
+                       o_ev[0] = 0.0;// ev->v[i] = 0.0;\r
+                       o_matrix.m00 = 0.0;// *(m2++) = 0.0;\r
+                       o_matrix.m01 = 0.0;// *(m2++) = 0.0;\r
+               }\r
+\r
+               if (o_ev[1] < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
+                       o_ev[1] = 0.0;// ev->v[i] = 0.0;\r
+                       o_matrix.m10 = 0.0;// *(m2++) = 0.0;\r
+                       o_matrix.m11 = 0.0;// *(m2++) = 0.0;\r
+               }\r
+               o_mean[0]=sx;\r
+               o_mean[1]=sy;\r
+               // }\r
+               return;\r
+       }\r
+       public void pca(double[] i_v1,double[] i_v2,int i_number_of_point,NyARDoubleMatrix22 o_evec, double[] o_ev,double[] o_mean) throws NyARException\r
+       {\r
+               PCA_PCA(i_v1,i_v2,i_number_of_point,o_evec, o_ev,o_mean);\r
+\r
+               final double sum = o_ev[0] + o_ev[1];\r
+               // For順変更禁止\r
+               o_ev[0] /= sum;// ev->v[i] /= sum;\r
+               o_ev[1] /= sum;// ev->v[i] /= sum;\r
+               return; \r
+       }\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/pickup/INyARColorPatt.java b/lib/src/jp/nyatla/nyartoolkit/core/pickup/INyARColorPatt.java
new file mode 100644 (file)
index 0000000..2a83598
--- /dev/null
@@ -0,0 +1,57 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public interface INyARColorPatt extends INyARRgbRaster\r
+{\r
+       /**\r
+        * ラスタイメージからi_square部分のカラーパターンを抽出して、thisメンバに格納します。\r
+        * \r
+        * @param image\r
+        * Source raster object.\r
+        * ----\r
+        * 抽出元のラスタオブジェクト\r
+        * @param i_vertexs\r
+        * Vertexes of the square. Number of element must be 4.\r
+        * ----\r
+        * 射影変換元の4角形を構成する頂点群頂群。要素数は4であること。\r
+        * @return\r
+        * True if sucessfull; otherwise false.\r
+        * ----\r
+        * ラスターの取得に成功するとTRUE/失敗するとFALSE\r
+        * @throws NyARException\r
+        */\r
+       public boolean pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertexs) throws NyARException;\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_O1.java b/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_O1.java
new file mode 100644 (file)
index 0000000..a3aede7
--- /dev/null
@@ -0,0 +1,243 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序以外の最適化をしたもの\r
+ * \r
+ */\r
+public class NyARColorPatt_O1 implements INyARColorPatt\r
+{\r
+       private static final int AR_PATT_SAMPLE_NUM = 64;\r
+       private static final int BUFFER_FORMAT=NyARBufferType.INT1D_X8R8G8B8_32;\r
+       private int[] _patdata;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+\r
+       private NyARIntSize _size;\r
+\r
+       public NyARColorPatt_O1(int i_width, int i_height)\r
+       {\r
+               //入力制限\r
+               assert i_width<=64 && i_height<=64;\r
+               \r
+               this._size=new NyARIntSize(i_width,i_height);\r
+               this._patdata = new int[i_height*i_width];\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+               return;\r
+       }\r
+\r
+       public final int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       public final int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+       public final NyARIntSize getSize()\r
+       {\r
+               return  this._size;\r
+       }\r
+       public final INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._patdata;\r
+       }\r
+       public boolean hasBuffer()\r
+       {\r
+               return this._patdata!=null;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               NyARException.notImplement();\r
+       }\r
+       final public int getBufferType()\r
+       {\r
+               return BUFFER_FORMAT;\r
+       }\r
+       final public boolean isEqualBufferType(int i_type_value)\r
+       {\r
+               return BUFFER_FORMAT==i_type_value;\r
+       }\r
+       private final NyARMat __get_cpara_a = new NyARMat(8, 8);\r
+       private final NyARMat __get_cpara_b = new NyARMat(8, 1);\r
+       private final static double[][] __get__cpara_world = {{ 100.0, 100.0 }, { 100.0 + 10.0, 100.0 }, { 100.0 + 10.0, 100.0 + 10.0 },{ 100.0, 100.0 + 10.0 } };\r
+       \r
+       final protected boolean get_cpara(final NyARIntPoint2d[] i_vertex, NyARMat o_para)throws NyARException\r
+       {\r
+               double[][] world = __get__cpara_world;\r
+               NyARMat a = __get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
+               double[][] a_array = a.getArray();\r
+               NyARMat b = __get_cpara_b;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
+               double[][] b_array = b.getArray();\r
+               double[] a_pt0, a_pt1;\r
+               double[] 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] = (double) world_pti[0];// a->m[i*16+0] = world[i][0];\r
+                       a_pt0[1] = (double) 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] = (double) (-world_pti[0] * i_vertex[i].x);// a->m[i*16+6]= -world[i][0]*vertex[i][0];\r
+                       a_pt0[7] = (double) (-world_pti[1] * i_vertex[i].x);// 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] = (double) world_pti[0];// a->m[i*16+11] = world[i][0];\r
+                       a_pt1[4] = (double) 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] = (double) (-world_pti[0] * i_vertex[i].y);// a->m[i*16+14]=-world[i][0]*vertex[i][1];\r
+                       a_pt1[7] = (double) (-world_pti[1] * i_vertex[i].y);// a->m[i*16+15]=-world[i][1]*vertex[i][1];\r
+                       b_array[i * 2 + 0][0] = (double) i_vertex[i].x;// b->m[i*2+0] =vertex[i][0];\r
+                       b_array[i * 2 + 1][0] = (double) i_vertex[i].y;// 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
+       private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
+       private final NyARMat __pickFromRaster_cpara_c = new NyARMat(8, 1);\r
+       \r
+       /**\r
+        * @see INyARColorPatt#pickFromRaster\r
+        */\r
+       public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+       {\r
+               // パターンの切り出しに失敗することもある。\r
+               NyARMat cpara = this.__pickFromRaster_cpara_c;\r
+               if (!get_cpara(i_vertexs, cpara)) {\r
+                       return false;\r
+               }\r
+               final double[][] para=cpara.getArray();\r
+               final double para00=para[0*3+0][0];\r
+               final double para01=para[0*3+1][0];\r
+               final double para02=para[0*3+2][0];\r
+               final double para10=para[1*3+0][0];\r
+               final double para11=para[1*3+1][0];\r
+               final double para12=para[1*3+2][0];\r
+               final double para20=para[2*3+0][0];\r
+               final double para21=para[2*3+1][0];\r
+               final double para22=1.0;\r
+               \r
+               int lx1 = (int) ((i_vertexs[0].x - i_vertexs[1].x) * (i_vertexs[0].x - i_vertexs[1].x) + (i_vertexs[0].y - i_vertexs[1].y)* (i_vertexs[0].y - i_vertexs[1].y));\r
+               int lx2 = (int) ((i_vertexs[2].x - i_vertexs[3].x) * (i_vertexs[2].x - i_vertexs[3].x) + (i_vertexs[2].y - i_vertexs[3].y)* (i_vertexs[2].y - i_vertexs[3].y));\r
+               int ly1 = (int) ((i_vertexs[1].x - i_vertexs[2].x) * (i_vertexs[1].x - i_vertexs[2].x) + (i_vertexs[1].y - i_vertexs[2].y)* (i_vertexs[1].y - i_vertexs[2].y));\r
+               int ly2 = (int) ((i_vertexs[3].x - i_vertexs[0].x) * (i_vertexs[3].x - i_vertexs[0].x) + (i_vertexs[3].y - i_vertexs[0].y)* (i_vertexs[3].y - i_vertexs[0].y));\r
+               if (lx2 > lx1) {\r
+                       lx1 = lx2;\r
+               }\r
+               if (ly2 > ly1) {\r
+                       ly1 = ly2;\r
+               }\r
+               \r
+               int sample_pixel_x = this._size.w;\r
+               int sample_pixel_y = this._size.h;\r
+               while (sample_pixel_x * sample_pixel_x < lx1 / 4) {\r
+                       sample_pixel_x *= 2;\r
+               }\r
+               while (sample_pixel_y * sample_pixel_y < ly1 / 4) {\r
+                       sample_pixel_y *= 2;\r
+               }\r
+\r
+               if (sample_pixel_x > AR_PATT_SAMPLE_NUM) {\r
+                       sample_pixel_x = AR_PATT_SAMPLE_NUM;\r
+               }\r
+               if (sample_pixel_y > AR_PATT_SAMPLE_NUM) {\r
+                       sample_pixel_y = AR_PATT_SAMPLE_NUM;\r
+               }\r
+\r
+               final int xdiv = sample_pixel_x / this._size.w;// xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
+               final int ydiv = sample_pixel_y / this._size.h;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+\r
+\r
+               int img_x = image.getWidth();\r
+               int img_y = image.getHeight();\r
+\r
+               final double xdiv2_reciprocal = 1.0 / sample_pixel_x;\r
+               final double ydiv2_reciprocal = 1.0 / sample_pixel_y;\r
+               int r,g,b;\r
+               int[] rgb_tmp = __pickFromRaster_rgb_tmp;\r
+\r
+               //ピクセルリーダーを取得\r
+               INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+               final int xdiv_x_ydiv = xdiv * ydiv;\r
+\r
+               for(int iy=0;iy<this._size.h;iy++){\r
+                       for(int ix=0;ix<this._size.w;ix++){\r
+                               r=g=b=0;\r
+                               //1ピクセルを作成\r
+                               for(int j=0;j<ydiv;j++){\r
+                                       final double yw = 102.5 + 5.0 * (iy*ydiv+j + 0.5) * ydiv2_reciprocal;                                           \r
+                                       for(int i=0;i<xdiv;i++){\r
+                                               final double xw = 102.5 + 5.0 * (ix*xdiv+i + 0.5) * xdiv2_reciprocal;\r
+                                               final double d = para20 * xw + para21 * yw+ para22;\r
+                                               if (d == 0) {\r
+                                                       throw new NyARException();\r
+                                               }\r
+                                               final int xc = (int) ((para00 * xw + para01 * yw + para02) / d);\r
+                                               final int yc = (int) ((para10 * xw + para11 * yw + para12) / d);\r
+       \r
+                                               if (xc >= 0 && xc < img_x && yc >= 0 && yc < img_y) {\r
+                                                       reader.getPixel(xc, yc, rgb_tmp);\r
+                                                       r += rgb_tmp[0];// R\r
+                                                       g += rgb_tmp[1];// G\r
+                                                       b += rgb_tmp[2];// B\r
+                                                       // System.out.println(xc+":"+yc+":"+rgb_tmp[0]+":"+rgb_tmp[1]+":"+rgb_tmp[2]);\r
+                                               }\r
+                                       }\r
+                               }\r
+                               this._patdata[iy*this._size.w+ix]=(((r / xdiv_x_ydiv)&0xff)<<16)|(((g / xdiv_x_ydiv)&0xff)<<8)|(((b / xdiv_x_ydiv)&0xff));\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+       \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_O3.java b/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_O3.java
new file mode 100644 (file)
index 0000000..ee7f23e
--- /dev/null
@@ -0,0 +1,316 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序を含む最適化をしたもの\r
+ * \r
+ */\r
+public class NyARColorPatt_O3 implements INyARColorPatt\r
+{\r
+       private static final int AR_PATT_SAMPLE_NUM = 64;\r
+       private static final int BUFFER_FORMAT=NyARBufferType.INT1D_X8R8G8B8_32;\r
+\r
+       private int[] _patdata;\r
+       private NyARIntSize _size;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+       \r
+       public NyARColorPatt_O3(int i_width, int i_height)\r
+       {\r
+               this._size=new NyARIntSize(i_width,i_height);\r
+               this._patdata = new int[i_height*i_width];\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+       }\r
+       public int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       public int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+       public NyARIntSize getSize()\r
+       {\r
+               return  this._size;\r
+       }\r
+       public INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._patdata;\r
+       }\r
+       public boolean hasBuffer()\r
+       {\r
+               return this._patdata!=null;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               NyARException.notImplement();\r
+       }\r
+       final public int getBufferType()\r
+       {\r
+               return BUFFER_FORMAT;\r
+       }\r
+       final public boolean isEqualBufferType(int i_type_value)\r
+       {\r
+               return BUFFER_FORMAT==i_type_value;\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_pickFromRaster_cpara = 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(final NyARIntPoint2d[] i_vertex, NyARMat o_para)throws NyARException\r
+       {\r
+               int[][] world = 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;\r
+               int[] 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] = (double) world_pti[0];// a->m[i*16+0] = world[i][0];\r
+                       a_pt0[1] = (double) 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] = (double) (-world_pti[0] * i_vertex[i].x);// a->m[i*16+6]= -world[i][0]*vertex[i][0];\r
+                       a_pt0[7] = (double) (-world_pti[1] * i_vertex[i].x);// 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] = (double) world_pti[0];// a->m[i*16+11] = world[i][0];\r
+                       a_pt1[4] = (double) 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] = (double) (-world_pti[0] * i_vertex[i].y);// a->m[i*16+14]=-world[i][0]*vertex[i][1];\r
+                       a_pt1[7] = (double) (-world_pti[1] * i_vertex[i].y);// a->m[i*16+15]=-world[i][1]*vertex[i][1];\r
+                       b_array[i * 2 + 0][0] = (double) i_vertex[i].x;// b->m[i*2+0] =vertex[i][0];\r
+                       b_array[i * 2 + 1][0] = (double) i_vertex[i].y;// 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 static int[][] wk_pickFromRaster_world = {// double world[4][2];\r
+       { 100, 100 }, { 100 + 10, 100 }, { 100 + 10, 100 + 10 }, { 100, 100 + 10 } };\r
+\r
+\r
+\r
+       /**\r
+        * @see INyARColorPatt#pickFromRaster\r
+        */\r
+       public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+       {\r
+               NyARMat cpara = this.wk_pickFromRaster_cpara;\r
+               // xdiv2,ydiv2の計算\r
+               int xdiv2, ydiv2;\r
+               int l1, l2;\r
+               int w1, w2;\r
+               // x計算\r
+               w1 = i_vertexs[0].x - i_vertexs[1].x;\r
+               w2 = i_vertexs[0].y - i_vertexs[1].y;\r
+               l1 = (w1 * w1 + w2 * w2);\r
+               w1 = i_vertexs[2].x - i_vertexs[3].x;\r
+               w2 = i_vertexs[2].y - i_vertexs[3].y;\r
+               l2 = (w1 * w1 + w2 * w2);\r
+               if (l2 > l1) {\r
+                       l1 = l2;\r
+               }\r
+               l1 = l1 / 4;\r
+               xdiv2 = this._size.w;\r
+               while (xdiv2 * xdiv2 < l1) {\r
+                       xdiv2 *= 2;\r
+               }\r
+               if (xdiv2 > AR_PATT_SAMPLE_NUM) {\r
+                       xdiv2 = AR_PATT_SAMPLE_NUM;\r
+               }\r
+\r
+               // y計算\r
+               w1 = i_vertexs[1].x - i_vertexs[2].x;\r
+               w2 = i_vertexs[1].y - i_vertexs[2].y;\r
+               l1 = (w1 * w1 + w2 * w2);\r
+               w1 = i_vertexs[3].x - i_vertexs[0].x;\r
+               w2 = i_vertexs[3].y - i_vertexs[0].y;\r
+               l2 = (w1 * w1 + w2 * w2);\r
+               if (l2 > l1) {\r
+                       l1 = l2;\r
+               }\r
+               ydiv2 = this._size.h;\r
+               l1 = l1 / 4;\r
+               while (ydiv2 * ydiv2 < l1) {\r
+                       ydiv2 *= 2;\r
+               }\r
+               if (ydiv2 > AR_PATT_SAMPLE_NUM) {\r
+                       ydiv2 = AR_PATT_SAMPLE_NUM;\r
+               }\r
+\r
+               // cparaの計算\r
+               if (!get_cpara(i_vertexs, cpara)) {\r
+                       return false;\r
+               }\r
+               updateExtpat(image, cpara, xdiv2, ydiv2);\r
+\r
+               return true;\r
+       }\r
+       private int[] __updateExtpat_rgbset;\r
+       private int[] __updateExtpat_xc;\r
+       private int[] __updateExtpat_yc;\r
+       private double[] __updateExtpat_xw;\r
+       private double[] __updateExtpat_yw;\r
+       private int _last_pix_resolution_x=0;\r
+       private int _last_pix_resolution_y=0;\r
+       private void reservWorkBuffers(int i_xdiv,int i_ydiv)\r
+       {\r
+               if(this._last_pix_resolution_x<i_xdiv || this._last_pix_resolution_y<i_ydiv){\r
+                       this.__updateExtpat_xc=new int[i_xdiv*i_ydiv];\r
+                       this.__updateExtpat_yc=new int[i_xdiv*i_ydiv];\r
+                       this.__updateExtpat_xw=new double[i_xdiv];\r
+                       this.__updateExtpat_yw=new double[i_ydiv];\r
+                       this.__updateExtpat_rgbset=new int[i_xdiv*i_ydiv*3];\r
+                       this._last_pix_resolution_x=i_xdiv;\r
+                       this._last_pix_resolution_y=i_ydiv;\r
+               }\r
+               return;\r
+       }\r
+       private static double LT_POS=102.5;\r
+       private static double SQ_SIZE=5.0;\r
+       \r
+       //分割数16未満になると少し遅くなるかも。\r
+       private void updateExtpat(INyARRgbRaster image, NyARMat i_cpara, int i_xdiv2,int i_ydiv2) throws NyARException\r
+       {\r
+\r
+               int i,j;\r
+               int r,g,b;\r
+               //ピクセルリーダーを取得\r
+               final int pat_size_w=this._size.w;\r
+               final int xdiv = i_xdiv2 / pat_size_w;// xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
+               final int ydiv = i_ydiv2 / this._size.h;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+               final int xdiv_x_ydiv = xdiv * ydiv;\r
+               double reciprocal;\r
+               final double[][] para=i_cpara.getArray();\r
+               final double para00=para[0*3+0][0];\r
+               final double para01=para[0*3+1][0];\r
+               final double para02=para[0*3+2][0];\r
+               final double para10=para[1*3+0][0];\r
+               final double para11=para[1*3+1][0];\r
+               final double para12=para[1*3+2][0];\r
+               final double para20=para[2*3+0][0];\r
+               final double para21=para[2*3+1][0];\r
+\r
+               INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+               final int img_width=image.getWidth();\r
+               final int img_height=image.getHeight();\r
+\r
+               //ワークバッファの準備\r
+               reservWorkBuffers(xdiv,ydiv);\r
+               final double[] xw=this.__updateExtpat_xw;\r
+               final double[] yw=this.__updateExtpat_yw;\r
+               final int[] xc=this.__updateExtpat_xc;\r
+               final int[] yc=this.__updateExtpat_yc;\r
+               int[] rgb_set = this.__updateExtpat_rgbset;\r
+\r
+               \r
+               for(int iy=this._size.h-1;iy>=0;iy--){\r
+                       for(int ix=pat_size_w-1;ix>=0;ix--){\r
+                               //xw,ywマップを作成\r
+                               reciprocal= 1.0 / i_xdiv2;\r
+                               for(i=xdiv-1;i>=0;i--){\r
+                                       xw[i]=LT_POS + SQ_SIZE * (ix*xdiv+i + 0.5) * reciprocal;\r
+                               }\r
+                               reciprocal= 1.0 / i_ydiv2;\r
+                               for(i=ydiv-1;i>=0;i--){\r
+                                       yw[i]=LT_POS + SQ_SIZE * (iy*ydiv+i + 0.5) * reciprocal;\r
+                               }\r
+                               //1ピクセルを構成するピクセル座標の集合をxc,yc配列に取得\r
+                               int number_of_pix=0;\r
+                               for(i=ydiv-1;i>=0;i--)\r
+                               {\r
+                                       final double para01_x_yw_para02=para01 * yw[i] + para02;\r
+                                       final double para11_x_yw_para12=para11 * yw[i] + para12;\r
+                                       final double para12_x_yw_para22=para21 * yw[i]+ 1.0;\r
+                                       for(j=xdiv-1;j>=0;j--){\r
+                                                       \r
+                                               final double d = para20 * xw[j] + para12_x_yw_para22;\r
+                                               if (d == 0) {\r
+                                                       throw new NyARException();\r
+                                               }\r
+                                               final int xcw= (int) ((para00 * xw[j] + para01_x_yw_para02) / d);\r
+                                               final int ycw= (int) ((para10 * xw[j] + para11_x_yw_para12) / d);\r
+                                               if(xcw<0 || xcw>=img_width || ycw<0 ||ycw>=img_height){\r
+                                                       continue;\r
+                                               }\r
+                                               xc[number_of_pix] =xcw;\r
+                                               yc[number_of_pix] =ycw;\r
+                                               number_of_pix++;\r
+                                       }\r
+                               }\r
+                               //1ピクセル分の配列を取得\r
+                               reader.getPixelSet(xc,yc,number_of_pix, rgb_set);\r
+                               r=g=b=0;\r
+                               for(i=number_of_pix*3-1;i>=0;i-=3){\r
+                                       r += rgb_set[i-2];// R\r
+                                       g += rgb_set[i-1];// G\r
+                                       b += rgb_set[i];// B\r
+                               }\r
+                               //1ピクセル確定\r
+                               this._patdata[iy*pat_size_w+ix]=(((r / xdiv_x_ydiv)&0xff)<<16)|(((g / xdiv_x_ydiv)&0xff)<<8)|(((b / xdiv_x_ydiv)&0xff));\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_Perspective.java b/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_Perspective.java
new file mode 100644 (file)
index 0000000..e0459a9
--- /dev/null
@@ -0,0 +1,218 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+\r
+\r
+/**\r
+ * 遠近法を使ったパースペクティブ補正をかけて、ラスタ上の四角形から\r
+ * 任意解像度の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_Perspective implements INyARColorPatt\r
+{\r
+       protected int[] _patdata;\r
+       protected NyARIntPoint2d _pickup_lt=new NyARIntPoint2d();       \r
+       protected NyARIntSize _pickup_wh=new NyARIntSize();     \r
+       protected int _resolution;\r
+       protected NyARIntSize _size;\r
+       protected NyARPerspectiveParamGenerator _perspective_gen;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+       private static final int LOCAL_LT=1;\r
+       private static final int BUFFER_FORMAT=NyARBufferType.INT1D_X8R8G8B8_32;\r
+       \r
+       private void initializeInstance(int i_width, int i_height,int i_point_per_pix)\r
+       {\r
+               assert i_width>2 && i_height>2;\r
+               this._size=new NyARIntSize(i_width,i_height);\r
+               this._patdata = new int[i_height*i_width];\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+               return;         \r
+       }\r
+       /**\r
+        * コンストラクタです。サンプリングサイズを指定して、\r
+        * @param i_width\r
+        * 取得画像の解像度幅\r
+        * @param i_height\r
+        * 取得画像の解像度高さ\r
+        * @param i_point_per_pix\r
+        * 1ピクセルあたりの縦横サンプリング数。2なら2x2=4ポイントをサンプリングする。\r
+        */\r
+       public NyARColorPatt_Perspective(int i_width, int i_height,int i_point_per_pix)\r
+       {\r
+               initializeInstance(i_width,i_height,i_point_per_pix);\r
+               setEdgeSize(0,0,i_point_per_pix);\r
+               return;\r
+       }\r
+       /**\r
+        * 例えば、64\r
+        * @param i_width\r
+        * 取得画像の解像度幅\r
+        * @param i_height\r
+        * 取得画像の解像度高さ\r
+        * @param i_edge_percentage\r
+        * エッジ幅の割合(ARToolKit標準と同じなら、25)\r
+        */\r
+       public NyARColorPatt_Perspective(int i_width, int i_height,int i_point_per_pix,int i_edge_percentage)\r
+       {\r
+               //入力制限\r
+               initializeInstance(i_width,i_height,i_point_per_pix);\r
+               setEdgeSizeByPercent(i_edge_percentage,i_edge_percentage,i_point_per_pix);\r
+               return;\r
+       }       \r
+       /**\r
+        * 矩形領域のエッジサイズを指定します。\r
+        * エッジの計算方法は以下の通りです。\r
+        * 1.マーカ全体を(i_x_edge*2+width)x(i_y_edge*2+height)の解像度でパラメタを計算します。\r
+        * 2.ピクセルの取得開始位置を(i_x_edge/2,i_y_edge/2)へ移動します。\r
+        * 3.開始位置から、width x height個のピクセルを取得します。\r
+        * \r
+        * ARToolKit標準マーカの場合は、width/2,height/2を指定してください。\r
+        * @param i_x_edge\r
+        * @param i_y_edge\r
+        */\r
+       public void setEdgeSize(int i_x_edge,int i_y_edge,int i_resolution)\r
+       {\r
+               assert(i_x_edge>=0);\r
+               assert(i_y_edge>=0);\r
+               //Perspectiveパラメタ計算器を作成\r
+               this._perspective_gen=new NyARPerspectiveParamGenerator_O1(LOCAL_LT,LOCAL_LT);\r
+               //ピックアップ開始位置を計算\r
+               this._pickup_lt.setValue(i_x_edge*i_resolution+LOCAL_LT,i_y_edge*i_resolution+LOCAL_LT);\r
+               this._pickup_wh.setValue((i_x_edge*2+this._size.w)*i_resolution,(i_y_edge*2+this._size.h)*i_resolution);\r
+               this._resolution=i_resolution;  \r
+               return;\r
+       }\r
+       public void setEdgeSizeByPercent(int i_x_percent,int i_y_percent,int i_resolution)\r
+       {\r
+               assert(i_x_percent>=0);\r
+               assert(i_y_percent>=0);\r
+               setEdgeSize(this._size.w*i_x_percent/50,this._size.h*i_y_percent/50,i_resolution);\r
+               return;\r
+       }\r
+\r
+       \r
+       public final int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       public final int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+       public final NyARIntSize getSize()\r
+       {\r
+               return  this._size;\r
+       }\r
+       public final INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._patdata;\r
+       }\r
+       public boolean hasBuffer()\r
+       {\r
+               return this._patdata!=null;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               NyARException.notImplement();\r
+       }\r
+       final public int getBufferType()\r
+       {\r
+               return BUFFER_FORMAT;\r
+       }\r
+       final public boolean isEqualBufferType(int i_type_value)\r
+       {\r
+               return BUFFER_FORMAT==i_type_value;\r
+       }\r
+       private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
+       protected final double[] __pickFromRaster_cpara=new double[8];\r
+       \r
+       /**\r
+        * @see INyARColorPatt#pickFromRaster\r
+        */\r
+       public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+       {\r
+               //遠近法のパラメータを計算\r
+               final double[] cpara = this.__pickFromRaster_cpara;\r
+               if (!this._perspective_gen.getParam(this._pickup_wh,i_vertexs, cpara)) {\r
+                       return false;\r
+               }\r
+               \r
+               final int resolution=this._resolution;\r
+               final int img_x = image.getWidth();\r
+               final int img_y = image.getHeight();\r
+               final int res_pix=resolution*resolution;\r
+\r
+               final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
+\r
+               //ピクセルリーダーを取得\r
+               INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+               int p=0;\r
+               for(int iy=0;iy<this._size.h*resolution;iy+=resolution){\r
+                       //解像度分の点を取る。\r
+                       for(int ix=0;ix<this._size.w*resolution;ix+=resolution){\r
+                               int r,g,b;\r
+                               r=g=b=0;\r
+                               for(int i2y=iy;i2y<iy+resolution;i2y++){\r
+                                       int cy=this._pickup_lt.y+i2y;\r
+                                       for(int i2x=ix;i2x<ix+resolution;i2x++){\r
+                                               //1ピクセルを作成\r
+                                               int cx=this._pickup_lt.x+i2x;\r
+                                               final double d=cpara[6]*cx+cpara[7]*cy+1.0;\r
+                                               int x=(int)((cpara[0]*cx+cpara[1]*cy+cpara[2])/d);\r
+                                               int y=(int)((cpara[3]*cx+cpara[4]*cy+cpara[5])/d);\r
+                                               if(x<0){x=0;}\r
+                                               if(x>=img_x){x=img_x-1;}\r
+                                               if(y<0){y=0;}\r
+                                               if(y>=img_y){y=img_y-1;}\r
+                                               \r
+                                               reader.getPixel(x, y, rgb_tmp);\r
+                                               r+=rgb_tmp[0];\r
+                                               g+=rgb_tmp[1];\r
+                                               b+=rgb_tmp[2];\r
+                                       }\r
+                               }\r
+                               r/=res_pix;\r
+                               g/=res_pix;\r
+                               b/=res_pix;\r
+                               this._patdata[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));\r
+                               p++;\r
+                       }\r
+               }\r
+                       //ピクセル問い合わせ\r
+                       //ピクセルセット\r
+               return true;\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_Perspective_O2.java b/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_Perspective_O2.java
new file mode 100644 (file)
index 0000000..a54fe50
--- /dev/null
@@ -0,0 +1,145 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 遠近法を使ったパースペクティブ補正をかけて、ラスタ上の四角形から\r
+ * 任意解像度の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_Perspective_O2 implements INyARColorPatt\r
+{\r
+       private NyARIntPoint2d _edge=new NyARIntPoint2d();\r
+       protected int[] _patdata;\r
+       protected int _resolution;\r
+       protected NyARIntSize _size;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+       private static final int BUFFER_FORMAT=NyARBufferType.INT1D_X8R8G8B8_32;\r
+       private NyARPerspectiveRasterReader _perspective_reader;\r
+       private void initializeInstance(int i_width, int i_height,int i_point_per_pix,int i_input_raster_type)\r
+       {\r
+               assert i_width>2 && i_height>2;\r
+               this._resolution=i_point_per_pix;       \r
+               this._size=new NyARIntSize(i_width,i_height);\r
+               this._patdata = new int[i_height*i_width];\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+               this._perspective_reader=new NyARPerspectiveRasterReader(i_input_raster_type);\r
+               return;         \r
+       }\r
+       /**\r
+        * コンストラクタです。エッジサイズ0,InputRaster=ANYでインスタンスを作成します。\r
+        * @param i_width\r
+        * 取得画像の解像度幅\r
+        * @param i_height\r
+        * 取得画像の解像度高さ\r
+        * @param i_point_per_pix\r
+        * 1ピクセルあたりの縦横サンプリング数。2なら2x2=4ポイントをサンプリングする。\r
+        */\r
+       public NyARColorPatt_Perspective_O2(int i_width, int i_height,int i_point_per_pix)\r
+       {\r
+               initializeInstance(i_width,i_height,i_point_per_pix,NyARBufferType.NULL_ALLZERO);\r
+               this._edge.setValue(0,0);\r
+               return;\r
+       }\r
+       /**\r
+        * コンストラクタです。エッジサイズ,InputRasterTypeを指定してインスタンスを作成します。\r
+        * @param i_width\r
+        * 取得画像の解像度幅\r
+        * @param i_height\r
+        * 取得画像の解像度高さ\r
+        * @param i_point_per_pix\r
+        * 1ピクセルあたりの解像度\r
+        * @param i_edge_percentage\r
+        * エッジ幅の割合(ARToolKit標準と同じなら、25)\r
+        * @param i_input_raster_type\r
+        * 入力ラスタの種類\r
+        */\r
+       public NyARColorPatt_Perspective_O2(int i_width, int i_height,int i_point_per_pix,int i_edge_percentage,int i_input_raster_type)\r
+       {\r
+               initializeInstance(i_width,i_height,i_point_per_pix,i_input_raster_type);\r
+               this._edge.setValue(i_edge_percentage, i_edge_percentage);\r
+               return;\r
+       }       \r
+       public void setEdgeSizeByPercent(int i_x_percent,int i_y_percent,int i_resolution)\r
+       {\r
+               assert(i_x_percent>=0);\r
+               assert(i_y_percent>=0);\r
+               this._edge.setValue(i_x_percent, i_y_percent);\r
+               this._resolution=i_resolution;\r
+               return;\r
+       }\r
+\r
+       \r
+       public final int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       public final int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+       public final NyARIntSize getSize()\r
+       {\r
+               return  this._size;\r
+       }\r
+       public final INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._patdata;\r
+       }\r
+       public boolean hasBuffer()\r
+       {\r
+               return this._patdata!=null;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               NyARException.notImplement();\r
+       }\r
+       final public int getBufferType()\r
+       {\r
+               return BUFFER_FORMAT;\r
+       }\r
+       final public boolean isEqualBufferType(int i_type_value)\r
+       {\r
+               return BUFFER_FORMAT==i_type_value;\r
+       }\r
+       /**\r
+        * @see INyARColorPatt#pickFromRaster\r
+        */\r
+       public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+       {\r
+               //遠近法のパラメータを計算\r
+               return this._perspective_reader.read4Point(image, i_vertexs,this._edge.x,this._edge.y,this._resolution, this);\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_PseudoAffine.java b/lib/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_PseudoAffine.java
new file mode 100644 (file)
index 0000000..35d3ec9
--- /dev/null
@@ -0,0 +1,183 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+\r
+\r
+/**\r
+ * 疑似アフィン変換を使用して、ラスタ上の四角形から任意解像度\r
+ * の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_PseudoAffine implements INyARColorPatt\r
+{\r
+       private int[] _patdata;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+       private NyARIntSize _size;\r
+       private static final int BUFFER_FORMAT=NyARBufferType.INT1D_X8R8G8B8_32;\r
+               \r
+       public final int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       \r
+       public final int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+       \r
+       public final NyARIntSize getSize()\r
+       {\r
+               return  this._size;\r
+       }\r
+       public final INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._patdata;\r
+       }\r
+       public boolean hasBuffer()\r
+       {\r
+               return this._patdata!=null;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               NyARException.notImplement();\r
+       }\r
+       final public int getBufferType()\r
+       {\r
+               return BUFFER_FORMAT;\r
+       }\r
+       final public boolean isEqualBufferType(int i_type_value)\r
+       {\r
+               return BUFFER_FORMAT==i_type_value;\r
+       }       \r
+       NyARDoubleMatrix44 _invmat=new NyARDoubleMatrix44();\r
+       /**\r
+        * @param i_width\r
+        * @param i_height\r
+        */\r
+       public NyARColorPatt_PseudoAffine(int i_width, int i_height)\r
+       {               \r
+               this._size=new NyARIntSize(i_width,i_height);\r
+               this._patdata = new int[i_height*i_width];\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+               //疑似アフィン変換のパラメタマトリクスを計算します。\r
+               //長方形から計算すると、有効要素がm00,m01,m02,m03,m10,m11,m20,m23,m30になります。\r
+               final NyARDoubleMatrix44 mat=this._invmat;\r
+               mat.m00=0;\r
+               mat.m01=0;\r
+               mat.m02=0;\r
+               mat.m03=1.0;\r
+               mat.m10=0;\r
+               mat.m11=i_width-1;\r
+               mat.m12=0;\r
+               mat.m13=1.0;\r
+               mat.m20=(i_width-1)*(i_height-1);\r
+               mat.m21=i_width-1;\r
+               mat.m22=i_height-1;\r
+               mat.m23=1.0;\r
+               mat.m30=0;\r
+               mat.m31=0;\r
+               mat.m32=i_height-1;\r
+               mat.m33=1.0;\r
+               mat.inverse(mat);\r
+               return;\r
+       }       \r
+\r
+       /**\r
+        * 変換行列と頂点座標から、パラメータを計算\r
+        * o_paramの[0..3]にはXのパラメタ、[4..7]にはYのパラメタを格納する。\r
+        * @param i_vertex\r
+        * @param pa\r
+        * @param pb\r
+        */\r
+       private void calcPara(NyARIntPoint2d[] i_vertex,double[] o_cparam)\r
+       {\r
+               final NyARDoubleMatrix44 invmat=this._invmat;\r
+               double v1,v2,v4;\r
+               //変換行列とベクトルの積から、変換パラメタを計算する。\r
+               v1=i_vertex[0].x;\r
+               v2=i_vertex[1].x;\r
+               v4=i_vertex[3].x;\r
+               \r
+               o_cparam[0]=invmat.m00*v1+invmat.m01*v2+invmat.m02*i_vertex[2].x+invmat.m03*v4;\r
+               o_cparam[1]=invmat.m10*v1+invmat.m11*v2;//m12,m13は0;\r
+               o_cparam[2]=invmat.m20*v1+invmat.m23*v4;//m21,m22は0;\r
+               o_cparam[3]=v1;//m30は1.0で、m31,m32,m33は0\r
+               \r
+               v1=i_vertex[0].y;\r
+               v2=i_vertex[1].y;\r
+               v4=i_vertex[3].y;\r
+\r
+               o_cparam[4]=invmat.m00*v1+invmat.m01*v2+invmat.m02*i_vertex[2].y+invmat.m03*v4;\r
+               o_cparam[5]=invmat.m10*v1+invmat.m11*v2;//m12,m13は0;\r
+               o_cparam[6]=invmat.m20*v1+invmat.m23*v4;//m21,m22は0;\r
+               o_cparam[7]=v1;//m30は1.0で、m31,m32,m33は0\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * 疑似アフィン変換の変換パラメタ\r
+        */\r
+       private double[] _convparam=new double[8];\r
+       \r
+       /**\r
+        * @see INyARColorPatt#pickFromRaster\r
+        */\r
+       public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+       {\r
+               final double[] conv_param=this._convparam;\r
+           int rx2,ry2;\r
+               rx2=this._size.w;\r
+               ry2=this._size.h;\r
+               int[] rgb_tmp=new int[3];\r
+\r
+               INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+               // 変形先領域の頂点を取得\r
+\r
+               //変換行列から現在の座標系への変換パラメタを作成\r
+               calcPara(i_vertexs,conv_param);// 変換パラメータを求める\r
+               for(int y=0;y<ry2;y++){\r
+                       for(int x=0;x<rx2;x++){\r
+                               final int ttx=(int)((conv_param[0]*x*y+conv_param[1]*x+conv_param[2]*y+conv_param[3])+0.5);\r
+                               final int tty=(int)((conv_param[4]*x*y+conv_param[5]*x+conv_param[6]*y+conv_param[7])+0.5);\r
+                               reader.getPixel((int)ttx,(int)tty,rgb_tmp);\r
+                               this._patdata[x+y*rx2]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|rgb_tmp[2];                             \r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/INyARRaster.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/INyARRaster.java
new file mode 100644 (file)
index 0000000..da28172
--- /dev/null
@@ -0,0 +1,71 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+\r
+public interface INyARRaster\r
+{\r
+       public int getWidth();\r
+       public int getHeight();\r
+       public NyARIntSize getSize();\r
+       /**\r
+        * バッファオブジェクトを返します。\r
+        * @return\r
+        */\r
+       public Object getBuffer();\r
+       /**\r
+        * バッファオブジェクトのタイプを返します。\r
+        * @return\r
+        */\r
+       public int getBufferType();\r
+       /**\r
+        * バッファのタイプがi_type_valueであるか、チェックします。\r
+        * この値は、NyARBufferTypeに定義された定数値です。\r
+        * @param i_type_value\r
+        * @return\r
+        */\r
+       public boolean isEqualBufferType(int i_type_value);\r
+       /**\r
+        * getBufferがオブジェクトを返せるかの真偽値です。\r
+        * @return\r
+        */\r
+       public boolean hasBuffer();\r
+       /**\r
+        * i_ref_bufをラップします。できる限り整合性チェックを行います。\r
+        * バッファの再ラッピングが可能な関数のみ、この関数を実装してください。\r
+        * @param i_ref_buf\r
+        */\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException;\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARBinRaster.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARBinRaster.java
new file mode 100644 (file)
index 0000000..8166029
--- /dev/null
@@ -0,0 +1,105 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+\r
+public class NyARBinRaster extends NyARRaster_BasicClass\r
+{\r
+       protected Object _buf;\r
+       /**\r
+        * バッファオブジェクトがアタッチされていればtrue\r
+        */\r
+       protected boolean _is_attached_buffer;\r
+       /**\r
+        * \r
+        * @param i_width\r
+        * @param i_height\r
+        * @param i_raster_type\r
+        * NyARBufferTypeに定義された定数値を指定してください。\r
+        * @param i_is_alloc\r
+        * @throws NyARException\r
+        */\r
+       public NyARBinRaster(int i_width, int i_height,int i_raster_type,boolean i_is_alloc) throws NyARException\r
+       {\r
+               super(i_width,i_height,i_raster_type);\r
+               if(!initInstance(this._size,i_raster_type,i_is_alloc)){\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public NyARBinRaster(int i_width, int i_height,boolean i_is_alloc) throws NyARException\r
+       {\r
+               super(i_width,i_height,NyARBufferType.INT1D_BIN_8);\r
+               if(!initInstance(this._size,NyARBufferType.INT1D_BIN_8,i_is_alloc)){\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public NyARBinRaster(int i_width, int i_height) throws NyARException\r
+       {\r
+               super(i_width,i_height,NyARBufferType.INT1D_BIN_8);\r
+               if(!initInstance(this._size,NyARBufferType.INT1D_BIN_8,true)){\r
+                       throw new NyARException();\r
+               }\r
+       }       \r
+       protected boolean initInstance(NyARIntSize i_size,int i_buf_type,boolean i_is_alloc)\r
+       {\r
+               switch(i_buf_type)\r
+               {\r
+                       case NyARBufferType.INT1D_BIN_8:\r
+                               this._buf = i_is_alloc?new int[i_size.w*i_size.h]:null;\r
+                               break;\r
+                       default:\r
+                               return false;\r
+               }\r
+               this._is_attached_buffer=i_is_alloc;\r
+               return true;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._buf;\r
+       }\r
+       /**\r
+        * インスタンスがバッファを所有するかを返します。\r
+        * コンストラクタでi_is_allocをfalseにしてラスタを作成した場合、\r
+        * バッファにアクセスするまえに、バッファの有無をこの関数でチェックしてください。\r
+        * @return\r
+        */     \r
+       public boolean hasBuffer()\r
+       {\r
+               return this._buf!=null;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf)\r
+       {\r
+               assert(!this._is_attached_buffer);//バッファがアタッチされていたら機能しない。\r
+               this._buf=i_ref_buf;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARGrayscaleRaster.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARGrayscaleRaster.java
new file mode 100644 (file)
index 0000000..2c69e79
--- /dev/null
@@ -0,0 +1,232 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 1枚のグレースケール画像を定義するクラスです。画像データは内部保持/外部保持が選択可能です。\r
+ */\r
+public class NyARGrayscaleRaster extends NyARRaster_BasicClass\r
+{\r
+       private IdoFilterImpl _impl;\r
+       protected Object _buf;\r
+       /**\r
+        * バッファオブジェクトがアタッチされていればtrue\r
+        */\r
+       protected boolean _is_attached_buffer;\r
+\r
+       public NyARGrayscaleRaster(int i_width, int i_height) throws NyARException\r
+       {\r
+               super(i_width, i_height, NyARBufferType.INT1D_GRAY_8);\r
+               if (!initInstance(this._size, NyARBufferType.INT1D_GRAY_8, true))\r
+               {\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       /**\r
+        * \r
+        * @param i_width\r
+        * @param i_height\r
+        * @param i_is_alloc\r
+        * 画像バッファを内部保持にするかのフラグ値。trueなら、インスタンスがバッファを確保します。falseなら、\r
+        * 画像バッファは外部参照になり、wrapBuffer関数を使用できます。\r
+        * @throws NyARException\r
+        */\r
+       public NyARGrayscaleRaster(int i_width, int i_height, boolean i_is_alloc)\r
+                       throws NyARException\r
+       {\r
+               super(i_width, i_height, NyARBufferType.INT1D_GRAY_8);\r
+               if (!initInstance(this._size, NyARBufferType.INT1D_GRAY_8, i_is_alloc))\r
+               {\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @param i_width\r
+        * @param i_height\r
+        * @param i_raster_type\r
+        *            NyARBufferTypeに定義された定数値を指定してください。\r
+        * @param i_is_alloc\r
+        * @throws NyARException\r
+        */\r
+       public NyARGrayscaleRaster(int i_width, int i_height, int i_raster_type,boolean i_is_alloc) throws NyARException\r
+       {\r
+               super(i_width, i_height, i_raster_type);\r
+               if (!initInstance(this._size, i_raster_type, i_is_alloc)) {\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * このクラスの初期化シーケンスです。コンストラクタから呼び出します。\r
+        * @param i_size\r
+        * @param i_buf_type\r
+        * @param i_is_alloc\r
+        * @return\r
+        */\r
+       protected boolean initInstance(NyARIntSize i_size, int i_buf_type,boolean i_is_alloc)\r
+       {\r
+               switch (i_buf_type) {\r
+               case NyARBufferType.INT1D_GRAY_8:\r
+                       this._impl=new IdoFilterImpl_INT1D_GRAY_8();\r
+                       this._buf = i_is_alloc ? new int[i_size.w * i_size.h] : null;\r
+                       break;\r
+               default:\r
+                       return false;\r
+               }\r
+               this._is_attached_buffer = i_is_alloc;\r
+               return true;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._buf;\r
+       }\r
+\r
+       /**\r
+        * インスタンスがバッファを所有するかを返します。 コンストラクタでi_is_allocをfalseにしてラスタを作成した場合、\r
+        * バッファにアクセスするまえに、バッファの有無をこの関数でチェックしてください。\r
+        * @return\r
+        */\r
+       public boolean hasBuffer()\r
+       {\r
+               return this._buf != null;\r
+       }\r
+       /**\r
+        * 追加機能-無し。\r
+        * @throws NyARException \r
+        */\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               assert (!this._is_attached_buffer);// バッファがアタッチされていたら機能しない。\r
+               this._buf = i_ref_buf;\r
+       }\r
+\r
+       /**\r
+        * 指定した数値でラスタを埋めます。\r
+        * この関数は高速化していません。\r
+        * @param i_value\r
+        */\r
+       public void fill(int i_value)\r
+       {\r
+               assert (this.isEqualBufferType(this.getBufferType()));\r
+               this._impl.fill(this,i_value);\r
+       }\r
+\r
+       /**\r
+        * ラスタの異解像度間コピーをします。\r
+        * @param i_input\r
+        * 入力ラスタ\r
+        * @param i_top\r
+        * 入力ラスタの左上点を指定します。\r
+        * @param i_left\r
+        * 入力ラスタの左上点を指定します。\r
+        * @param i_skip\r
+        * skip値。1なら等倍、2なら1/2倍、3なら1/3倍の偏重の画像を出力します。\r
+        * @param o_output\r
+        * 出力先ラスタ。このラスタの解像度は、w=(i_input.w-i_left)/i_skip,h=(i_input.h-i_height)/i_skipを満たす必要があります。\r
+        * 出力先ラスタと入力ラスタのバッファタイプは、同じである必要があります。\r
+        */\r
+       public void copyTo(int i_left,int i_top,int i_skip, NyARGrayscaleRaster o_output)\r
+       {\r
+               assert (this.getSize().isInnerSize(i_left + o_output.getWidth() * i_skip, i_top+ o_output.getHeight() * i_skip));               \r
+               assert (this.isEqualBufferType(o_output.getBufferType()));\r
+               this._impl.copyTo(this, i_left, i_top, i_skip, o_output);\r
+               return;\r
+       }\r
+       ////////////////////////////////////////////////////////////////////////////////\r
+       //ここからラスタドライバ\r
+       \r
+       interface IdoFilterImpl\r
+       {\r
+               public void fill(NyARGrayscaleRaster i_raster,int i_value);\r
+               public void copyTo(NyARGrayscaleRaster i_input, int i_left,int i_top,int i_skip, NyARGrayscaleRaster o_output);\r
+       }\r
+       \r
+       final class IdoFilterImpl_INT1D_GRAY_8 implements IdoFilterImpl\r
+       {\r
+               public void fill(NyARGrayscaleRaster i_raster,int i_value)\r
+               {\r
+                       assert (i_raster._buffer_type == NyARBufferType.INT1D_GRAY_8);\r
+                       int[] buf = (int[]) i_raster._buf;\r
+                       for (int i = i_raster._size.h * i_raster._size.w - 1; i >= 0; i--) {\r
+                               buf[i] = i_value;\r
+                       }                       \r
+               }\r
+\r
+               public void copyTo(NyARGrayscaleRaster i_input, int i_left,int i_top,int i_skip, NyARGrayscaleRaster o_output)\r
+               {\r
+                       assert (i_input.getSize().isInnerSize(i_left + o_output.getWidth() * i_skip, i_top+ o_output.getHeight() * i_skip));            \r
+                       final int[] input = (int[]) i_input.getBuffer();\r
+                       final int[] output = (int[]) o_output.getBuffer();\r
+                       int pt_src, pt_dst;\r
+                       NyARIntSize dest_size = o_output.getSize();\r
+                       NyARIntSize src_size = i_input.getSize();\r
+                       int skip_src_y = (src_size.w - dest_size.w * i_skip) + src_size.w * (i_skip - 1);\r
+                       final int pix_count = dest_size.w;\r
+                       final int pix_mod_part = pix_count - (pix_count % 8);\r
+                       // 左上から1行づつ走査していく\r
+                       pt_dst = 0;\r
+                       pt_src = (i_top * src_size.w + i_left);\r
+                       for (int y = dest_size.h - 1; y >= 0; y -= 1) {\r
+                               int x;\r
+                               for (x = pix_count - 1; x >= pix_mod_part; x--) {\r
+                                       output[pt_dst++] = input[pt_src];\r
+                                       pt_src += i_skip;\r
+                               }\r
+                               for (; x >= 0; x -= 8) {\r
+                                       output[pt_dst++] = input[pt_src];\r
+                                       pt_src += i_skip;\r
+                                       output[pt_dst++] = input[pt_src];\r
+                                       pt_src += i_skip;\r
+                                       output[pt_dst++] = input[pt_src];\r
+                                       pt_src += i_skip;\r
+                                       output[pt_dst++] = input[pt_src];\r
+                                       pt_src += i_skip;\r
+                                       output[pt_dst++] = input[pt_src];\r
+                                       pt_src += i_skip;\r
+                                       output[pt_dst++] = input[pt_src];\r
+                                       pt_src += i_skip;\r
+                                       output[pt_dst++] = input[pt_src];\r
+                                       pt_src += i_skip;\r
+                                       output[pt_dst++] = input[pt_src];\r
+                                       pt_src += i_skip;\r
+                               }\r
+                               // スキップ\r
+                               pt_src += skip_src_y;\r
+                       }\r
+                       return;\r
+               }\r
+       }       \r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARHsvRaster.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARHsvRaster.java
new file mode 100644 (file)
index 0000000..90e06f6
--- /dev/null
@@ -0,0 +1,59 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public final class NyARHsvRaster extends NyARRaster_BasicClass\r
+{\r
+\r
+       private int[] _ref_buf;\r
+       \r
+       public NyARHsvRaster(int i_width, int i_height)\r
+       {\r
+               //このクラスは外部参照バッファ/形式多重化が使えない簡易実装です。\r
+               super(i_width,i_height,NyARBufferType.INT1D_X7H9S8V8_32);\r
+               this._ref_buf = new int[i_height*i_width];\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._ref_buf;\r
+       }\r
+       public boolean hasBuffer()\r
+       {\r
+               return true;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               NyARException.notImplement();\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARRaster.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARRaster.java
new file mode 100644 (file)
index 0000000..39d1728
--- /dev/null
@@ -0,0 +1,106 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**このクラスは、単機能のNyARRasterです。\r
+ *\r
+ */\r
+public class NyARRaster extends NyARRaster_BasicClass\r
+{\r
+       protected Object _buf;\r
+       /**\r
+        * バッファオブジェクトがアタッチされていればtrue\r
+        */\r
+       protected boolean _is_attached_buffer;\r
+       /**\r
+        * 指定したバッファタイプのラスタを作成します。\r
+        * @param i_width\r
+        * @param i_height\r
+        * @param i_buffer_type\r
+        * NyARBufferTypeに定義された定数値を指定してください。\r
+        * @param i_is_alloc\r
+        * @throws NyARException\r
+        */\r
+       public NyARRaster(int i_width, int i_height,int i_buffer_type,boolean i_is_alloc) throws NyARException\r
+       {\r
+               super(i_width,i_height,i_buffer_type);\r
+               if(!initInstance(this._size,i_buffer_type,i_is_alloc)){\r
+                       throw new NyARException();\r
+               }\r
+               return;\r
+       }       \r
+\r
+       public NyARRaster(int i_width, int i_height,int i_buffer_type) throws NyARException\r
+       {\r
+               super(i_width,i_height,i_buffer_type);\r
+               if(!initInstance(this._size,i_buffer_type,true)){\r
+                       throw new NyARException();\r
+               }\r
+               return;\r
+       }       \r
+       protected boolean initInstance(NyARIntSize i_size,int i_buf_type,boolean i_is_alloc)\r
+       {\r
+               switch(i_buf_type)\r
+               {\r
+                       case NyARBufferType.INT1D:\r
+                       case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                               this._buf=i_is_alloc?new int[i_size.w*i_size.h]:null;\r
+                               break;\r
+                               \r
+                       default:\r
+                               return false;\r
+               }\r
+               this._is_attached_buffer=i_is_alloc;\r
+               return true;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._buf;\r
+       }\r
+       /**\r
+        * インスタンスがバッファを所有するかを返します。\r
+        * コンストラクタでi_is_allocをfalseにしてラスタを作成した場合、\r
+        * バッファにアクセスするまえに、バッファの有無をこの関数でチェックしてください。\r
+        * @return\r
+        */     \r
+       public boolean hasBuffer()\r
+       {\r
+               return this._buf!=null;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               assert(!this._is_attached_buffer);//バッファがアタッチされていたら機能しない。\r
+               this._buf=i_ref_buf;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARRaster_BasicClass.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/NyARRaster_BasicClass.java
new file mode 100644 (file)
index 0000000..26a6258
--- /dev/null
@@ -0,0 +1,67 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public abstract class NyARRaster_BasicClass implements INyARRaster\r
+{\r
+       protected NyARIntSize _size;\r
+       protected int _buffer_type;\r
+       protected NyARRaster_BasicClass(int i_width,int i_height,int i_buffer_type)\r
+       {\r
+               this._size= new NyARIntSize(i_width,i_height);\r
+               this._buffer_type=i_buffer_type;\r
+       }\r
+\r
+       final public int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+\r
+       final public int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+\r
+       final public NyARIntSize getSize()\r
+       {\r
+               return this._size;\r
+       }\r
+       final public int getBufferType()\r
+       {\r
+               return _buffer_type;\r
+       }\r
+       final public boolean isEqualBufferType(int i_type_value)\r
+       {\r
+               return this._buffer_type==i_type_value;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/INyARRgbRaster.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/INyARRgbRaster.java
new file mode 100644 (file)
index 0000000..35f6954
--- /dev/null
@@ -0,0 +1,44 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+/**\r
+ * 8bitRGBを表現できるラスタ\r
+ * \r
+ */\r
+public interface INyARRgbRaster extends INyARRaster\r
+{\r
+       public INyARRgbPixelReader getRgbPixelReader() throws NyARException;\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster.java
new file mode 100644 (file)
index 0000000..73aff17
--- /dev/null
@@ -0,0 +1,108 @@
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+\r
+public class NyARRgbRaster extends NyARRgbRaster_BasicClass\r
+{\r
+       protected Object _buf;\r
+       protected INyARRgbPixelReader _reader;\r
+       /**\r
+        * バッファオブジェクトがアタッチされていればtrue\r
+        */\r
+       protected boolean _is_attached_buffer;\r
+       \r
+       /**\r
+        * \r
+        * @param i_width\r
+        * @param i_height\r
+        * @param i_raster_type\r
+        * NyARBufferTypeに定義された定数値を指定してください。\r
+        * @param i_is_alloc\r
+        * @throws NyARException\r
+        */\r
+       public NyARRgbRaster(int i_width, int i_height,int i_raster_type,boolean i_is_alloc) throws NyARException\r
+       {\r
+               super(i_width,i_height,i_raster_type);\r
+               if(!initInstance(this._size,i_raster_type,i_is_alloc)){\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       /**\r
+        * \r
+        * @param i_width\r
+        * @param i_height\r
+        * @param i_raster_type\r
+        * NyARBufferTypeに定義された定数値を指定してください。\r
+        * @throws NyARException\r
+        */\r
+       public NyARRgbRaster(int i_width, int i_height,int i_raster_type) throws NyARException\r
+       {\r
+               super(i_width,i_height,i_raster_type);\r
+               if(!initInstance(this._size,i_raster_type,true)){\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       /**\r
+        * Readerとbufferを初期化する関数です。コンストラクタから呼び出します。\r
+        * 継承クラスでこの関数を拡張することで、対応するバッファタイプの種類を増やせます。\r
+        * @param i_size\r
+        * @param i_raster_type\r
+        * @param i_is_alloc\r
+        * @return\r
+        */\r
+       protected boolean initInstance(NyARIntSize i_size,int i_raster_type,boolean i_is_alloc)\r
+       {\r
+               switch(i_raster_type)\r
+               {\r
+                       case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                               this._buf=i_is_alloc?new int[i_size.w*i_size.h]:null;\r
+                               this._reader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32((int[])this._buf,i_size);\r
+                               break;\r
+                       case NyARBufferType.BYTE1D_B8G8R8X8_32:\r
+                               this._buf=i_is_alloc?new byte[i_size.w*i_size.h*4]:null;\r
+                               this._reader=new NyARRgbPixelReader_BYTE1D_B8G8R8X8_32((byte[])this._buf,i_size);\r
+                               break;\r
+                       case NyARBufferType.BYTE1D_R8G8B8_24:\r
+                               this._buf=i_is_alloc?new byte[i_size.w*i_size.h*3]:null;\r
+                               this._reader=new NyARRgbPixelReader_BYTE1D_R8G8B8_24((byte[])this._buf,i_size);\r
+                               break;\r
+                       case NyARBufferType.BYTE1D_B8G8R8_24:\r
+                               this._buf=i_is_alloc?new byte[i_size.w*i_size.h*3]:null;\r
+                               this._reader=new NyARRgbPixelReader_BYTE1D_B8G8R8_24((byte[])this._buf,i_size);\r
+                               break;\r
+                       case NyARBufferType.BYTE1D_X8R8G8B8_32:\r
+                               this._buf=i_is_alloc?new byte[i_size.w*i_size.h*4]:null;\r
+                               this._reader=new NyARRgbPixelReader_BYTE1D_X8R8G8B8_32((byte[])this._buf,i_size);\r
+                               break;\r
+                       case NyARBufferType.WORD1D_R5G6B5_16LE:\r
+                               this._buf=i_is_alloc?new short[i_size.w*i_size.h]:null;\r
+                               this._reader=new NyARRgbPixelReader_WORD1D_R5G6B5_16LE((short[])this._buf,i_size);\r
+                               break;\r
+                       default:\r
+                               return false;\r
+               }\r
+               this._is_attached_buffer=i_is_alloc;\r
+               return true;\r
+       }\r
+       public INyARRgbPixelReader getRgbPixelReader() throws NyARException\r
+       {\r
+               return this._reader;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return this._buf;\r
+       }\r
+       public boolean hasBuffer()\r
+       {\r
+               return this._buf!=null;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               assert(!this._is_attached_buffer);//バッファがアタッチされていたら機能しない。\r
+               this._buf=i_ref_buf;\r
+               //ピクセルリーダーの参照バッファを切り替える。\r
+               this._reader.switchBuffer(i_ref_buf);\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_BGRA.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_BGRA.java
new file mode 100644 (file)
index 0000000..d29e2dd
--- /dev/null
@@ -0,0 +1,48 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+\r
+public class NyARRgbRaster_BGRA extends NyARRgbRaster\r
+{\r
+       public NyARRgbRaster_BGRA(int i_width, int i_height,boolean i_is_alloc) throws NyARException\r
+       {\r
+               super(i_width,i_height,NyARBufferType.BYTE1D_B8G8R8X8_32,i_is_alloc);\r
+       }       \r
+       public NyARRgbRaster_BGRA(int i_width, int i_height) throws NyARException\r
+       {\r
+               super(i_width,i_height,NyARBufferType.BYTE1D_B8G8R8X8_32);\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_BasicClass.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_BasicClass.java
new file mode 100644 (file)
index 0000000..da164e3
--- /dev/null
@@ -0,0 +1,95 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARRgbPixelReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * NyARRasterインタフェイスの基本関数/メンバを実装したクラス\r
+ * \r
+ * \r
+ */\r
+public abstract class NyARRgbRaster_BasicClass implements INyARRgbRaster\r
+{\r
+       final protected NyARIntSize _size;\r
+       private int _buffer_type;\r
+       protected NyARRgbRaster_BasicClass(int i_width,int i_height,int i_buffer_type)\r
+       {\r
+               this._size= new NyARIntSize(i_width,i_height);\r
+               this._buffer_type=i_buffer_type;\r
+       }\r
+       final public int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       final public int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+\r
+       final public NyARIntSize getSize()\r
+       {\r
+               return this._size;\r
+       }\r
+       final public int getBufferType()\r
+       {\r
+               return _buffer_type;\r
+       }\r
+       final public boolean isEqualBufferType(int i_type_value)\r
+       {\r
+               return this._buffer_type==i_type_value;\r
+       }\r
+       /**\r
+        * ラスタのコピーを実行します。\r
+        * この関数は暫定です。低速なので注意してください。\r
+        * @param i_input\r
+        * @param o_output\r
+        * @throws NyARException \r
+        */\r
+       public static void copy(INyARRgbRaster i_input,INyARRgbRaster o_output) throws NyARException\r
+       {\r
+               assert(i_input.getSize().isEqualSize(o_output.getSize()));\r
+               int width=i_input.getWidth();\r
+               int height=i_input.getHeight();\r
+               int[] rgb=new int[3];\r
+               INyARRgbPixelReader inr=i_input.getRgbPixelReader();\r
+               INyARRgbPixelReader outr=o_output.getRgbPixelReader();\r
+               for(int i=height-1;i>=0;i--){\r
+                       for(int i2=width-1;i2>=0;i2--){\r
+                               inr.getPixel(i2,i,rgb);\r
+                               outr.setPixel(i2,i,rgb);\r
+                       }\r
+               }\r
+       }\r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_Blank.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_Blank.java
new file mode 100644 (file)
index 0000000..a75c2a9
--- /dev/null
@@ -0,0 +1,104 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARRgbPixelReader;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/*\r
+ * 真っ黒の矩形を定義する。\r
+ * \r
+ */\r
+public class NyARRgbRaster_Blank extends NyARRgbRaster_BasicClass\r
+{\r
+       private class PixelReader implements INyARRgbPixelReader\r
+       {\r
+               public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+               {\r
+                       o_rgb[0] = 0;// R\r
+                       o_rgb[1] = 0;// G\r
+                       o_rgb[2] = 0;// B\r
+                       return;\r
+               }\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
+               public void setPixel(int i_x, int i_y, int i_r,int i_g,int i_b) throws NyARException\r
+               {\r
+                       NyARException.notImplement();                   \r
+               }\r
+               public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+               {\r
+                       NyARException.notImplement();           \r
+               }\r
+               public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+               {\r
+                       NyARException.notImplement();           \r
+               }\r
+               public void switchBuffer(Object i_ref_buffer) throws NyARException\r
+               {\r
+                       NyARException.notImplement();           \r
+               }               \r
+               \r
+       }\r
+\r
+       private INyARRgbPixelReader _reader;\r
+       \r
+       public NyARRgbRaster_Blank(int i_width, int i_height)\r
+       {\r
+               super(i_width,i_height,NyARBufferType.NULL_ALLZERO);\r
+               this._reader = new PixelReader();\r
+               return;\r
+       }\r
+       public INyARRgbPixelReader getRgbPixelReader() throws NyARException\r
+       {\r
+               return this._reader;\r
+       }\r
+       public Object getBuffer()\r
+       {\r
+               return null;\r
+       }\r
+       public boolean hasBuffer()\r
+       {\r
+               return false;\r
+       }\r
+       public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               NyARException.notImplement();\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_RGB.java b/lib/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_RGB.java
new file mode 100644 (file)
index 0000000..3815ad6
--- /dev/null
@@ -0,0 +1,49 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+\r
+public class NyARRgbRaster_RGB extends NyARRgbRaster\r
+{\r
+       public NyARRgbRaster_RGB(int i_width, int i_height,boolean i_is_alloc) throws NyARException\r
+       {\r
+               super(i_width,i_height,NyARBufferType.BYTE1D_R8G8B8_24,i_is_alloc);\r
+       }\r
+\r
+       public NyARRgbRaster_RGB(int i_width, int i_height) throws NyARException\r
+       {\r
+               super(i_width,i_height,NyARBufferType.BYTE1D_R8G8B8_24);\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/INyARRasterFilter.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/INyARRasterFilter.java
new file mode 100644 (file)
index 0000000..c2d7900
--- /dev/null
@@ -0,0 +1,33 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+public interface INyARRasterFilter\r
+{\r
+       public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException;\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_CustomToneTable.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_CustomToneTable.java
new file mode 100644 (file)
index 0000000..b17ea32
--- /dev/null
@@ -0,0 +1,78 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * 色調テーブルを使用したフィルターです。\r
+ * 色調テーブルクラスのベースクラスです。\r
+ */\r
+public class NyARRasterFilter_CustomToneTable implements INyARRasterFilter\r
+{\r
+       protected final int[] table=new int[256];\r
+       private IdoFilterImpl _dofilterimpl;\r
+       protected NyARRasterFilter_CustomToneTable(int i_raster_type) throws NyARException\r
+       {\r
+               switch (i_raster_type) {\r
+               case NyARBufferType.INT1D_GRAY_8:\r
+                       this._dofilterimpl=new IdoFilterImpl_INT1D_GRAY_8();\r
+                       break;\r
+               default:\r
+                       throw new NyARException();\r
+               }\r
+               this._dofilterimpl._table_ref=this.table;\r
+       }\r
+       public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+               this._dofilterimpl.doFilter(i_input,i_output,i_input.getSize());\r
+       }\r
+       \r
+       private abstract class IdoFilterImpl\r
+       {\r
+               public int[] _table_ref;\r
+               public abstract void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException;\r
+               \r
+       }\r
+       private class IdoFilterImpl_INT1D_GRAY_8 extends IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       assert(         i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       \r
+                       int[] out_buf = (int[]) i_output.getBuffer();\r
+                       int[] in_buf = (int[]) i_input.getBuffer();\r
+                       for(int i=i_size.h*i_size.w-1;i>=0;i--)\r
+                       {\r
+                               out_buf[i]=this._table_ref[in_buf[i]];\r
+                       }\r
+                       return;\r
+               }\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_EqualizeHist.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_EqualizeHist.java
new file mode 100644 (file)
index 0000000..9a9623a
--- /dev/null
@@ -0,0 +1,61 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.analyzer.raster.NyARRasterAnalyzer_Histogram;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistogram;\r
+/**\r
+ * ヒストグラムを平滑化します。\r
+ *\r
+ */\r
+public class NyARRasterFilter_EqualizeHist extends NyARRasterFilter_CustomToneTable\r
+{\r
+       private NyARRasterAnalyzer_Histogram _hist_analyzer;\r
+       private NyARHistogram _histogram=new NyARHistogram(256);\r
+       public NyARRasterFilter_EqualizeHist(int i_raster_type,int i_sample_interval) throws NyARException\r
+       {\r
+               super(i_raster_type);\r
+               this._hist_analyzer=new NyARRasterAnalyzer_Histogram(i_raster_type,i_sample_interval);\r
+       }\r
+       public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+       {\r
+               //ヒストグラムを得る\r
+               NyARHistogram hist=this._histogram;\r
+               this._hist_analyzer.analyzeRaster(i_input,hist);\r
+               //変換テーブルを作成\r
+               int hist_total=this._histogram.total_of_data;\r
+               int min=hist.getMinData();\r
+               int hist_size=this._histogram.length;\r
+               int sum=0;\r
+               for(int i=0;i<hist_size;i++){\r
+                       sum+=hist.data[i];\r
+                       this.table[i]=(int)((sum-min)*(hist_size-1)/((hist_total-min)));\r
+               }\r
+               //変換\r
+               super.doFilter(i_input, i_output);\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_GaussianSmooth.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_GaussianSmooth.java
new file mode 100644 (file)
index 0000000..b152697
--- /dev/null
@@ -0,0 +1,123 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+/**\r
+ * 平滑化フィルタ\r
+ * Gaussianフィルタで画像を平滑化します。\r
+ * カーネルサイズは3x3です。\r
+ */\r
+public class NyARRasterFilter_GaussianSmooth implements INyARRasterFilter\r
+{\r
+       private IdoFilterImpl _do_filter_impl; \r
+       public NyARRasterFilter_GaussianSmooth(int i_raster_type) throws NyARException\r
+       {\r
+               switch (i_raster_type) {\r
+               case NyARBufferType.INT1D_GRAY_8:\r
+                       this._do_filter_impl=new IdoFilterImpl_GRAY_8();\r
+                       break;\r
+               default:\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input!=i_output);\r
+               this._do_filter_impl.doFilter(i_input,i_output,i_input.getSize());\r
+       }\r
+       \r
+       interface IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException;\r
+       }\r
+       class IdoFilterImpl_GRAY_8 implements IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       assert (i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       assert (i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       int[] in_ptr =(int[])i_input.getBuffer();\r
+                       int[] out_ptr=(int[])i_output.getBuffer();\r
+                       int width=i_size.w;\r
+                       int height=i_size.h;\r
+                       int col0,col1,col2;\r
+                       int bptr=0;\r
+                       //1行目\r
+                       col1=in_ptr[bptr  ]*2+in_ptr[bptr+width  ];\r
+                       col2=in_ptr[bptr+1]*2+in_ptr[bptr+width+1];\r
+                       out_ptr[bptr]=(col1*2+col2)/9;\r
+                       bptr++;\r
+                       for(int x=0;x<width-2;x++){\r
+                               col0=col1;\r
+                               col1=col2;\r
+                               col2=in_ptr[bptr+1]*2+in_ptr[bptr+width+1];\r
+                               out_ptr[bptr]=(col0+col1*2+col2)/12;\r
+                               bptr++;\r
+                       }                       \r
+                       out_ptr[bptr]=(col1+col2)/9;\r
+                       bptr++;\r
+                       //2行目-末行-1\r
+\r
+                       for(int y=0;y<height-2;y++){\r
+                               //左端\r
+                               col1=in_ptr[bptr  ]*2+in_ptr[bptr-width  ]+in_ptr[bptr+width  ];\r
+                               col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1]+in_ptr[bptr+width+1];\r
+                               out_ptr[bptr]=(col1+col2)/12;\r
+                               bptr++;\r
+                               for(int x=0;x<width-2;x++){\r
+                                       col0=col1;\r
+                                       col1=col2;\r
+                                       col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1]+in_ptr[bptr+width+1];\r
+                                       out_ptr[bptr]=(col0+col1*2+col2)/16;\r
+                                       bptr++;\r
+                               }\r
+                               //右端\r
+                               out_ptr[bptr]=(col1*2+col2)/12;\r
+                               bptr++;\r
+                       }\r
+                       //末行目\r
+                       col1=in_ptr[bptr  ]*2+in_ptr[bptr-width  ];\r
+                       col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1];\r
+                       out_ptr[bptr]=(col1+col2)/9;\r
+                       bptr++;\r
+                       for(int x=0;x<width-2;x++){\r
+                               col0=col1;\r
+                               col1=col2;\r
+                               col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1];\r
+                               out_ptr[bptr]=(col0+col1*2+col2)/12;\r
+                               bptr++;\r
+                       }                       \r
+                       out_ptr[bptr]=(col1*2+col2)/9;\r
+                       bptr++;\r
+                       return;\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Reverse.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Reverse.java
new file mode 100644 (file)
index 0000000..8fc765c
--- /dev/null
@@ -0,0 +1,77 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+\r
+/**\r
+ * ネガポジ反転フィルタ。\r
+ * 画像の明暗を反転します。\r
+ *\r
+ */\r
+public class NyARRasterFilter_Reverse implements INyARRasterFilter\r
+{\r
+       private IdoFilterImpl _do_filter_impl; \r
+       public NyARRasterFilter_Reverse(int i_raster_type) throws NyARException\r
+       {\r
+               switch (i_raster_type) {\r
+               case NyARBufferType.INT1D_GRAY_8:\r
+                       this._do_filter_impl=new IdoFilterImpl_GRAY_8();\r
+                       break;\r
+               default:\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+       {\r
+               this._do_filter_impl.doFilter(i_input,i_output,i_input.getSize());\r
+       }\r
+       \r
+       interface IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException;\r
+       }\r
+       class IdoFilterImpl_GRAY_8 implements IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       assert (i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       assert (i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       int[] in_ptr =(int[])i_input.getBuffer();\r
+                       int[] out_ptr=(int[])i_output.getBuffer();\r
+\r
+                       \r
+                       int number_of_pixel=i_size.h*i_size.w;\r
+                       for(int i=0;i<number_of_pixel;i++){\r
+                               out_ptr[i]=255-in_ptr[i];\r
+                       }\r
+                       return;\r
+               }\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Rgb2Hsv.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Rgb2Hsv.java
new file mode 100644 (file)
index 0000000..634a11d
--- /dev/null
@@ -0,0 +1,96 @@
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * RGB画像をHSV画像に変換します。\r
+ *\r
+ */\r
+public class NyARRasterFilter_Rgb2Hsv implements INyARRasterFilter\r
+{\r
+       private IdoFilterImpl _dofilterimpl;\r
+       public NyARRasterFilter_Rgb2Hsv(int i_raster_type) throws NyARException\r
+       {\r
+               switch (i_raster_type) {\r
+               case NyARBufferType.BYTE1D_B8G8R8_24:\r
+                       this._dofilterimpl=new IdoFilterImpl_BYTE1D_B8G8R8_24();\r
+                       break;\r
+               case NyARBufferType.BYTE1D_R8G8B8_24:\r
+               default:\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+               this._dofilterimpl.doFilter(i_input,i_output,i_input.getSize());\r
+       }\r
+       \r
+       abstract class IdoFilterImpl\r
+       {\r
+               public abstract void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException;\r
+               \r
+       }\r
+       class IdoFilterImpl_BYTE1D_B8G8R8_24 extends IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       assert(         i_input.isEqualBufferType(NyARBufferType.INT1D_X7H9S8V8_32));\r
+                       \r
+                       int[] out_buf = (int[]) i_output.getBuffer();\r
+                       byte[] in_buf = (byte[]) i_input.getBuffer();\r
+                       int s;\r
+                       for(int i=i_size.h*i_size.w-1;i>=0;i--)\r
+                       {\r
+                               int r=(in_buf[i*3+2] & 0xff);\r
+                               int g=(in_buf[i*3+1] & 0xff);\r
+                               int b=(in_buf[i*3+0] & 0xff);\r
+                               int cmax,cmin;\r
+                               //最大値と最小値を計算\r
+                               if(r>g){\r
+                                       cmax=r;\r
+                                       cmin=g;\r
+                               }else{\r
+                                       cmax=g;\r
+                                       cmin=r;\r
+                               }\r
+                               if(b>cmax){\r
+                                       cmax=b;\r
+                               }\r
+                               if(b<cmin){\r
+                                       cmin=b;\r
+                               }\r
+                               int h;\r
+                               if(cmax==0) {\r
+                                       s=0;\r
+                                       h=0;\r
+                               }else {\r
+                                       s=(cmax-cmin)*255/cmax;\r
+                                       int cdes=cmax-cmin;\r
+                                       //H成分を計算\r
+                                       if(cdes!=0){\r
+                                               if(cmax==r){\r
+                                                       h=(g-b)*60/cdes;\r
+                                               }else if(cmax==g){\r
+                                                       h=(b-r)*60/cdes+2*60;\r
+                                               }else{\r
+                                                       h=(r-g)*60/cdes+4*60;\r
+                                               }\r
+                                       }else{\r
+                                               h=0;\r
+                                       }\r
+                               }\r
+                               if(h<0)\r
+                               {\r
+                                       h+=360;\r
+                               }\r
+                               //hsv変換(h9s8v8)\r
+                               out_buf[i]=(0x1ff0000&(h<<16))|(0x00ff00&(s<<8))|(cmax&0xff);\r
+                       }\r
+                       return;\r
+               }\r
+       }       \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Roberts.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_Roberts.java
new file mode 100644 (file)
index 0000000..429d869
--- /dev/null
@@ -0,0 +1,121 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * Roberts法で勾配を計算します。\r
+ * 右端と左端の1ピクセルは、常に0が入ります。\r
+ * X=|-1, 0|  Y=|0,-1|\r
+ *   | 0, 1|    |1, 0|\r
+ * V=sqrt(X^2+Y+2)/2\r
+ */\r
+public class NyARRasterFilter_Roberts implements INyARRasterFilter\r
+{\r
+       private IdoFilterImpl _do_filter_impl; \r
+       public NyARRasterFilter_Roberts(int i_raster_type) throws NyARException\r
+       {\r
+               switch (i_raster_type) {\r
+               case NyARBufferType.INT1D_GRAY_8:\r
+                       this._do_filter_impl=new IdoFilterImpl_GRAY_8();\r
+                       break;\r
+               default:\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+       {\r
+               this._do_filter_impl.doFilter(i_input,i_output,i_input.getSize());\r
+       }\r
+       \r
+       interface IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException;\r
+       }\r
+       class IdoFilterImpl_GRAY_8 implements IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       assert (i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       assert (i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       int[] in_ptr =(int[])i_input.getBuffer();\r
+                       int[] out_ptr=(int[])i_output.getBuffer();\r
+                       int width=i_size.w;\r
+                       int idx=0;\r
+                       int idx2=width;\r
+                       int fx,fy;\r
+                       int mod_p=(width-2)-(width-2)%8;\r
+                       for(int y=i_size.h-2;y>=0;y--){\r
+                               int p00=in_ptr[idx++];\r
+                               int p10=in_ptr[idx2++];\r
+                               int p01,p11;\r
+                               int x=width-2;\r
+                               for(;x>=mod_p;x--){\r
+                                       p01=in_ptr[idx++];p11=in_ptr[idx2++];\r
+                                       fx=p11-p00;fy=p10-p01;\r
+                                       out_ptr[idx-2]=((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1;\r
+                                       p00=p01;\r
+                                       p10=p11;\r
+                               }\r
+                               for(;x>=0;x-=4){\r
+                                       p01=in_ptr[idx++];p11=in_ptr[idx2++];\r
+                                       fx=p11-p00;\r
+                                       fy=p10-p01;\r
+                                       out_ptr[idx-2]=((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1;\r
+                                       p00=p01;p10=p11;\r
+\r
+                                       p01=in_ptr[idx++];p11=in_ptr[idx2++];\r
+                                       fx=p11-p00;\r
+                                       fy=p10-p01;\r
+                                       out_ptr[idx-2]=((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1;\r
+                                       p00=p01;p10=p11;\r
+                                       p01=in_ptr[idx++];p11=in_ptr[idx2++];\r
+                                       \r
+                                       fx=p11-p00;\r
+                                       fy=p10-p01;\r
+                                       out_ptr[idx-2]=((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1;\r
+                                       p00=p01;p10=p11;\r
+\r
+                                       p01=in_ptr[idx++];p11=in_ptr[idx2++];\r
+                                       fx=p11-p00;\r
+                                       fy=p10-p01;\r
+                                       out_ptr[idx-2]=((fx<0?-fx:fx)+(fy<0?-fy:fy))>>1;\r
+                                       p00=p01;p10=p11;\r
+\r
+                               }\r
+                               out_ptr[idx-1]=0;\r
+                       }\r
+                       for(int x=width-1;x>=0;x--){\r
+                               out_ptr[idx++]=0;\r
+                       }\r
+                       return;\r
+               }\r
+       }\r
+}\r
+\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_SimpleSmooth.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_SimpleSmooth.java
new file mode 100644 (file)
index 0000000..796bf84
--- /dev/null
@@ -0,0 +1,125 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+/**\r
+ * 平滑化フィルタ\r
+ * 画像を平滑化します。\r
+ * カーネルサイズは3x3です。\r
+ */\r
+public class NyARRasterFilter_SimpleSmooth implements INyARRasterFilter\r
+{\r
+       private IdoFilterImpl _do_filter_impl; \r
+       public NyARRasterFilter_SimpleSmooth(int i_raster_type) throws NyARException\r
+       {\r
+               switch (i_raster_type) {\r
+               case NyARBufferType.INT1D_GRAY_8:\r
+                       this._do_filter_impl=new IdoFilterImpl_GRAY_8();\r
+                       break;\r
+               default:\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input!=i_output);\r
+               this._do_filter_impl.doFilter(i_input,i_output,i_input.getSize());\r
+       }\r
+       \r
+       interface IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException;\r
+       }\r
+       class IdoFilterImpl_GRAY_8 implements IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       assert (i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       assert (i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       int[] in_ptr =(int[])i_input.getBuffer();\r
+                       int[] out_ptr=(int[])i_output.getBuffer();\r
+                       /* 画像端は捨てる。\r
+                        */\r
+                       int width=i_size.w;\r
+                       int height=i_size.h;\r
+                       int col0,col1,col2;\r
+                       int bptr=0;\r
+                       //1行目\r
+                       col1=in_ptr[bptr  ]+in_ptr[bptr+width  ];\r
+                       col2=in_ptr[bptr+1]+in_ptr[bptr+width+1];\r
+                       out_ptr[bptr]=(col1+col2)/4;\r
+                       bptr++;\r
+                       for(int x=0;x<width-2;x++){\r
+                               col0=col1;\r
+                               col1=col2;\r
+                               col2=in_ptr[bptr+1]+in_ptr[bptr+width+1];\r
+                               out_ptr[bptr]=(col0+col1+col2)/6;\r
+                               bptr++;\r
+                       }                       \r
+                       out_ptr[bptr]=(col1+col2)/4;\r
+                       bptr++;\r
+                       //2行目-末行-1\r
+\r
+                       for(int y=0;y<height-2;y++){\r
+                               //左端\r
+                               col1=in_ptr[bptr  ]+in_ptr[bptr-width  ]+in_ptr[bptr+width  ];\r
+                               col2=in_ptr[bptr+1]+in_ptr[bptr-width+1]+in_ptr[bptr+width+1];\r
+                               out_ptr[bptr]=(col1+col2)/6;\r
+                               bptr++;\r
+                               for(int x=0;x<width-2;x++){\r
+                                       col0=col1;\r
+                                       col1=col2;\r
+                                       col2=in_ptr[bptr+1]+in_ptr[bptr-width+1]+in_ptr[bptr+width+1];\r
+                                       out_ptr[bptr]=(col0+col1+col2)/9;\r
+                                       bptr++;\r
+                               }\r
+                               //右端\r
+                               out_ptr[bptr]=(col1+col2)/6;\r
+                               bptr++;\r
+                       }\r
+                       //末行目\r
+                       col1=in_ptr[bptr  ]+in_ptr[bptr-width  ];\r
+                       col2=in_ptr[bptr+1]+in_ptr[bptr-width+1];\r
+                       out_ptr[bptr]=(col1+col2)/4;\r
+                       bptr++;\r
+                       for(int x=0;x<width-2;x++){\r
+                               col0=col1;\r
+                               col1=col2;\r
+                               col2=in_ptr[bptr+1]+in_ptr[bptr-width+1];\r
+                               out_ptr[bptr]=(col0+col1+col2)/6;\r
+                               bptr++;\r
+                       }                       \r
+                       out_ptr[bptr]=(col1+col2)/4;\r
+                       bptr++;\r
+                       return;\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_ToneTable.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/NyARRasterFilter_ToneTable.java
new file mode 100644 (file)
index 0000000..bc46d3b
--- /dev/null
@@ -0,0 +1,101 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * 色調テーブルを使用したフィルターです。\r
+ * 基本的な関数テーブルで色調テーブルを作成できます。\r
+ */\r
+public class NyARRasterFilter_ToneTable extends NyARRasterFilter_CustomToneTable\r
+{\r
+       public NyARRasterFilter_ToneTable(int i_raster_type) throws NyARException\r
+       {\r
+               super(i_raster_type);\r
+       }\r
+       /**\r
+        * 点x,yを通過する、傾きi_aの直線をテーブルに書き込みます。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_a\r
+        */\r
+       public void setLine(int i_x,int i_y,double i_a)\r
+       {\r
+               if(i_a==0){\r
+                       int i;\r
+                       for(i=0;i<=i_x;i++){\r
+                               this.table[i]=0;\r
+                       }\r
+                       for(i=0;i<256;i++){\r
+                               this.table[i]=255;\r
+                       }\r
+               }else{\r
+                       int b=i_y-(int)(i_a*i_x);\r
+                       for(int i=0;i<256;i++){\r
+                               int v=(int)(i_a*i)+b;\r
+                               this.table[i]=v<0?0:v>255?255:v;\r
+                       }\r
+               }\r
+       }\r
+       /**\r
+        * 点0,0を通過する、傾きaの直線をテーブルに書き込みます。\r
+        * i_aの値をvとしたとき、以下のようになります。\r
+        * v<=0         黒色\r
+        * 0<v<1        暗くする。\r
+        * v=0          変化しない\r
+        * 1<v<255      明るくする。\r
+        * 255<=v       白色\r
+        * @param i_ax\r
+        * @param i_ay\r
+        */\r
+       public void setLine(double i_a)\r
+       {\r
+               setLine(0,0,i_a);\r
+       }\r
+       /**\r
+        * 点 i_x,i_yを中心とする、ゲインi_gainのシグモイド関数をテーブルに書き込みます。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_gain\r
+        */\r
+       public void setSigmoid(int i_x,int i_y,double i_gain)\r
+       {\r
+               for(int i=0;i<256;i++){\r
+                       int v=255*(int)(1/(1+Math.exp(i_gain*(i-i_x)))-0.5)+i_y;\r
+                       this.table[i]=v<0?0:v>255?255:v;\r
+               }\r
+       }\r
+       /**\r
+        * ガンマ補正値をテーブルに書き込みます。\r
+        * @param i_gamma\r
+        */\r
+       public void setGamma(double i_gamma)\r
+       {\r
+               for(int i=0;i<256;i++){\r
+                       this.table[i]=(int)(Math.pow((double)i/255.0,i_gamma)*255.0);\r
+               }\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/gs2bin/INyARRasterFilter_Gs2Bin.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/gs2bin/INyARRasterFilter_Gs2Bin.java
new file mode 100644 (file)
index 0000000..14daf29
--- /dev/null
@@ -0,0 +1,11 @@
+package jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARGrayscaleRaster;\r
+\r
+public interface INyARRasterFilter_Gs2Bin\r
+{\r
+       public void doFilter(NyARGrayscaleRaster i_input, NyARBinRaster i_output) throws NyARException;\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/gs2bin/NyARRasterFilter_ConstantThreshold.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/gs2bin/NyARRasterFilter_ConstantThreshold.java
new file mode 100644 (file)
index 0000000..465d7be
--- /dev/null
@@ -0,0 +1,70 @@
+package jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRasterFilter_ConstantThreshold implements INyARRasterFilter_Gs2Bin\r
+{\r
+       public int _threshold;\r
+       public NyARRasterFilter_ConstantThreshold(int i_initial_threshold,int i_in_raster_type,int i_out_raster_type) throws NyARException\r
+       {\r
+               assert(i_in_raster_type==NyARBufferType.INT1D_GRAY_8);\r
+               assert(i_out_raster_type==NyARBufferType.INT1D_BIN_8);\r
+               //初期化\r
+               this._threshold=i_initial_threshold;\r
+               \r
+       }\r
+       /**\r
+        * 2値化の閾値を設定する。\r
+        * 暗点<=th<明点となります。\r
+        * @throws NyARException\r
+        */\r
+       public NyARRasterFilter_ConstantThreshold() throws NyARException\r
+       {\r
+               this._threshold=0;\r
+       }\r
+\r
+       \r
+       public void setThreshold(int i_threshold)\r
+       {\r
+               this._threshold = i_threshold;\r
+       }\r
+       public void doFilter(NyARGrayscaleRaster i_input, NyARBinRaster i_output) throws NyARException\r
+       {\r
+               assert(i_input.getBufferType()==NyARBufferType.INT1D_GRAY_8);\r
+               assert(i_output.getBufferType()==NyARBufferType.INT1D_BIN_8);\r
+               int[] out_buf = (int[]) i_output.getBuffer();\r
+               int[] in_buf = (int[]) i_input.getBuffer();\r
+               NyARIntSize s=i_input.getSize();\r
+               \r
+               final int th=this._threshold;\r
+               int bp =s.w*s.h-1;\r
+               final int pix_count   =s.h*s.w;\r
+               final int pix_mod_part=pix_count-(pix_count%8);\r
+               for(bp=pix_count-1;bp>=pix_mod_part;bp--){\r
+                       out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+               }\r
+               //タイリング\r
+               for (;bp>=0;) {\r
+                       out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+                       bp--;\r
+                       out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+                       bp--;\r
+                       out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+                       bp--;\r
+                       out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+                       bp--;\r
+                       out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+                       bp--;\r
+                       out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+                       bp--;\r
+                       out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+                       bp--;\r
+                       out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+                       bp--;\r
+               }\r
+               return;                 \r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2bin/INyARRasterFilter_Rgb2Bin.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2bin/INyARRasterFilter_Rgb2Bin.java
new file mode 100644 (file)
index 0000000..21e70cb
--- /dev/null
@@ -0,0 +1,44 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+\r
+/**\r
+ * RGB画像からBin画像に変換するフィルタを定義します。\r
+ */\r
+public interface INyARRasterFilter_Rgb2Bin\r
+{\r
+       public void doFilter(INyARRgbRaster i_input, NyARBinRaster i_output) throws NyARException;\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2bin/NyARRasterFilter_ARToolkitThreshold.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2bin/NyARRasterFilter_ARToolkitThreshold.java
new file mode 100644 (file)
index 0000000..7fc0f85
--- /dev/null
@@ -0,0 +1,323 @@
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntRect;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+\r
+/**\r
+ * 定数閾値による2値化をする。\r
+ * \r
+ */\r
+public class NyARRasterFilter_ARToolkitThreshold implements INyARRasterFilter_Rgb2Bin\r
+{\r
+       protected int _threshold;\r
+       private IdoThFilterImpl _do_threshold_impl;\r
+\r
+       public NyARRasterFilter_ARToolkitThreshold(int i_threshold,int i_in_raster_type) throws NyARException\r
+       {\r
+               if(!initInstance(i_threshold,i_in_raster_type,NyARBufferType.INT1D_BIN_8)){\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public NyARRasterFilter_ARToolkitThreshold(int i_threshold,int i_in_raster_type,int i_out_raster_type) throws NyARException\r
+       {\r
+               if(!initInstance(i_threshold,i_in_raster_type,i_out_raster_type)){\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       protected boolean initInstance(int i_threshold,int i_in_raster_type,int i_out_raster_type)\r
+       {\r
+               switch(i_out_raster_type){\r
+               case NyARBufferType.INT1D_BIN_8:\r
+                       switch (i_in_raster_type){\r
+                       case NyARBufferType.BYTE1D_B8G8R8_24:\r
+                       case NyARBufferType.BYTE1D_R8G8B8_24:\r
+                               this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_BYTE1D_RGB_24();\r
+                               break;\r
+                       case NyARBufferType.BYTE1D_B8G8R8X8_32:\r
+                               this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_BYTE1D_B8G8R8X8_32();\r
+                               break;\r
+                       case NyARBufferType.BYTE1D_X8R8G8B8_32:\r
+                               this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_BYTE1D_X8R8G8B8_32();\r
+                               break;\r
+                       case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                               this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_INT1D_X8R8G8B8_32();\r
+                               break;\r
+                       case NyARBufferType.WORD1D_R5G6B5_16LE:\r
+                               this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_WORD1D_R5G6B5_16LE();\r
+                               break;\r
+                       default:\r
+                               return false;//サポートしない組み合わせ\r
+                       }\r
+                       break;\r
+               default:\r
+                       return false;//サポートしない組み合わせ\r
+               }\r
+               this._threshold = i_threshold;\r
+               return true;\r
+       }       \r
+       \r
+       /**\r
+        * 画像を2値化するための閾値。暗点<=th<明点となります。\r
+        * @param i_threshold\r
+        */\r
+       public void setThreshold(int i_threshold)\r
+       {\r
+               this._threshold = i_threshold;\r
+       }\r
+\r
+       public void doFilter(INyARRgbRaster i_input, NyARBinRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+               NyARIntSize s=i_input.getSize();\r
+               this._do_threshold_impl.doThFilter(i_input,0,0,s.w,s.h,this._threshold,i_output);\r
+               return;\r
+       }\r
+       public void doFilter(INyARRgbRaster i_input,NyARIntRect i_area, NyARBinRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+               this._do_threshold_impl.doThFilter(i_input,i_area.x,i_area.y,i_area.w,i_area.h,this._threshold,i_output);\r
+               return;\r
+               \r
+       }\r
+       \r
+\r
+\r
+       protected interface IdoThFilterImpl\r
+       {\r
+               public void doThFilter(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h,int i_th,INyARRaster o_raster);\r
+       }\r
+       \r
+       class doThFilterImpl_BUFFERFORMAT_BYTE1D_RGB_24 implements IdoThFilterImpl\r
+       {\r
+               public void doThFilter(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h,int i_th,INyARRaster o_raster)\r
+               {\r
+                       assert (\r
+                                       i_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24)||\r
+                                       i_raster.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));\r
+                       final byte[] input=(byte[])i_raster.getBuffer();\r
+                       final int[] output=(int[])o_raster.getBuffer();\r
+                       int th=i_th*3;\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip_dst=(s.w-i_w);\r
+                       int skip_src=skip_dst*3;\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt_dst=(i_t*s.w+i_l);\r
+                       int pt_src=pt_dst*3;\r
+                       for (int y = i_h-1; y >=0 ; y-=1){\r
+                               int x;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=3;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=3;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=3;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=3;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=3;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=3;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=3;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=3;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=3;\r
+                               }\r
+                               //スキップ\r
+                               pt_src+=skip_src;\r
+                               pt_dst+=skip_dst;\r
+                       }\r
+                       return; \r
+               }\r
+       }\r
+       class doThFilterImpl_BUFFERFORMAT_INT1D_X8R8G8B8_32 implements IdoThFilterImpl\r
+       {\r
+               public void doThFilter(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h,int i_th,INyARRaster o_raster)\r
+               {\r
+                       assert (i_raster.isEqualBufferType( NyARBufferType.INT1D_X8R8G8B8_32));\r
+                       final int[] input=(int[])i_raster.getBuffer();\r
+                       final int[] output=(int[])o_raster.getBuffer();\r
+                       int th=i_th*3;\r
+\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip_src=(s.w-i_w);\r
+                       int skip_dst=skip_src;\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt_dst=(i_t*s.w+i_l);\r
+                       int pt_src=pt_dst;\r
+                       for (int y = i_h-1; y >=0 ; y-=1){\r
+                               int x,v;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v& 0xff))<=th?0:1;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v& 0xff))<=th?0:1;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v& 0xff))<=th?0:1;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v& 0xff))<=th?0:1;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v& 0xff))<=th?0:1;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v& 0xff))<=th?0:1;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v& 0xff))<=th?0:1;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v& 0xff))<=th?0:1;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v& 0xff))<=th?0:1;\r
+                               }\r
+                               //スキップ\r
+                               pt_src+=skip_src;\r
+                               pt_dst+=skip_dst;                               \r
+                       }\r
+                       return;                 \r
+               }       \r
+       }\r
+\r
+       \r
+\r
+\r
+       class doThFilterImpl_BUFFERFORMAT_BYTE1D_B8G8R8X8_32 implements IdoThFilterImpl\r
+       {\r
+               public void doThFilter(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h,int i_th,INyARRaster o_raster)\r
+               {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8X8_32));\r
+                       final byte[] input=(byte[])i_raster.getBuffer();\r
+                       final int[] output=(int[])o_raster.getBuffer();\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int th=i_th*3;\r
+                       int skip_dst=(s.w-i_w);\r
+                       int skip_src=skip_dst*4;\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt_dst=(i_t*s.w+i_l);\r
+                       int pt_src=pt_dst*4;\r
+                       for (int y = i_h-1; y >=0 ; y-=1){\r
+                               int x;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       output[pt_dst++]=((input[pt_src+ 0]& 0xff)+(input[pt_src+ 1]& 0xff)+(input[pt_src+ 2]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                               }\r
+                               //スキップ\r
+                               pt_src+=skip_src;\r
+                               pt_dst+=skip_dst;                               \r
+                       }\r
+                       return; \r
+           }\r
+       }\r
+\r
+       class doThFilterImpl_BUFFERFORMAT_BYTE1D_X8R8G8B8_32 implements IdoThFilterImpl\r
+       {\r
+               public void doThFilter(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h,int i_th,INyARRaster o_raster)\r
+               {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.BYTE1D_X8R8G8B8_32));\r
+                       final byte[] input=(byte[])i_raster.getBuffer();\r
+                       final int[] output=(int[])o_raster.getBuffer();\r
+                       int th=i_th*3;\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip_dst=(s.w-i_w);\r
+                       int skip_src=skip_dst*4;\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt_dst=(i_t*s.w+i_l);\r
+                       int pt_src=pt_dst*4;\r
+                       for (int y = i_h-1; y >=0 ; y-=1){\r
+                               int x;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       output[pt_dst++]=((input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff)+(input[pt_src+3]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       output[pt_dst++]=((input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff)+(input[pt_src+3]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff)+(input[pt_src+3]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff)+(input[pt_src+3]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff)+(input[pt_src+3]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff)+(input[pt_src+3]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff)+(input[pt_src+3]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff)+(input[pt_src+3]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                                       output[pt_dst++]=((input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff)+(input[pt_src+3]& 0xff))<=th?0:1;\r
+                                       pt_src+=4;\r
+                               }\r
+                               //スキップ\r
+                               pt_src+=skip_src;\r
+                               pt_dst+=skip_dst;                               \r
+                       }\r
+                       return; \r
+           }\r
+       }\r
+\r
+       class doThFilterImpl_BUFFERFORMAT_WORD1D_R5G6B5_16LE implements IdoThFilterImpl\r
+       {\r
+               public void doThFilter(INyARRaster i_raster,int i_l,int i_t,int i_w,int i_h,int i_th,INyARRaster o_raster)\r
+               {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.WORD1D_R5G6B5_16LE));\r
+                       final short[] input=(short[])i_raster.getBuffer();\r
+                       final int[] output=(int[])o_raster.getBuffer();\r
+                       int th=i_th*3;\r
+                       NyARIntSize s=i_raster.getSize();\r
+                       int skip_dst=(s.w-i_w);\r
+                       int skip_src=skip_dst;\r
+                       final int pix_count=i_w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       int pt_dst=(i_t*s.w+i_l);\r
+                       int pt_src=pt_dst;\r
+                       for (int y = i_h-1; y >=0 ; y-=1){\r
+                               int x,v;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       v =(int)input[pt_src++]; output[pt_dst++]=(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))<=th?0:1;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       v =(int)input[pt_src++]; output[pt_dst++]=(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))<=th?0:1;\r
+                                       v =(int)input[pt_src++]; output[pt_dst++]=(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))<=th?0:1;\r
+                                       v =(int)input[pt_src++]; output[pt_dst++]=(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))<=th?0:1;\r
+                                       v =(int)input[pt_src++]; output[pt_dst++]=(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))<=th?0:1;\r
+                                       v =(int)input[pt_src++]; output[pt_dst++]=(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))<=th?0:1;\r
+                                       v =(int)input[pt_src++]; output[pt_dst++]=(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))<=th?0:1;\r
+                                       v =(int)input[pt_src++]; output[pt_dst++]=(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))<=th?0:1;\r
+                                       v =(int)input[pt_src++]; output[pt_dst++]=(((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))<=th?0:1;\r
+                               }\r
+                               //スキップ\r
+                               pt_src+=skip_src;\r
+                               pt_dst+=skip_dst;\r
+                       }\r
+                       return; \r
+           }\r
+       }\r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/INyARRasterFilter_Rgb2Gs.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/INyARRasterFilter_Rgb2Gs.java
new file mode 100644 (file)
index 0000000..8e15c10
--- /dev/null
@@ -0,0 +1,50 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+\r
+/**\r
+ * このインタフェイスは、RGBラスタをグレースケールラスタに変換します。\r
+ *\r
+ */\r
+public interface INyARRasterFilter_Rgb2Gs\r
+{\r
+       /**\r
+        * 同一サイズのラスタi_inputとi_outputの間で、フィルタ処理を実行します。\r
+        * @param i_input\r
+        * @param i_output\r
+        * @throws NyARException\r
+        */\r
+       public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException;\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_RgbAve192.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_RgbAve192.java
new file mode 100644 (file)
index 0000000..7346c5d
--- /dev/null
@@ -0,0 +1,355 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * RGBラスタをGrayScaleに変換するフィルタを作成します。\r
+ * このフィルタは、RGB値の平均値を、(R+G+B)>>4で算出します。(スケールは、192>=n>=0になります。)\r
+ *\r
+ */\r
+public class NyARRasterFilter_Rgb2Gs_RgbAve192 implements INyARRasterFilter_Rgb2Gs\r
+{\r
+       IdoThFilterImpl _do_filter_impl;\r
+       public NyARRasterFilter_Rgb2Gs_RgbAve192(int i_in_raster_type,int i_out_raster_type) throws NyARException\r
+       {\r
+               if(!initInstance(i_in_raster_type,i_out_raster_type))\r
+               {\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public NyARRasterFilter_Rgb2Gs_RgbAve192(int i_in_raster_type) throws NyARException\r
+       {\r
+               if(!initInstance(i_in_raster_type,NyARBufferType.INT1D_GRAY_8))\r
+               {\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       protected boolean initInstance(int i_in_raster_type,int i_out_raster_type)\r
+       {\r
+               switch(i_out_raster_type){\r
+               case NyARBufferType.INT1D_GRAY_8:\r
+                       switch (i_in_raster_type){\r
+                       case NyARBufferType.BYTE1D_B8G8R8_24:\r
+                       case NyARBufferType.BYTE1D_R8G8B8_24:\r
+                               this._do_filter_impl=new doThFilterImpl_BYTE1D_B8G8R8_24();\r
+                               break;\r
+                       case NyARBufferType.BYTE1D_B8G8R8X8_32:\r
+                               this._do_filter_impl=new doThFilterImpl_BYTE1D_B8G8R8X8_32();\r
+                               break;\r
+                       case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                               this._do_filter_impl=new doThFilterImpl_BUFFERFORMAT_INT1D_X8R8G8B8_32();\r
+                               break;\r
+                       default:\r
+                               return false;\r
+                       }\r
+                       break;\r
+               default:\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+       public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+               NyARIntSize s=i_input.getSize();\r
+               this._do_filter_impl.doFilter(i_input,(int[])i_output.getBuffer(),0,0,s.w,s.h);\r
+               return;\r
+       }\r
+       /**\r
+        * 同一サイズのラスタi_inputとi_outputの間で、一部の領域だけにラスタ処理を実行します。\r
+        * @param i_input\r
+        * @param i_rect\r
+        * @param i_output\r
+        * @throws NyARException\r
+        */\r
+       public void doFilter(INyARRgbRaster i_input,NyARIntRect i_rect, NyARGrayscaleRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+               this._do_filter_impl.doFilter(i_input,(int[])i_output.getBuffer(),i_rect.x,i_rect.y,i_rect.w,i_rect.h);\r
+               \r
+       }\r
+       /**\r
+        * 異サイズのラスタi_inputとi_outputの間で、一部の領域をi_outputへ転送します。\r
+        * 関数は、i_outputのサイズをi_skip倍した領域を、i_inputのi_left,i_topの位置から切り出し、フィルタ処理をしてi_outputへ格納します。\r
+        * @param i_input\r
+        * @param i_left\r
+        * @param i_top\r
+        * @param i_skip\r
+        * @param i_output\r
+        */\r
+       public void doCutFilter(INyARRgbRaster i_input,int i_left,int i_top,int i_skip,NyARGrayscaleRaster i_output) throws NyARException\r
+       {\r
+               this._do_filter_impl.doCutFilter(i_input,i_left,i_top,i_skip,i_output);         \r
+       }\r
+       /*\r
+        * ここから各種ラスタ向けのフィルタ実装\r
+        *\r
+        */\r
+       interface IdoThFilterImpl\r
+       {\r
+               /**\r
+                * 同一サイズのラスタ間での転送\r
+                * @param i_input\r
+                * @param o_output\r
+                * @param l\r
+                * @param t\r
+                * @param w\r
+                * @param h\r
+                */\r
+               public void doFilter(INyARRaster i_input,int[] o_output, int l,int t,int w,int h) throws NyARException;\r
+               /**\r
+                * 異サイズラスタ間での転送\r
+                * @param i_input\r
+                * @param l\r
+                * @param t\r
+                * @param i_st\r
+                * @param o_output\r
+                */\r
+               public void doCutFilter(INyARRaster i_input, int l,int t,int i_st,NyARGrayscaleRaster o_output) throws NyARException;\r
+       }\r
+       \r
+       class doThFilterImpl_BUFFERFORMAT_INT1D_X8R8G8B8_32 implements IdoThFilterImpl\r
+       {\r
+               public void doCutFilter(INyARRaster i_input, int l,int t,int i_st,NyARGrayscaleRaster o_output) throws NyARException\r
+               {\r
+                       assert(i_input.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
+                       assert(i_input.getSize().isInnerSize(l+o_output.getWidth()*i_st,t+o_output.getHeight()*i_st));\r
+                       final int[] input=(int[])i_input.getBuffer();\r
+                       final int[] output=(int[])o_output.getBuffer();\r
+                       int v;\r
+                       int pt_src,pt_dst;\r
+                       NyARIntSize dest_size=o_output.getSize();                       \r
+                       NyARIntSize src_size=i_input.getSize();\r
+                       int skip_src_y=(src_size.w-dest_size.w*i_st)+src_size.w*(i_st-1);\r
+                       int skip_src_x=i_st;\r
+                       final int pix_count=dest_size.w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       pt_dst=0;\r
+                       pt_src=(t*src_size.w+l);\r
+                       for (int y = dest_size.h-1; y >=0; y-=1){\r
+                               int x;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       v=input[pt_src++];output[pt_dst++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                               }\r
+                               //スキップ\r
+                               pt_src+=skip_src_y;\r
+                       }\r
+                       return;         \r
+               }\r
+               public void doFilter(INyARRaster i_input, int[] o_output,int l,int t,int w,int h)\r
+               {\r
+                       assert(i_input.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
+                       NyARIntSize size=i_input.getSize();\r
+                       int[] in_buf = (int[]) i_input.getBuffer();\r
+                       int bp = (l+t*size.w);\r
+                       int v;\r
+                       final int b=t+h;\r
+                       final int row_padding_dst=(size.w-w);\r
+                       final int row_padding_src=row_padding_dst;\r
+                       final int pix_count=w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);\r
+                       int src_ptr=t*size.w+l;\r
+                       for (int y = t; y < b; y++) {\r
+                               int x=0;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       v=in_buf[src_ptr++];o_output[bp++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       v=in_buf[src_ptr++];o_output[bp++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       v=in_buf[src_ptr++];o_output[bp++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       v=in_buf[src_ptr++];o_output[bp++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       v=in_buf[src_ptr++];o_output[bp++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       v=in_buf[src_ptr++];o_output[bp++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       v=in_buf[src_ptr++];o_output[bp++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       v=in_buf[src_ptr++];o_output[bp++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                                       v=in_buf[src_ptr++];o_output[bp++]=(((v>>16)& 0xff)+((v>>8)& 0xff)+(v &0xff))>>2;\r
+                               }\r
+                               bp+=row_padding_dst;\r
+                               src_ptr+=row_padding_src;\r
+                       }\r
+                       return;                 \r
+               }\r
+       }\r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       class doThFilterImpl_BYTE1D_B8G8R8_24 implements IdoThFilterImpl\r
+       {\r
+               public void doCutFilter(INyARRaster i_input, int l,int t,int i_st,NyARGrayscaleRaster o_output) throws NyARException\r
+               {\r
+                       assert(i_input.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24)||i_input.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));\r
+                       assert(i_input.getSize().isInnerSize(l+o_output.getWidth()*i_st,t+o_output.getHeight()*i_st));\r
+                       \r
+                       final byte[] input=(byte[])i_input.getBuffer();\r
+                       final int[] output=(int[])o_output.getBuffer();\r
+                       int pt_src,pt_dst;\r
+                       NyARIntSize dest_size=o_output.getSize();                       \r
+                       NyARIntSize src_size=i_input.getSize();\r
+                       int skip_src_y=(src_size.w-dest_size.w*i_st)*3+src_size.w*(i_st-1)*3;\r
+                       int skip_src_x=3*i_st;\r
+                       final int pix_count=dest_size.w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);                 \r
+                       //左上から1行づつ走査していく\r
+                       pt_dst=0;\r
+                       pt_src=(t*src_size.w+l)*3;\r
+                       for (int y = dest_size.h-1; y >=0; y-=1){\r
+                               int x;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                                       output[pt_dst++]=((input[pt_src+0]& 0xff)+(input[pt_src+1]& 0xff)+(input[pt_src+2]& 0xff))>>2;\r
+                                       pt_src+=skip_src_x;\r
+                               }\r
+                               //スキップ\r
+                               pt_src+=skip_src_y;\r
+                       }\r
+                       return;\r
+               }\r
+               public void doFilter(INyARRaster i_input, int[] o_output,int l,int t,int w,int h)\r
+               {\r
+                       assert(i_input.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24)||i_input.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));\r
+                       \r
+                       NyARIntSize size=i_input.getSize();\r
+                       byte[] in_buf = (byte[]) i_input.getBuffer();\r
+                       int bp = (l+t*size.w)*3;\r
+                       final int b=t+h;\r
+                       final int row_padding_dst=(size.w-w);\r
+                       final int row_padding_src=row_padding_dst*3;\r
+                       final int pix_count=w;\r
+                       final int pix_mod_part=pix_count-(pix_count%8);\r
+                       int src_ptr=t*size.w+l;\r
+                       for (int y = t; y < b; y++) {\r
+                               \r
+                               int x=0;\r
+                               for (x = pix_count-1; x >=pix_mod_part; x--){\r
+                                       o_output[src_ptr++] = ((in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff)) >>2;\r
+                               }\r
+                               for (;x>=0;x-=8){\r
+                                       o_output[src_ptr++] = ((in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff)) >>2;\r
+                                       o_output[src_ptr++] = ((in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff)) >>2;\r
+                                       o_output[src_ptr++] = ((in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff)) >>2;\r
+                                       o_output[src_ptr++] = ((in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff)) >>2;\r
+                                       o_output[src_ptr++] = ((in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff)) >>2;\r
+                                       o_output[src_ptr++] = ((in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff)) >>2;\r
+                                       o_output[src_ptr++] = ((in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff)) >>2;\r
+                                       o_output[src_ptr++] = ((in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff) + (in_buf[bp++] & 0xff)) >>2;\r
+                               }\r
+                               \r
+                               bp+=row_padding_dst;\r
+                               src_ptr+=row_padding_src;\r
+                       }\r
+                       return;\r
+               }               \r
+       }\r
+       class doThFilterImpl_BYTE1D_B8G8R8X8_32 implements IdoThFilterImpl\r
+       {\r
+               public void doCutFilter(INyARRaster i_input, int l,int t,int i_st,NyARGrayscaleRaster o_output) throws NyARException\r
+               {\r
+                       NyARException.notImplement();\r
+               }\r
+               public void doFilter(INyARRaster i_input, int[] o_output,int l,int t,int w,int h) throws NyARException\r
+               {\r
+                       assert(i_input.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8X8_32));\r
+                       NyARIntSize size=i_input.getSize();\r
+                       byte[] in_buf = (byte[]) i_input.getBuffer();\r
+\r
+                       int bp = (l+t*size.w)*4;\r
+                       final int b=t+h;\r
+                       final int row_padding=(size.w-w)*4;\r
+                       for (int y = t; y < b; y++) {\r
+                               for (int x = 0; x < w; x++) {\r
+                                       o_output[y*size.w+x+l] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) >>2;\r
+                                       bp += 4;\r
+                               }\r
+                               bp+=row_padding;\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_RgbCube.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_RgbCube.java
new file mode 100644 (file)
index 0000000..9b023c6
--- /dev/null
@@ -0,0 +1,121 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_Rgb2Gs;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+/**\r
+ * RGBラスタをGrayScaleに変換するフィルタを作成します。\r
+ * このフィルタは、RGB値の平均値を、(R*G*B)/(255*255)で算出します。\r
+ * \r
+ * この値は、RGB成分の作る立方体の体積を0-255スケールにした値です。\r
+ *\r
+ */\r
+public class NyARRasterFilter_Rgb2Gs_RgbCube implements INyARRasterFilter_Rgb2Gs\r
+{\r
+       private IdoFilterImpl _dofilterimpl;\r
+       public NyARRasterFilter_Rgb2Gs_RgbCube(int i_in_raster_type) throws NyARException\r
+       {\r
+               if(!initInstance(i_in_raster_type,NyARBufferType.INT1D_GRAY_8))\r
+               {\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public NyARRasterFilter_Rgb2Gs_RgbCube(int i_in_raster_type,int i_out_raster) throws NyARException\r
+       {\r
+               if(!initInstance(i_in_raster_type,i_out_raster))\r
+               {\r
+                       throw new NyARException();\r
+               }\r
+       }       \r
+       protected boolean initInstance(int i_in_raster_type,int i_out_raster_type)\r
+       {\r
+               switch(i_out_raster_type){\r
+               case NyARBufferType.INT1D_GRAY_8:\r
+                       switch (i_in_raster_type) {\r
+                       case NyARBufferType.BYTE1D_B8G8R8_24:\r
+                       case NyARBufferType.BYTE1D_R8G8B8_24:\r
+                               this._dofilterimpl=new IdoFilterImpl_BYTE1D_B8G8R8_24();\r
+                               break;\r
+                       default:\r
+                               return false;\r
+                       }\r
+                       break;\r
+               default:\r
+                       return false;\r
+               }\r
+               return true;\r
+       }       \r
+       \r
+       \r
+       public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+               this._dofilterimpl.doFilter(i_input,i_output,i_input.getSize());\r
+       }\r
+       \r
+       interface IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException;\r
+       }\r
+       class IdoFilterImpl_BYTE1D_B8G8R8_24 implements IdoFilterImpl\r
+       {\r
+               /**\r
+                * This function is not optimized.\r
+                */\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       assert(         i_input.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24)\r
+                                       ||      i_input.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));\r
+                       assert(i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       \r
+                       int[] out_buf = (int[]) i_output.getBuffer();\r
+                       byte[] in_buf = (byte[]) i_input.getBuffer();\r
+\r
+                       int bp = 0;\r
+                       for (int y = 0; y < i_size.h; y++) {\r
+                               for (int x = 0; x < i_size.w; x++) {\r
+                                       out_buf[y*i_size.w+x] = ((in_buf[bp] & 0xff) * (in_buf[bp + 1] & 0xff) * (in_buf[bp + 2] & 0xff)) >> 16;\r
+                                       bp += 3;\r
+                               }\r
+                       }\r
+                       return;\r
+               }\r
+       }\r
+       \r
+}\r
+\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_YCbCr.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterfilter/rgb2gs/NyARRasterFilter_Rgb2Gs_YCbCr.java
new file mode 100644 (file)
index 0000000..f08e92b
--- /dev/null
@@ -0,0 +1,107 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_Rgb2Gs;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * YCbCr変換して、Y成分のグレースケールの値を計算します。\r
+ * 変換式は、http://www.tyre.gotdns.org/を参考にしました。\r
+ */\r
+public class NyARRasterFilter_Rgb2Gs_YCbCr implements INyARRasterFilter_Rgb2Gs\r
+{\r
+       private IdoFilterImpl _dofilterimpl;\r
+       public NyARRasterFilter_Rgb2Gs_YCbCr(int i_in_raster_type) throws NyARException\r
+       {\r
+               if(!initInstance(i_in_raster_type,NyARBufferType.INT1D_GRAY_8))\r
+               {\r
+                       throw new NyARException();\r
+               }\r
+       }\r
+       public NyARRasterFilter_Rgb2Gs_YCbCr(int i_in_raster_type,int i_out_raster) throws NyARException\r
+       {\r
+               if(!initInstance(i_in_raster_type,i_out_raster))\r
+               {\r
+                       throw new NyARException();\r
+               }\r
+       }       \r
+       protected boolean initInstance(int i_in_raster_type,int i_out_raster_type)\r
+       {\r
+               switch(i_out_raster_type){\r
+               case NyARBufferType.INT1D_GRAY_8:\r
+                       switch (i_in_raster_type) {\r
+                       case NyARBufferType.BYTE1D_B8G8R8_24:\r
+                               this._dofilterimpl=new IdoFilterImpl_BYTE1D_B8G8R8_24();\r
+                               break;\r
+                       case NyARBufferType.BYTE1D_R8G8B8_24:\r
+                       default:\r
+                               return false;\r
+                       }\r
+                       break;\r
+               default:\r
+                       return false;\r
+               }\r
+               return true;\r
+       }       \r
+       \r
+       public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException\r
+       {\r
+               assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+               this._dofilterimpl.doFilter(i_input,i_output,i_input.getSize());\r
+       }\r
+       \r
+       interface IdoFilterImpl\r
+       {\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException;\r
+       }\r
+       class IdoFilterImpl_BYTE1D_B8G8R8_24 implements IdoFilterImpl\r
+       {\r
+               /**\r
+                * This function is not optimized.\r
+                */\r
+               public void doFilter(INyARRaster i_input, INyARRaster i_output,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       assert( i_input.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24));\r
+                       assert(i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+                       \r
+                       int[] out_buf = (int[]) i_output.getBuffer();\r
+                       byte[] in_buf = (byte[]) i_input.getBuffer();\r
+\r
+                       int bp = 0;\r
+                       for (int y = 0; y < i_size.h; y++){\r
+                               for (int x = 0; x < i_size.w; x++){\r
+                                       out_buf[y*i_size.w+x]=(306*(in_buf[bp+2] & 0xff)+601*(in_buf[bp + 1] & 0xff)+117 * (in_buf[bp + 0] & 0xff))>>10;\r
+                                       bp += 3;\r
+                               }\r
+                       }\r
+                       return;\r
+               }\r
+       }       \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/INyARRgbPixelReader.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/INyARRgbPixelReader.java
new file mode 100644 (file)
index 0000000..ea9dfcc
--- /dev/null
@@ -0,0 +1,95 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * R8G8B8でピクセルを読み出すインタフェイス\r
+ * \r
+ */\r
+public interface INyARRgbPixelReader\r
+{\r
+       /**\r
+        * 1ピクセルをint配列にして返します。\r
+        * \r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_rgb\r
+        */\r
+       public void getPixel(int i_x, int i_y, int[] i_rgb) throws NyARException;\r
+\r
+       /**\r
+        * 複数のピクセル値をint配列に返します。\r
+        * 配列には、[R1][G1][B1][R2][G2][B2]の順でピクセル値が格納されます。\r
+        * \r
+        * @param i_x\r
+        * xのインデックス配列\r
+        * @param i_y\r
+        * yのインデックス配列\r
+        */\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException;\r
+       /**\r
+        * 1ピクセルを設定します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_r\r
+        * @param i_g\r
+        * @param i_b\r
+        * @throws NyARException\r
+        */\r
+       public void setPixel(int i_x, int i_y, int i_r,int i_g,int i_b) throws NyARException;\r
+       \r
+       /**\r
+        * 1ピクセルを設定します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_rgb\r
+        * @throws NyARException\r
+        */\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException;\r
+       /**\r
+        * 複数のピクセル値をint配列から設定します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_num\r
+        * @param i_intrgb\r
+        * @throws NyARException\r
+        */\r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException;\r
+       /**\r
+        * 参照しているバッファをi_ref_bufferへ切り替えます。\r
+        * 内部パラメータのチェックは、実装依存です。\r
+        * @param i_ref_buffer\r
+        * @throws NyARException\r
+        */\r
+       public void switchBuffer(Object i_ref_buffer) throws NyARException;\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARPerspectiveRasterReader.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARPerspectiveRasterReader.java
new file mode 100644 (file)
index 0000000..9993044
--- /dev/null
@@ -0,0 +1,997 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+\r
+\r
+/**\r
+ * 遠近法を使ったパースペクティブ補正をかけて、ラスタ上の四角形から\r
+ * 任意解像度の矩形パターンを作成します。\r
+ * \r
+ * 出力ラスタ形式が、INT1D_X8R8G8B8_32の物については、単体サンプリングモードの時は高速化済み。マルチサンプリングモードのときは高速化なし。\r
+ * 入力ラスタ形式がINT1D_X8R8G8B8_32,BYTE1D_B8G8R8_24,BYTE1D_R8G8B8_24については、高速化済み。\r
+ * 他の形式のラスタでは、PixelReaderを介した低速転送で対応します。\r
+ * <p>メモ-\r
+ * この関数は、1倍の時はNyARColorPatt_Perspective,\r
+ * n倍の時はNyARColorPatt_Perspective_O2の関数を元に作ってます。\r
+ * </p>\r
+ *\r
+ */\r
+public class NyARPerspectiveRasterReader\r
+{\r
+       protected NyARPerspectiveParamGenerator _perspective_gen;\r
+       private static final int LOCAL_LT=1;\r
+       protected final double[] __pickFromRaster_cpara=new double[8];\r
+       private IPickupRasterImpl _picker;      \r
+       \r
+       private void initializeInstance(int i_buffer_type)\r
+       {\r
+               //新しいモードに対応したら書いてね。\r
+               switch(i_buffer_type){\r
+               case NyARBufferType.BYTE1D_B8G8R8X8_32:\r
+                       this._picker=new PPickup_Impl_BYTE1D_B8G8R8X8_32();\r
+                       break;\r
+               case NyARBufferType.BYTE1D_B8G8R8_24:\r
+                       this._picker=new PPickup_Impl_BYTE1D_B8G8R8_24();\r
+                       break;\r
+               case NyARBufferType.BYTE1D_R8G8B8_24:\r
+                       this._picker=new PPickup_Impl_BYTE1D_R8G8B8_24();\r
+                       break;\r
+               default:\r
+                       this._picker=new PPickup_Impl_AnyRaster();\r
+                       //低速インタフェイス警告。必要に応じて、高速取得系を実装してね\r
+//                     System.out.println("NyARToolKit Warning:"+this.getClass().getName()+":Low speed interface.");\r
+                       break;\r
+               }\r
+               this._perspective_gen=new NyARPerspectiveParamGenerator_O1(LOCAL_LT,LOCAL_LT);\r
+               return;         \r
+       }\r
+       /**\r
+        * コンストラクタです。このコンストラクタで作成したインスタンスは、入力ラスタタイプに依存しませんが低速です。\r
+        * 入力画像のラスタの形式が既知の場合は、もう一方のコンストラクタを使用してください。\r
+        */\r
+       public NyARPerspectiveRasterReader()\r
+       {\r
+               initializeInstance(NyARBufferType.NULL_ALLZERO);\r
+               return;\r
+       }\r
+       /**\r
+        * コンストラクタです。入力ラスタの形式を制限してインスタンスを作成します。\r
+        * @param i_input_raster_type\r
+        */\r
+       public NyARPerspectiveRasterReader(int i_input_raster_type)\r
+       {\r
+               //入力制限\r
+               this.initializeInstance(i_input_raster_type);\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * i_in_rasterから4頂点i_vertexsでかこまれた領域の画像を射影変換して、o_outへ格納します。\r
+        * @param i_in_raster\r
+        * このラスタの形式は、コンストラクタで制限したものと一致している必要があります。\r
+        * @param i_vertex\r
+        * 4頂点を格納した配列です。\r
+        * @param i_edge_x\r
+        * X方向のエッジ割合です。0-99の数値を指定します。\r
+        * @param i_edge_y\r
+        * Y方向のエッジ割合です。0-99の数値を指定します。\r
+        * @param i_resolution\r
+        * 出力の1ピクセルあたりのサンプリング数を指定します。例えば2を指定すると、出力1ピクセルあたり4ピクセルをサンプリングします。\r
+        * @param o_out\r
+        * 出力先のラスタです。\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public boolean read4Point(INyARRgbRaster i_in_raster,NyARDoublePoint2d[] i_vertex,int i_edge_x,int i_edge_y,int i_resolution,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               NyARIntSize out_size=o_out.getSize();\r
+               int xe=out_size.w*i_edge_x/50;\r
+               int ye=out_size.h*i_edge_y/50;\r
+\r
+               //サンプリング解像度で分岐\r
+               if(i_resolution==1){\r
+                       if (!this._perspective_gen.getParam((xe*2+out_size.w),(ye*2+out_size.h),i_vertex, this.__pickFromRaster_cpara)) {\r
+                               return false;\r
+                       }\r
+                       this._picker.onePixel(xe+LOCAL_LT,ye+LOCAL_LT,this.__pickFromRaster_cpara,i_in_raster,o_out);\r
+               }else{\r
+                       if (!this._perspective_gen.getParam((xe*2+out_size.w)*i_resolution,(ye*2+out_size.h)*i_resolution,i_vertex, this.__pickFromRaster_cpara)) {\r
+                               return false;\r
+                       }\r
+                       this._picker.multiPixel(xe*i_resolution+LOCAL_LT,ye*i_resolution+LOCAL_LT,this.__pickFromRaster_cpara,i_resolution,i_in_raster,o_out);\r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * read4Pointの入力型違いです。\r
+        */     \r
+       public boolean read4Point(INyARRgbRaster i_in_raster,NyARIntPoint2d[] i_vertex,int i_edge_x,int i_edge_y,int i_resolution,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               NyARIntSize out_size=o_out.getSize();\r
+               int xe=out_size.w*i_edge_x/50;\r
+               int ye=out_size.h*i_edge_y/50;\r
+\r
+               //サンプリング解像度で分岐\r
+               if(i_resolution==1){\r
+                       if (!this._perspective_gen.getParam((xe*2+out_size.w),(ye*2+out_size.h),i_vertex, this.__pickFromRaster_cpara)) {\r
+                               return false;\r
+                       }\r
+                       this._picker.onePixel(xe+LOCAL_LT,ye+LOCAL_LT,this.__pickFromRaster_cpara,i_in_raster,o_out);\r
+               }else{\r
+                       if (!this._perspective_gen.getParam((xe*2+out_size.w)*i_resolution,(ye*2+out_size.h)*i_resolution,i_vertex, this.__pickFromRaster_cpara)) {\r
+                               return false;\r
+                       }\r
+                       this._picker.multiPixel(xe*i_resolution+LOCAL_LT,ye*i_resolution+LOCAL_LT,this.__pickFromRaster_cpara,i_resolution,i_in_raster,o_out);\r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * read4Pointの入力型違いです。\r
+        */     \r
+       public boolean read4Point(INyARRgbRaster i_in_raster,double i_x1,double i_y1,double i_x2,double i_y2,double i_x3,double i_y3,double i_x4,double i_y4,int i_edge_x,int i_edge_y,int i_resolution,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               NyARIntSize out_size=o_out.getSize();\r
+               int xe=out_size.w*i_edge_x/50;\r
+               int ye=out_size.h*i_edge_y/50;\r
+\r
+               //サンプリング解像度で分岐\r
+               if(i_resolution==1){\r
+                       if (!this._perspective_gen.getParam((xe*2+out_size.w),(ye*2+out_size.h),i_x1,i_y1,i_x2,i_y2,i_x3,i_y3,i_x4,i_y4, this.__pickFromRaster_cpara)) {\r
+                               return false;\r
+                       }\r
+                       this._picker.onePixel(xe+LOCAL_LT,ye+LOCAL_LT,this.__pickFromRaster_cpara,i_in_raster,o_out);\r
+               }else{\r
+                       if (!this._perspective_gen.getParam((xe*2+out_size.w)*i_resolution,(ye*2+out_size.h)*i_resolution,i_x1,i_y1,i_x2,i_y2,i_x3,i_y3,i_x4,i_y4, this.__pickFromRaster_cpara)) {\r
+                               return false;\r
+                       }\r
+                       this._picker.multiPixel(xe*i_resolution+LOCAL_LT,ye*i_resolution+LOCAL_LT,this.__pickFromRaster_cpara,i_resolution,i_in_raster,o_out);\r
+               }\r
+               return true;\r
+       }       \r
+}\r
+\r
+\r
+//\r
+//ここから先は入力画像毎のラスタドライバ\r
+//\r
+\r
+interface IPickupRasterImpl\r
+{\r
+       public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException;\r
+       public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException;\r
+}\r
+\r
+final class PPickup_Impl_BYTE1D_R8G8B8_24 implements IPickupRasterImpl\r
+{\r
+       public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));\r
+               //出力形式による分岐\r
+               switch(o_out.getBufferType())\r
+               {\r
+               case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                       onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
+                       break;\r
+               default:\r
+                       onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
+                       break;\r
+               }\r
+               return;\r
+       }\r
+       public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));\r
+               //出力形式による分岐(分解能が高い時は大した差が出ないから、ANYだけ。)\r
+               multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
+               return;         \r
+       }\r
+       \r
+       private void onePixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
+               int[] pat_data=(int[])o_out.getBuffer();\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
+               double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
+               double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
+               int r,g,b;\r
+               int p=0;\r
+               for(int iy=0;iy<out_h;iy++){\r
+                       //解像度分の点を取る。\r
+                       double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
+                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
+                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
+                       \r
+                       for(int ix=0;ix<out_w;ix++){\r
+                               //1ピクセルを作成\r
+                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                               final int bp = (x + y * in_w) * 3;\r
+                               r=(i_in_buf[bp + 0] & 0xff);\r
+                               g=(i_in_buf[bp + 1] & 0xff);\r
+                               b=(i_in_buf[bp + 2] & 0xff);\r
+                               cp7_cy_1_cp6_cx+=cp6;\r
+                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                               cp4_cy_cp5_cp3_cx+=cp3;\r
+                               pat_data[p]=(r<<16)|(g<<8)|((b&0xff));\r
+                               p++;\r
+                       }\r
+                       cp7_cy_1+=cp7;\r
+                       cp1_cy_cp2+=cp1;\r
+                       cp4_cy_cp5+=cp4;\r
+               }\r
+               return;\r
+       }\r
+       private void onePixel_ANY(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
+               double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
+               double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
+               int r,g,b;\r
+               for(int iy=0;iy<out_h;iy++){\r
+                       //解像度分の点を取る。\r
+                       double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
+                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
+                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
+                       \r
+                       for(int ix=0;ix<out_w;ix++){\r
+                               //1ピクセルを作成\r
+                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                               final int bp = (x + y * in_w) * 3;\r
+                               r=(i_in_buf[bp + 0] & 0xff);\r
+                               g=(i_in_buf[bp + 1] & 0xff);\r
+                               b=(i_in_buf[bp + 2] & 0xff);\r
+                               cp7_cy_1_cp6_cx+=cp6;\r
+                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                               cp4_cy_cp5_cp3_cx+=cp3;\r
+\r
+                               out_reader.setPixel(ix,iy,r,g,b);\r
+                       }\r
+                       cp7_cy_1+=cp7;\r
+                       cp1_cy_cp2+=cp1;\r
+                       cp4_cy_cp5+=cp4;\r
+               }\r
+               return;\r
+       }\r
+       private void multiPixel_ANY(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               final int res_pix=i_resolution*i_resolution;\r
+\r
+               INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               double cp2=cpara[2];\r
+               double cp5=cpara[5];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               for(int iy=out_h-1;iy>=0;iy--){\r
+                       //解像度分の点を取る。\r
+                       for(int ix=out_w-1;ix>=0;ix--){\r
+                               int r,g,b;\r
+                               r=g=b=0;\r
+                               int cy=pk_t+iy*i_resolution;\r
+                               int cx=pk_l+ix*i_resolution;\r
+                               double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
+                               double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
+                               double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
+                               for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
+                                       double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
+                                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
+                                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
+                                       for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
+                                               //1ピクセルを作成\r
+                                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                                               final int bp = (x + y * in_w) * 3;\r
+                                               r+=(i_in_buf[bp + 0] & 0xff);\r
+                                               g+=(i_in_buf[bp + 1] & 0xff);\r
+                                               b+=(i_in_buf[bp + 2] & 0xff);\r
+                                               cp7_cy_1_cp6_cx+=cp6;\r
+                                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                                               cp4_cy_cp5_cp3_cx+=cp3;\r
+                                       }\r
+                                       cp7_cy_1_cp6_cx_b+=cp7;\r
+                                       cp1_cy_cp2_cp0_cx_b+=cp1;\r
+                                       cp4_cy_cp5_cp3_cx_b+=cp4;\r
+                               }\r
+                               out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+final class PPickup_Impl_BYTE1D_B8G8R8_24 implements IPickupRasterImpl\r
+{\r
+       public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24));\r
+               //出力形式による分岐\r
+               switch(o_out.getBufferType())\r
+               {\r
+               case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                       onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
+                       break;\r
+               default:\r
+                       onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
+                       break;\r
+               }\r
+               return;\r
+       }\r
+       public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24));\r
+               //出力形式による分岐(分解能が高い時は大した差が出ないから、ANYだけ。)\r
+               multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
+               return;         \r
+       }\r
+       \r
+       private void onePixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
+               int[] pat_data=(int[])o_out.getBuffer();\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
+               double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
+               double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
+               int r,g,b;\r
+               int p=0;\r
+               for(int iy=0;iy<out_h;iy++){\r
+                       //解像度分の点を取る。\r
+                       double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
+                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
+                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
+                       \r
+                       for(int ix=0;ix<out_w;ix++){\r
+                               //1ピクセルを作成\r
+                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                               final int bp = (x + y * in_w) * 3;\r
+                               r=(i_in_buf[bp + 2] & 0xff);\r
+                               g=(i_in_buf[bp + 1] & 0xff);\r
+                               b=(i_in_buf[bp + 0] & 0xff);\r
+                               cp7_cy_1_cp6_cx+=cp6;\r
+                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                               cp4_cy_cp5_cp3_cx+=cp3;\r
+                               pat_data[p]=(r<<16)|(g<<8)|((b&0xff));\r
+                               p++;\r
+                       }\r
+                       cp7_cy_1+=cp7;\r
+                       cp1_cy_cp2+=cp1;\r
+                       cp4_cy_cp5+=cp4;\r
+               }\r
+               return;\r
+       }\r
+       private void onePixel_ANY(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
+               double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
+               double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
+               int r,g,b;\r
+               for(int iy=0;iy<out_h;iy++){\r
+                       //解像度分の点を取る。\r
+                       double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
+                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
+                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
+                       \r
+                       for(int ix=0;ix<out_w;ix++){\r
+                               //1ピクセルを作成\r
+                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                               final int bp = (x + y * in_w) * 3;\r
+                               r=(i_in_buf[bp + 2] & 0xff);\r
+                               g=(i_in_buf[bp + 1] & 0xff);\r
+                               b=(i_in_buf[bp + 0] & 0xff);\r
+                               cp7_cy_1_cp6_cx+=cp6;\r
+                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                               cp4_cy_cp5_cp3_cx+=cp3;\r
+\r
+                               out_reader.setPixel(ix,iy,r,g,b);\r
+                       }\r
+                       cp7_cy_1+=cp7;\r
+                       cp1_cy_cp2+=cp1;\r
+                       cp4_cy_cp5+=cp4;\r
+               }\r
+               return;\r
+       }\r
+       private void multiPixel_ANY(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               final int res_pix=i_resolution*i_resolution;\r
+\r
+               INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               double cp2=cpara[2];\r
+               double cp5=cpara[5];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               for(int iy=out_h-1;iy>=0;iy--){\r
+                       //解像度分の点を取る。\r
+                       for(int ix=out_w-1;ix>=0;ix--){\r
+                               int r,g,b;\r
+                               r=g=b=0;\r
+                               int cy=pk_t+iy*i_resolution;\r
+                               int cx=pk_l+ix*i_resolution;\r
+                               double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
+                               double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
+                               double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
+                               for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
+                                       double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
+                                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
+                                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
+                                       for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
+                                               //1ピクセルを作成\r
+                                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                                               final int bp = (x + y * in_w) * 3;\r
+                                               r+=(i_in_buf[bp + 2] & 0xff);\r
+                                               g+=(i_in_buf[bp + 1] & 0xff);\r
+                                               b+=(i_in_buf[bp + 0] & 0xff);\r
+                                               cp7_cy_1_cp6_cx+=cp6;\r
+                                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                                               cp4_cy_cp5_cp3_cx+=cp3;\r
+                                       }\r
+                                       cp7_cy_1_cp6_cx_b+=cp7;\r
+                                       cp1_cy_cp2_cp0_cx_b+=cp1;\r
+                                       cp4_cy_cp5_cp3_cx_b+=cp4;\r
+                               }\r
+                               out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+final class PPickup_Impl_BYTE1D_B8G8R8X8_32 implements IPickupRasterImpl\r
+{\r
+       public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8X8_32));\r
+               //出力形式による分岐\r
+               switch(o_out.getBufferType())\r
+               {\r
+               case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                       onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
+                       break;\r
+               default:\r
+                       onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
+                       break;\r
+               }\r
+               return;\r
+       }\r
+       public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8X8_32));\r
+               //出力形式による分岐(分解能が高い時は大した差が出ないから、ANYだけ。)\r
+               multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
+               return;         \r
+       }\r
+       \r
+       private void onePixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
+               int[] pat_data=(int[])o_out.getBuffer();\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
+               double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
+               double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
+               int r,g,b;\r
+               int p=0;\r
+               for(int iy=0;iy<out_h;iy++){\r
+                       //解像度分の点を取る。\r
+                       double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
+                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
+                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
+                       \r
+                       for(int ix=0;ix<out_w;ix++){\r
+                               //1ピクセルを作成\r
+                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                               final int bp = (x + y * in_w) * 4;\r
+                               r=(i_in_buf[bp + 2] & 0xff);\r
+                               g=(i_in_buf[bp + 1] & 0xff);\r
+                               b=(i_in_buf[bp + 0] & 0xff);\r
+                               cp7_cy_1_cp6_cx+=cp6;\r
+                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                               cp4_cy_cp5_cp3_cx+=cp3;\r
+                               pat_data[p]=(r<<16)|(g<<8)|((b&0xff));\r
+                               p++;\r
+                       }\r
+                       cp7_cy_1+=cp7;\r
+                       cp1_cy_cp2+=cp1;\r
+                       cp4_cy_cp5+=cp4;\r
+               }\r
+               return;\r
+       }\r
+       private void onePixel_ANY(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
+               double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
+               double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
+               int r,g,b;\r
+               for(int iy=0;iy<out_h;iy++){\r
+                       //解像度分の点を取る。\r
+                       double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
+                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
+                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
+                       \r
+                       for(int ix=0;ix<out_w;ix++){\r
+                               //1ピクセルを作成\r
+                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                               final int bp = (x + y * in_w) * 4;\r
+                               r=(i_in_buf[bp + 2] & 0xff);\r
+                               g=(i_in_buf[bp + 1] & 0xff);\r
+                               b=(i_in_buf[bp + 0] & 0xff);\r
+                               cp7_cy_1_cp6_cx+=cp6;\r
+                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                               cp4_cy_cp5_cp3_cx+=cp3;\r
+\r
+                               out_reader.setPixel(ix,iy,r,g,b);\r
+                       }\r
+                       cp7_cy_1+=cp7;\r
+                       cp1_cy_cp2+=cp1;\r
+                       cp4_cy_cp5+=cp4;\r
+               }\r
+               return;\r
+       }\r
+\r
+       private void multiPixel_ANY(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               final int res_pix=i_resolution*i_resolution;\r
+\r
+               INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               double cp2=cpara[2];\r
+               double cp5=cpara[5];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               for(int iy=out_h-1;iy>=0;iy--){\r
+                       //解像度分の点を取る。\r
+                       for(int ix=out_w-1;ix>=0;ix--){\r
+                               int r,g,b;\r
+                               r=g=b=0;\r
+                               int cy=pk_t+iy*i_resolution;\r
+                               int cx=pk_l+ix*i_resolution;\r
+                               double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
+                               double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
+                               double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
+                               for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
+                                       double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
+                                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
+                                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
+                                       for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
+                                               //1ピクセルを作成\r
+                                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                                               final int bp = (x + y * in_w) * 4;\r
+                                               r+=(i_in_buf[bp + 2] & 0xff);\r
+                                               g+=(i_in_buf[bp + 1] & 0xff);\r
+                                               b+=(i_in_buf[bp + 0] & 0xff);\r
+                                               cp7_cy_1_cp6_cx+=cp6;\r
+                                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                                               cp4_cy_cp5_cp3_cx+=cp3;\r
+                                       }\r
+                                       cp7_cy_1_cp6_cx_b+=cp7;\r
+                                       cp1_cy_cp2_cp0_cx_b+=cp1;\r
+                                       cp4_cy_cp5_cp3_cx_b+=cp4;\r
+                               }\r
+                               out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+}\r
+\r
+/**\r
+ * 全種類のNyARRasterを入力できるクラス\r
+ */\r
+final class PPickup_Impl_AnyRaster implements IPickupRasterImpl\r
+{\r
+       private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
+       public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               //出力形式による分岐\r
+               switch(o_out.getBufferType())\r
+               {\r
+               case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                       onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,i_in_raster.getRgbPixelReader(),o_out);\r
+                       break;\r
+               default:\r
+                       onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,i_in_raster.getRgbPixelReader(),o_out);\r
+                       break;\r
+               }\r
+               return;\r
+       }\r
+       public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               //出力形式による分岐\r
+               switch(o_out.getBufferType())\r
+               {\r
+               case NyARBufferType.INT1D_X8R8G8B8_32:\r
+                       multiPixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,i_in_raster.getRgbPixelReader(),o_out);\r
+                       break;\r
+               default:\r
+                       multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,i_in_raster.getRgbPixelReader(),o_out);\r
+                       break;\r
+               }\r
+               return;         \r
+       }\r
+       \r
+       private void onePixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,INyARRgbPixelReader i_in_reader,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
+               final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
+               int[] pat_data=(int[])o_out.getBuffer();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
+               double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
+               double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
+               int p=0;\r
+               for(int iy=out_h-1;iy>=0;iy--){\r
+                       //解像度分の点を取る。\r
+                       double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
+                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
+                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
+                       \r
+                       for(int ix=out_w-1;ix>=0;ix--){\r
+                               //1ピクセルを作成\r
+                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                               i_in_reader.getPixel(x, y, rgb_tmp);\r
+                               cp7_cy_1_cp6_cx+=cp6;\r
+                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                               cp4_cy_cp5_cp3_cx+=cp3;\r
+\r
+                               pat_data[p]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|((rgb_tmp[2]&0xff));\r
+                               p++;\r
+                       }\r
+                       cp7_cy_1+=cp7;\r
+                       cp1_cy_cp2+=cp1;\r
+                       cp4_cy_cp5+=cp4;\r
+               }\r
+               return;\r
+       }\r
+       private void onePixel_ANY(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,INyARRgbPixelReader i_in_reader,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
+               INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
+               double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
+               double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
+               \r
+               for(int iy=0;iy<out_h;iy++){\r
+                       //解像度分の点を取る。\r
+                       double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
+                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
+                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
+                       \r
+                       for(int ix=0;ix<out_w;ix++){\r
+                               //1ピクセルを作成\r
+                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                               i_in_reader.getPixel(x, y, rgb_tmp);\r
+                               cp7_cy_1_cp6_cx+=cp6;\r
+                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                               cp4_cy_cp5_cp3_cx+=cp3;\r
+\r
+                               out_reader.setPixel(ix,iy,rgb_tmp);\r
+                       }\r
+                       cp7_cy_1+=cp7;\r
+                       cp1_cy_cp2+=cp1;\r
+                       cp4_cy_cp5+=cp4;\r
+               }\r
+               return;\r
+       }\r
+\r
+       private void multiPixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,INyARRgbPixelReader i_in_reader,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
+               final int res_pix=i_resolution*i_resolution;\r
+\r
+               final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
+               int[] pat_data=(int[])o_out.getBuffer();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               double cp2=cpara[2];\r
+               double cp5=cpara[5];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               int p=(out_w*out_h-1);\r
+               for(int iy=out_h-1;iy>=0;iy--){\r
+                       //解像度分の点を取る。\r
+                       for(int ix=out_w-1;ix>=0;ix--){\r
+                               int r,g,b;\r
+                               r=g=b=0;\r
+                               int cy=pk_t+iy*i_resolution;\r
+                               int cx=pk_l+ix*i_resolution;\r
+                               double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
+                               double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
+                               double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
+                               for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
+                                       double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
+                                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
+                                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
+                                       for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
+                                               //1ピクセルを作成\r
+                                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                                               i_in_reader.getPixel(x, y, rgb_tmp);\r
+                                               r+=rgb_tmp[0];\r
+                                               g+=rgb_tmp[1];\r
+                                               b+=rgb_tmp[2];\r
+                                               cp7_cy_1_cp6_cx+=cp6;\r
+                                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                                               cp4_cy_cp5_cp3_cx+=cp3;\r
+                                       }\r
+                                       cp7_cy_1_cp6_cx_b+=cp7;\r
+                                       cp1_cy_cp2_cp0_cx_b+=cp1;\r
+                                       cp4_cy_cp5_cp3_cx_b+=cp4;\r
+                               }\r
+                               r/=res_pix;\r
+                               g/=res_pix;\r
+                               b/=res_pix;\r
+                               pat_data[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));\r
+                               p--;\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+       private void multiPixel_ANY(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,INyARRgbPixelReader i_in_reader,INyARRgbRaster o_out)throws NyARException\r
+       {\r
+               final int res_pix=i_resolution*i_resolution;\r
+\r
+               final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
+               INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
+\r
+               //ピクセルリーダーを取得\r
+               double cp0=cpara[0];\r
+               double cp3=cpara[3];\r
+               double cp6=cpara[6];\r
+               double cp1=cpara[1];\r
+               double cp4=cpara[4];\r
+               double cp7=cpara[7];\r
+               double cp2=cpara[2];\r
+               double cp5=cpara[5];\r
+               \r
+               int out_w=o_out.getWidth();\r
+               int out_h=o_out.getHeight();\r
+               for(int iy=out_h-1;iy>=0;iy--){\r
+                       //解像度分の点を取る。\r
+                       for(int ix=out_w-1;ix>=0;ix--){\r
+                               int r,g,b;\r
+                               r=g=b=0;\r
+                               int cy=pk_t+iy*i_resolution;\r
+                               int cx=pk_l+ix*i_resolution;\r
+                               double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
+                               double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
+                               double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
+                               for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
+                                       double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
+                                       double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
+                                       double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
+                                       for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
+                                               //1ピクセルを作成\r
+                                               final double d=1/(cp7_cy_1_cp6_cx);\r
+                                               int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
+                                               int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
+                                               if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
+                                               if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
+                                               \r
+                                               i_in_reader.getPixel(x, y, rgb_tmp);\r
+                                               r+=rgb_tmp[0];\r
+                                               g+=rgb_tmp[1];\r
+                                               b+=rgb_tmp[2];\r
+                                               cp7_cy_1_cp6_cx+=cp6;\r
+                                               cp1_cy_cp2_cp0_cx+=cp0;\r
+                                               cp4_cy_cp5_cp3_cx+=cp3;\r
+                                       }\r
+                                       cp7_cy_1_cp6_cx_b+=cp7;\r
+                                       cp1_cy_cp2_cp0_cx_b+=cp1;\r
+                                       cp4_cy_cp5_cp3_cx_b+=cp4;\r
+                               }\r
+                               out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);\r
+                       }\r
+               }\r
+               return;\r
+       }       \r
+}\r
+\r
+\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_B8G8R8X8_32.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_B8G8R8X8_32.java
new file mode 100644 (file)
index 0000000..5eac630
--- /dev/null
@@ -0,0 +1,96 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+final public class NyARRgbPixelReader_BYTE1D_B8G8R8X8_32 implements INyARRgbPixelReader\r
+{\r
+       protected byte[] _ref_buf;\r
+       private NyARIntSize _ref_size;\r
+\r
+       public NyARRgbPixelReader_BYTE1D_B8G8R8X8_32(byte[] i_ref_buf, NyARIntSize i_size)\r
+       {\r
+               this._ref_buf=i_ref_buf;\r
+               this._ref_size = i_size;\r
+       }\r
+\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+       {\r
+               final byte[] ref_buf =this._ref_buf;\r
+               final int bp = (i_x + i_y * this._ref_size.w) * 4;\r
+               o_rgb[0] = (ref_buf[bp + 2] & 0xff);// R\r
+               o_rgb[1] = (ref_buf[bp + 1] & 0xff);// G\r
+               o_rgb[2] = (ref_buf[bp + 0] & 0xff);// B\r
+               return;\r
+       }\r
+\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+       {\r
+               int bp;\r
+               final int width = this._ref_size.w;\r
+               final byte[] ref_buf =this._ref_buf;\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_buf[bp + 2] & 0xff);// R\r
+                       o_rgb[i * 3 + 1] = (ref_buf[bp + 1] & 0xff);// G\r
+                       o_rgb[i * 3 + 2] = (ref_buf[bp + 0] & 0xff);// B\r
+               }\r
+               return;\r
+       }\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+       {\r
+               final byte[] ref_buf =this._ref_buf;\r
+               final int bp = (i_x + i_y * this._ref_size.w) * 4;\r
+               ref_buf[bp+2] = (byte)i_rgb[0];// R\r
+               ref_buf[bp+1] = (byte)i_rgb[1];// G\r
+               ref_buf[bp+0] = (byte)i_rgb[2];// B     \r
+       }\r
+       public void setPixel(int i_x, int i_y, int i_r,int i_g,int i_b) throws NyARException\r
+       {\r
+               final byte[] ref_buf =this._ref_buf;\r
+               final int bp = (i_x + i_y * this._ref_size.w) * 4;\r
+               ref_buf[bp+2] = (byte)i_r;// R\r
+               ref_buf[bp+1] = (byte)i_g;// G\r
+               ref_buf[bp+0] = (byte)i_b;// B  \r
+       }\r
+       \r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void switchBuffer(Object i_ref_buffer) throws NyARException\r
+       {\r
+               assert(((byte[])i_ref_buffer).length>=this._ref_size.w*this._ref_size.h*4);\r
+               this._ref_buf=(byte[])i_ref_buffer;\r
+       }               \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_B8G8R8_24.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_B8G8R8_24.java
new file mode 100644 (file)
index 0000000..93da2b5
--- /dev/null
@@ -0,0 +1,100 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * byte[]配列に、パディング無しの8bit画素値が、BGRBGRの順で並んでいる\r
+ * バッファに使用できるピクセルリーダー\r
+ *\r
+ */\r
+final public class NyARRgbPixelReader_BYTE1D_B8G8R8_24 implements INyARRgbPixelReader\r
+{\r
+       protected byte[] _ref_buf;\r
+\r
+       private NyARIntSize _size;\r
+\r
+       public NyARRgbPixelReader_BYTE1D_B8G8R8_24(byte[] i_buf, NyARIntSize i_size)\r
+       {\r
+               this._ref_buf = i_buf;\r
+               this._size = i_size;\r
+       }\r
+\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+       {\r
+               final byte[] ref_buf = this._ref_buf;\r
+               final int bp = (i_x + i_y * this._size.w) * 3;\r
+               o_rgb[0] = (ref_buf[bp + 2] & 0xff);// R\r
+               o_rgb[1] = (ref_buf[bp + 1] & 0xff);// G\r
+               o_rgb[2] = (ref_buf[bp + 0] & 0xff);// B\r
+               return;\r
+       }\r
+\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+       {\r
+               int bp;\r
+               final int width = this._size.w;\r
+               final byte[] ref_buf = this._ref_buf;\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_buf[bp + 2] & 0xff);// R\r
+                       o_rgb[i * 3 + 1] = (ref_buf[bp + 1] & 0xff);// G\r
+                       o_rgb[i * 3 + 2] = (ref_buf[bp + 0] & 0xff);// B\r
+               }\r
+               return;\r
+       }\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+       {\r
+               final byte[] ref_buf = this._ref_buf;\r
+               final int idx=(i_y*this._size.w+i_x)*3;\r
+               ref_buf[idx + 0] = (byte)i_rgb[2];// B\r
+               ref_buf[idx + 1] = (byte)i_rgb[1];// G\r
+               ref_buf[idx + 2] = (byte)i_rgb[0];// R\r
+       }\r
+       public void setPixel(int i_x, int i_y, int i_r,int i_g,int i_b) throws NyARException\r
+       {\r
+               final byte[] ref_buf = this._ref_buf;\r
+               final int idx=(i_y*this._size.w+i_x)*3;\r
+               ref_buf[idx + 0] = (byte)i_b;// B\r
+               ref_buf[idx + 1] = (byte)i_g;// G\r
+               ref_buf[idx + 2] = (byte)i_r;// R\r
+       }\r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void switchBuffer(Object i_ref_buffer) throws NyARException\r
+       {\r
+               assert(((byte[])i_ref_buffer).length>=this._size.w*this._size.h*3);\r
+               this._ref_buf=(byte[])i_ref_buffer;\r
+       }       \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_R8G8B8_24.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_R8G8B8_24.java
new file mode 100644 (file)
index 0000000..168d96c
--- /dev/null
@@ -0,0 +1,100 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * byte[]配列に、パディング無しの8bit画素値が、RGBRGBの順で並んでいる\r
+ * バッファに使用できるピクセルリーダー\r
+ *\r
+ */\r
+final public class NyARRgbPixelReader_BYTE1D_R8G8B8_24 implements INyARRgbPixelReader\r
+{\r
+       protected byte[] _ref_buf;\r
+\r
+       private NyARIntSize _size;\r
+\r
+       public NyARRgbPixelReader_BYTE1D_R8G8B8_24(byte[] i_buf, NyARIntSize i_size)\r
+       {\r
+               this._ref_buf = i_buf;\r
+               this._size = i_size;\r
+       }\r
+\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+       {\r
+               final byte[] ref_buf = this._ref_buf;\r
+               final int bp = (i_x + i_y * this._size.w) * 3;\r
+               o_rgb[0] = (ref_buf[bp + 0] & 0xff);// R\r
+               o_rgb[1] = (ref_buf[bp + 1] & 0xff);// G\r
+               o_rgb[2] = (ref_buf[bp + 2] & 0xff);// B\r
+               return;\r
+       }\r
+\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+       {\r
+               int bp;\r
+               final int width = this._size.w;\r
+               final byte[] ref_buf = this._ref_buf;\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_buf[bp + 0] & 0xff);// R\r
+                       o_rgb[i * 3 + 1] = (ref_buf[bp + 1] & 0xff);// G\r
+                       o_rgb[i * 3 + 2] = (ref_buf[bp + 2] & 0xff);// B\r
+               }\r
+               return;\r
+       }\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+       {\r
+               final byte[] ref_buf = this._ref_buf;\r
+               final int idx=(i_y*this._size.w+i_x)*3;\r
+               ref_buf[idx + 0] = (byte)i_rgb[0];// R\r
+               ref_buf[idx + 1] = (byte)i_rgb[1];// G\r
+               ref_buf[idx + 2] = (byte)i_rgb[2];// B\r
+       }\r
+       public void setPixel(int i_x, int i_y, int i_r,int i_g,int i_b) throws NyARException\r
+       {\r
+               final byte[] ref_buf = this._ref_buf;\r
+               final int idx=(i_y*this._size.w+i_x)*3;\r
+               ref_buf[idx + 0] = (byte)i_r;// R\r
+               ref_buf[idx + 1] = (byte)i_g;// G\r
+               ref_buf[idx + 2] = (byte)i_b;// B\r
+       }\r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void switchBuffer(Object i_ref_buffer) throws NyARException\r
+       {\r
+               assert(((byte[])i_ref_buffer).length>=this._size.w*this._size.h*3);\r
+               this._ref_buf=(byte[])i_ref_buffer;\r
+       }       \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_X8R8G8B8_32.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_BYTE1D_X8R8G8B8_32.java
new file mode 100644 (file)
index 0000000..90099a1
--- /dev/null
@@ -0,0 +1,92 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * byte[]配列に、パディング無しの8bit画素値が、XRGBXRGBの順で並んでいる\r
+ * バッファに使用できるピクセルリーダー\r
+ *\r
+ */\r
+final public class NyARRgbPixelReader_BYTE1D_X8R8G8B8_32 implements INyARRgbPixelReader\r
+{\r
+       protected byte[] _ref_buf;\r
+\r
+       private NyARIntSize _size;\r
+\r
+       public NyARRgbPixelReader_BYTE1D_X8R8G8B8_32(byte[] i_buf, NyARIntSize i_size)\r
+       {\r
+               this._ref_buf = i_buf;\r
+               this._size = i_size;\r
+       }\r
+\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+       {\r
+               final byte[] ref_buf = this._ref_buf;\r
+               final int bp = (i_x + i_y * this._size.w) * 4;\r
+               o_rgb[0] = (ref_buf[bp + 1] & 0xff);// R\r
+               o_rgb[1] = (ref_buf[bp + 2] & 0xff);// G\r
+               o_rgb[2] = (ref_buf[bp + 3] & 0xff);// B\r
+               return;\r
+       }\r
+\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+       {\r
+               int bp;\r
+               final int width = this._size.w;\r
+               final byte[] ref_buf = this._ref_buf;\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_buf[bp + 1] & 0xff);// R\r
+                       o_rgb[i * 3 + 1] = (ref_buf[bp + 2] & 0xff);// G\r
+                       o_rgb[i * 3 + 2] = (ref_buf[bp + 3] & 0xff);// B\r
+               }\r
+               return;\r
+       }\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void setPixel(int i_x, int i_y, int i_r,int i_g,int i_b) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void switchBuffer(Object i_ref_buffer) throws NyARException\r
+       {\r
+               assert(((byte[])i_ref_buffer).length>=this._size.w*this._size.h*4);\r
+               this._ref_buf=(byte[])i_ref_buffer;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_GRAY_8.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_GRAY_8.java
new file mode 100644 (file)
index 0000000..e6cf4bb
--- /dev/null
@@ -0,0 +1,80 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+final public class NyARRgbPixelReader_INT1D_GRAY_8 implements INyARRgbPixelReader\r
+{\r
+       protected int[] _ref_buf;\r
+\r
+       private NyARIntSize _size;\r
+\r
+       public NyARRgbPixelReader_INT1D_GRAY_8(int[] i_buf, NyARIntSize i_size)\r
+       {\r
+               this._ref_buf = i_buf;\r
+               this._size = i_size;\r
+       }\r
+\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+       {\r
+               o_rgb[0] = o_rgb[1]=o_rgb[2]=this._ref_buf[i_x + i_y * this._size.w];\r
+               return;\r
+       }\r
+\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+       {\r
+               final int width = this._size.w;\r
+               final int[] ref_buf = this._ref_buf;\r
+               for (int i = i_num - 1; i >= 0; i--){\r
+                       o_rgb[i * 3 + 0] = o_rgb[i * 3 + 1]=o_rgb[i * 3 + 2]=ref_buf[i_x[i] + i_y[i] * width];\r
+               }\r
+               return;\r
+       }\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void setPixel(int i_x, int i_y, int i_r,int i_g,int i_b) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void switchBuffer(Object i_ref_buffer) throws NyARException\r
+       {\r
+               assert(((int[])i_ref_buffer).length>=this._size.w*this._size.h);\r
+               this._ref_buf=(int[])i_ref_buffer;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_X8R8G8B8_32.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_X8R8G8B8_32.java
new file mode 100644 (file)
index 0000000..f11122e
--- /dev/null
@@ -0,0 +1,87 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+final public class NyARRgbPixelReader_INT1D_X8R8G8B8_32 implements INyARRgbPixelReader\r
+{\r
+       protected int[] _ref_buf;\r
+\r
+       private NyARIntSize _size;\r
+\r
+       public NyARRgbPixelReader_INT1D_X8R8G8B8_32(int[] i_buf, NyARIntSize i_size)\r
+       {\r
+               this._ref_buf = i_buf;\r
+               this._size = i_size;\r
+       }\r
+\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+       {\r
+               final int rgb= this._ref_buf[i_x + i_y * this._size.w];\r
+               o_rgb[0] = (rgb>>16)&0xff;// R\r
+               o_rgb[1] = (rgb>>8)&0xff;// G\r
+               o_rgb[2] = rgb&0xff;// B\r
+               return;\r
+       }\r
+\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+       {\r
+               final int width = this._size.w;\r
+               final int[] ref_buf = this._ref_buf;\r
+               for (int i = i_num - 1; i >= 0; i--){\r
+                       int rgb=ref_buf[i_x[i] + i_y[i] * width];\r
+                       o_rgb[i * 3 + 0] = (rgb>>16)&0xff;// R\r
+                       o_rgb[i * 3 + 1] = (rgb>>8)&0xff;// G\r
+                       o_rgb[i * 3 + 2] = rgb&0xff;// B\r
+               }\r
+               return;\r
+       }\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+       {\r
+               this._ref_buf[i_x + i_y * this._size.w]=(i_rgb[0]<<16)|(i_rgb[1]<<8)|(i_rgb[2]);\r
+       }\r
+       public void setPixel(int i_x, int i_y, int i_r,int i_g,int i_b) throws NyARException\r
+       {\r
+               this._ref_buf[i_x + i_y * this._size.w]=(i_r<<16)|(i_g<<8)|(i_b);\r
+       }\r
+       \r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void switchBuffer(Object i_ref_buffer) throws NyARException\r
+       {\r
+               assert(((int[])i_ref_buffer).length>=this._size.w*this._size.h);\r
+               this._ref_buf=(int[])i_ref_buffer;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_WORD1D_R5G6B5_16LE.java b/lib/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_WORD1D_R5G6B5_16LE.java
new file mode 100644 (file)
index 0000000..e89435f
--- /dev/null
@@ -0,0 +1,97 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * 主にWindowsMobileのRGB565フォーマット読み出し用\r
+ */\r
+final public class NyARRgbPixelReader_WORD1D_R5G6B5_16LE implements INyARRgbPixelReader\r
+{\r
+       protected short[] _ref_buf;\r
+\r
+       private NyARIntSize _size;\r
+\r
+       public NyARRgbPixelReader_WORD1D_R5G6B5_16LE(short[] i_buf, NyARIntSize i_size)\r
+       {\r
+               this._ref_buf = i_buf;\r
+               this._size = i_size;\r
+       }\r
+\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+       {\r
+        short[] buf = this._ref_buf;\r
+        int y = i_y;\r
+        int idx = y * this._size.w + i_x;\r
+        int pixcel =(int)(buf[idx] &0xffff);\r
+\r
+        o_rgb[0] = (int)((pixcel & 0xf800) >> 8);//R\r
+        o_rgb[1] = (int)((pixcel & 0x07e0) >> 3);//G\r
+        o_rgb[2] = (int)((pixcel & 0x001f) << 3);//B\r
+               return;\r
+       }\r
+\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+       {\r
+        int stride = this._size.w;\r
+        short[] buf = this._ref_buf;\r
+\r
+        for (int i = i_num - 1; i >= 0; i--)\r
+        {\r
+            int idx = i_y[i] * stride + i_x[i];\r
+\r
+            int pixcel =(int)(buf[idx] &0xffff);\r
+            o_rgb[i * 3 + 0] = (int)((pixcel & 0xf800) >> 8);//R\r
+            o_rgb[i * 3 + 1] = (int)((pixcel & 0x07e0) >> 3);//G\r
+            o_rgb[i * 3 + 2] = (int)((pixcel & 0x001f) << 3);//B\r
+        }              \r
+               return;\r
+       }\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void setPixel(int i_x, int i_y, int i_r,int i_g,int i_b) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       \r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void switchBuffer(Object i_ref_buffer) throws NyARException\r
+       {\r
+               assert(((short[])i_ref_buffer).length>=this._size.w*this._size.h);\r
+               this._ref_buf=(short[])i_ref_buffer;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARContourPickup.java b/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARContourPickup.java
new file mode 100644 (file)
index 0000000..3a9585a
--- /dev/null
@@ -0,0 +1,236 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 輪郭線を取得するクラスです。\r
+ *\r
+ */\r
+public class NyARContourPickup\r
+{\r
+       //巡回参照できるように、テーブルを二重化\r
+       //                                           0  1  2  3  4  5  6  7   0  1  2  3  4  5  6\r
+       protected final static int[] _getContour_xdir = { 0, 1, 1, 1, 0,-1,-1,-1 , 0, 1, 1, 1, 0,-1,-1};\r
+       protected final static int[] _getContour_ydir = {-1,-1, 0, 1, 1, 1, 0,-1 ,-1,-1, 0, 1, 1, 1, 0};\r
+       public boolean getContour(NyARBinRaster i_raster,int i_entry_x,int i_entry_y,NyARIntCoordinates o_coord) throws NyARException\r
+       {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.INT1D_BIN_8));\r
+               NyARIntSize s=i_raster.getSize();\r
+               return impl_getContour(i_raster,0,0,s.w-1,s.h-1,0,i_entry_x,i_entry_y,o_coord);\r
+       }\r
+       public boolean getContour(NyARBinRaster i_raster,NyARIntRect i_area,int i_entry_x,int i_entry_y,NyARIntCoordinates o_coord) throws NyARException\r
+       {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.INT1D_BIN_8));\r
+               return impl_getContour(i_raster,i_area.x,i_area.y,i_area.x+i_area.w-1,i_area.h+i_area.y-1,0,i_entry_x,i_entry_y,o_coord);\r
+       }\r
+       /**\r
+        * ラスタの指定点を基点に、輪郭線を抽出します。開始点は、輪郭の一部、かつ左上のエッジで有る必要があります。\r
+        * @param i_raster\r
+        * 輪郭線を抽出するラスタを指定します。\r
+        * @param i_th\r
+        * 輪郭とみなす暗点の敷居値を指定します。\r
+        * @param i_entry_x\r
+        * 輪郭抽出の開始点です。\r
+        * @param i_entry_y\r
+        * 輪郭抽出の開始点です。\r
+        * @param o_coord\r
+        * 輪郭点を格納する配列を指定します。i_array_sizeよりも大きなサイズの配列が必要です。\r
+        * @return\r
+        * 輪郭の抽出に成功するとtrueを返します。輪郭抽出に十分なバッファが無いと、falseになります。\r
+        * @throws NyARException\r
+        */\r
+       public boolean getContour(NyARGrayscaleRaster i_raster,int i_th,int i_entry_x,int i_entry_y,NyARIntCoordinates o_coord) throws NyARException\r
+       {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+               NyARIntSize s=i_raster.getSize();\r
+               return impl_getContour(i_raster,0,0,s.w-1,s.h-1,i_th,i_entry_x,i_entry_y,o_coord);\r
+       }\r
+       public boolean getContour(NyARGrayscaleRaster i_raster,NyARIntRect i_area,int i_th,int i_entry_x,int i_entry_y,NyARIntCoordinates o_coord) throws NyARException\r
+       {\r
+               assert(i_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));\r
+               return impl_getContour(i_raster,i_area.x,i_area.y,i_area.x+i_area.w-1,i_area.h+i_area.y-1,i_th,i_entry_x,i_entry_y,o_coord);\r
+       }\r
+       \r
+       /**\r
+        * 輪郭線抽出関数の実体です。\r
+        * @param i_raster\r
+        * @param i_l\r
+        * @param i_t\r
+        * @param i_r\r
+        * @param i_b\r
+        * @param i_th\r
+        * @param i_entry_x\r
+        * @param i_entry_y\r
+        * @param o_coord\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       private boolean impl_getContour(INyARRaster i_raster,int i_l,int i_t,int i_r,int i_b,int i_th,int i_entry_x,int i_entry_y,NyARIntCoordinates o_coord) throws NyARException\r
+       {\r
+               assert(i_t<=i_entry_x);\r
+               NyARIntPoint2d[] coord=o_coord.items;\r
+               final int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};\r
+               final int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};\r
+\r
+               final int[] buf=(int[])i_raster.getBuffer();\r
+               final int width=i_raster.getWidth();\r
+               //クリップ領域の上端に接しているポイントを得る。\r
+\r
+\r
+               int max_coord=o_coord.items.length;\r
+               int coord_num = 1;\r
+               coord[0].x = i_entry_x;\r
+               coord[0].y = i_entry_y;\r
+               int dir = 5;\r
+\r
+               int c = i_entry_x;\r
+               int r = i_entry_y;\r
+               for (;;) {\r
+                       dir = (dir + 5) % 8;//dirの正規化\r
+                       //ここは頑張ればもっと最適化できると思うよ。\r
+                       //4隅以外の境界接地の場合に、境界チェックを省略するとかね。\r
+                       if(c>i_l && c<i_r && r>i_t && r<i_b){\r
+                               for(;;){//gotoのエミュレート用のfor文\r
+                                       //境界に接していないとき(暗点判定)\r
+                                       if (buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+                                               break;\r
+                                       }\r
+\r
+                                       //8方向全て調べたけどラベルが無いよ?\r
+                                       throw new NyARException();                      \r
+                               }\r
+                       }else{\r
+                               //境界に接しているとき\r
+                               int i;\r
+                               for (i = 0; i < 8; i++){                                \r
+                                       final int x=c + xdir[dir];\r
+                                       final int y=r + ydir[dir];\r
+                                       //境界チェック\r
+                                       if(x>=i_l && x<=i_r && y>=i_t && y<=i_b){\r
+                                               if (buf[(y)*width+(x)] <= i_th) {\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       dir++;//倍長テーブルを参照するので問題なし\r
+                               }\r
+                               if (i == 8) {\r
+                                       //8方向全て調べたけどラベルが無いよ?\r
+                                       throw new NyARException();// return(-1);\r
+                               }                               \r
+                       }\r
+\r
+                       // xcoordとycoordをc,rにも保存\r
+                       c = c + xdir[dir];\r
+                       r = r + ydir[dir];\r
+                       coord[coord_num].x = c;\r
+                       coord[coord_num].y = r;\r
+                       //終了条件判定\r
+                       if (c == i_entry_x && r == i_entry_y){\r
+                               //開始点と同じピクセルに到達したら、終点の可能性がある。\r
+                               coord_num++;\r
+                               //末端のチェック\r
+                               if (coord_num == max_coord) {\r
+                                       //輪郭bufが末端に達した\r
+                                       return false;\r
+                               }                               \r
+                               //末端候補の次のピクセルを調べる\r
+                               dir = (dir + 5) % 8;//dirの正規化\r
+                               int i;\r
+                               for (i = 0; i < 8; i++){                                \r
+                                       final int x=c + xdir[dir];\r
+                                       final int y=r + ydir[dir];\r
+                                       //境界チェック\r
+                                       if(x>=i_l && x<=i_r && y>=i_t && y<=i_b){\r
+                                               if (buf[(y)*width+(x)] <= i_th) {\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       dir++;//倍長テーブルを参照するので問題なし\r
+                               }\r
+                               if (i == 8) {\r
+                                       //8方向全て調べたけどラベルが無いよ?\r
+                                       throw new NyARException();\r
+                               }\r
+                               //得たピクセルが、[1]と同じならば、末端である。\r
+                               c = c + xdir[dir];\r
+                               r = r + ydir[dir];\r
+                               if(coord[1].x ==c && coord[1].y ==r){\r
+                                       //終点に達している。\r
+                                       o_coord.length=coord_num;\r
+                                       break;\r
+                               }else{\r
+                                       //終点ではない。\r
+                                       coord[coord_num].x = c;\r
+                                       coord[coord_num].y = r;\r
+                               }\r
+                       }\r
+                       coord_num++;\r
+                       //末端のチェック\r
+                       if (coord_num == max_coord) {\r
+                               //輪郭が末端に達した\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARContourPickup_ARToolKit.java b/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARContourPickup_ARToolKit.java
new file mode 100644 (file)
index 0000000..d09ec11
--- /dev/null
@@ -0,0 +1,135 @@
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntCoordinates;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * NyARLabelingImageから、輪郭線を抽出します。\r
+ * @bug\r
+ * この輪郭線抽出は、1ドット幅の輪郭を正しく抽出できません。ARToolKit互換の画像処理では問題になることは少ないので、\r
+ * 大きな影響はありませんが、必要に応じてNyARContourPickupを参考に直してください。\r
+ */\r
+public class NyARContourPickup_ARToolKit extends NyARContourPickup\r
+{\r
+       /**\r
+        * ラスタの指定点を基点に、輪郭線を抽出します。開始点は、輪郭の一部、かつ左上のエッジで有る必要があります。\r
+        * @param i_raster\r
+        * 輪郭線を抽出するラスタを指定します。\r
+        * @param i_entry_x\r
+        * 輪郭抽出の開始点です。\r
+        * @param i_entry_y\r
+        * 輪郭抽出の開始点です。\r
+        * @param i_array_size\r
+        * o_coordの有効長を指定します。\r
+        * @param o_coord\r
+        * 輪郭点を格納するオブジェクトを指定します。\r
+        * @return\r
+        * 輪郭線がo_coordの長さを超えた場合、falseを返します。\r
+        * @throws NyARException\r
+        */\r
+       public boolean getContour(NyARLabelingImage i_raster,int i_entry_x,int i_entry_y,NyARIntCoordinates o_coord) throws NyARException\r
+       {       \r
+               final int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};\r
+               final int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};\r
+\r
+               final int[] i_buf=(int[])i_raster.getBuffer();\r
+               final int width=i_raster.getWidth();\r
+               final int height=i_raster.getHeight();\r
+               final NyARIntPoint2d[] coord=o_coord.items;\r
+               int i_array_size=o_coord.items.length;\r
+               //クリップ領域の上端に接しているポイントを得る。\r
+               int sx=i_entry_x;\r
+               int sy=i_entry_y;\r
+\r
+               int coord_num = 1;\r
+               coord[0].x = sx;\r
+               coord[0].y = sy;\r
+               int dir = 5;\r
+\r
+               int c = coord[0].x;\r
+               int r = coord[0].y;\r
+               for (;;) {\r
+                       dir = (dir + 5) % 8;//dirの正規化\r
+                       //ここは頑張ればもっと最適化できると思うよ。\r
+                       //4隅以外の境界接地の場合に、境界チェックを省略するとかね。\r
+                       if(c>=1 && c<width-1 && r>=1 && r<height-1){\r
+                               for(;;){//gotoのエミュレート用のfor文\r
+                                       //境界に接していないとき\r
+                                       if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+                                               break;\r
+                                       }\r
+                                       dir++;\r
+                                       if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+                                               break;\r
+                                       }\r
+                                       //8方向全て調べたけどラベルが無いよ?\r
+                                       throw new NyARException();                      \r
+                               }\r
+                       }else{\r
+                               //境界に接しているとき\r
+                               int i;\r
+                               for (i = 0; i < 8; i++){                                \r
+                                       final int x=c + xdir[dir];\r
+                                       final int y=r + ydir[dir];\r
+                                       //境界チェック\r
+                                       if(x>=0 && x<width && y>=0 && y<height){\r
+                                               if (i_buf[(y)*width+(x)] > 0) {\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       dir++;//倍長テーブルを参照するので問題なし\r
+                               }\r
+                               if (i == 8) {\r
+                                       //8方向全て調べたけどラベルが無いよ?\r
+                                       throw new NyARException();// return(-1);\r
+                               }                               \r
+                       }\r
+                       \r
+                       dir=dir% 8;//dirの正規化\r
+\r
+                       // xcoordとycoordをc,rにも保存\r
+                       c = c + xdir[dir];\r
+                       r = r + ydir[dir];\r
+                       coord[coord_num].x = c;\r
+                       coord[coord_num].y = r;\r
+                       // 終了条件判定\r
+                       if (c == sx && r == sy){\r
+                               coord_num++;\r
+                               break;\r
+                       }\r
+                       coord_num++;\r
+                       if (coord_num == i_array_size) {\r
+                               //輪郭が末端に達した\r
+                               return false;\r
+                       }\r
+               }\r
+               o_coord.length=coord_num;\r
+               return true;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARCoord2Linear.java b/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARCoord2Linear.java
new file mode 100644 (file)
index 0000000..5f08bab
--- /dev/null
@@ -0,0 +1,142 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.param.NyARObserv2IdealMap;\r
+import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;\r
+import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntCoordinates;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+\r
+\r
+\r
+/**\r
+ * 頂点集合を一次方程式のパラメータに変換します。\r
+ * \r
+ *\r
+ */\r
+public class NyARCoord2Linear\r
+{\r
+       private final double[] _xpos;\r
+       private final double[] _ypos;   \r
+       private final INyARPca2d _pca;\r
+       private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();\r
+       private final double[] __getSquareLine_mean=new double[2];\r
+       private final double[] __getSquareLine_ev=new double[2];\r
+       private final NyARObserv2IdealMap _dist_factor;\r
+       /**\r
+        * @param i_size\r
+        * @param i_distfactor_ref\r
+        * カメラ歪みを補正する場合のパラメータを指定します。\r
+        * nullの場合、補正マップを使用しません。\r
+        */\r
+       public NyARCoord2Linear(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor)\r
+       {\r
+               if(i_distfactor!=null){\r
+                       this._dist_factor = new NyARObserv2IdealMap(i_distfactor,i_size);\r
+               }else{\r
+                       this._dist_factor=null;\r
+               }\r
+               // 輪郭バッファ\r
+               this._pca=new NyARPca2d_MatrixPCA_O2();\r
+               this._xpos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height\r
+               this._ypos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height\r
+               return;\r
+       }\r
+\r
+\r
+       /**\r
+        * 輪郭点集合からay+bx+c=0の直線式を計算します。\r
+        * @param i_st\r
+        * @param i_ed\r
+        * @param i_coord\r
+        * @param o_line\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public boolean coord2Line(int i_st,int i_ed,NyARIntCoordinates i_coord, NyARLinear o_line) throws NyARException\r
+       {\r
+               //頂点を取得\r
+               int n,st,ed;\r
+               double w1;\r
+               int cood_num=i_coord.length;\r
+       \r
+               //探索区間の決定\r
+               if(i_ed>=i_st){\r
+                       //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき\r
+                       w1 = (double) (i_ed - i_st + 1) * 0.05 + 0.5;\r
+                       //探索区間の決定\r
+                       st = (int) (i_st+w1);\r
+                       ed = (int) (i_ed - w1);\r
+               }else{\r
+                       //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき\r
+                       w1 = (double)((i_ed+cood_num-i_st+1)%cood_num) * 0.05 + 0.5;\r
+                       //探索区間の決定\r
+                       st = ((int) (i_st+w1))%cood_num;\r
+                       ed = ((int) (i_ed+cood_num-w1))%cood_num;\r
+               }\r
+               //探索区間数を確認\r
+               if(st<=ed){\r
+                       //探索区間は1区間\r
+                       n = ed - st + 1;\r
+                       if(this._dist_factor!=null){\r
+                               this._dist_factor.observ2IdealBatch(i_coord.items, st, n,this._xpos,this._ypos,0);\r
+                       }\r
+               }else{\r
+                       //探索区間は2区間\r
+                       n=ed+1+cood_num-st;\r
+                       if(this._dist_factor!=null){\r
+                               this._dist_factor.observ2IdealBatch(i_coord.items, st,cood_num-st,this._xpos,this._ypos,0);\r
+                               this._dist_factor.observ2IdealBatch(i_coord.items, 0,ed+1,this._xpos,this._ypos,cood_num-st);\r
+                       }\r
+               }\r
+               //要素数の確認\r
+               if (n < 2) {\r
+                       // nが2以下でmatrix.PCAを計算することはできないので、エラー\r
+                       return false;\r
+               }\r
+               //主成分分析する。\r
+               final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;\r
+               final double[] mean=this.__getSquareLine_mean;\r
+\r
+               \r
+               this._pca.pca(this._xpos,this._ypos,n,evec, this.__getSquareLine_ev,mean);\r
+               o_line.a = evec.m01;// line[i][0] = evec->m[1];\r
+               o_line.b = -evec.m00;// line[i][1] = -evec->m[0];\r
+               o_line.c = -(o_line.a * mean[0] + o_line.b * mean[1]);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);\r
+\r
+               return true;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARCoord2SquareVertexIndexes.java b/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARCoord2SquareVertexIndexes.java
new file mode 100644 (file)
index 0000000..de6e045
--- /dev/null
@@ -0,0 +1,253 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * 座標店集合(輪郭線)から、四角系の頂点候補点を計算します。\r
+ *\r
+ */\r
+public class NyARCoord2SquareVertexIndexes\r
+{\r
+       private static final double VERTEX_FACTOR = 1.0;// 線検出のファクタ     \r
+       private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();\r
+       private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();\r
+       public NyARCoord2SquareVertexIndexes()\r
+       {\r
+               return;\r
+       }\r
+       /**\r
+        * 座標集合から、頂点候補になりそうな場所を4箇所探して、そのインデクス番号を返します。\r
+        * @param i_coord\r
+        * 輪郭を格納した配列です。\r
+        * @param i_area\r
+        * @param o_vertex\r
+        * @return\r
+        */\r
+       public boolean getVertexIndexes(NyARIntCoordinates i_coord, int i_area, int[] o_vertex)\r
+       {\r
+               final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;\r
+               final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;\r
+               int i_coord_num=i_coord.length;\r
+               int vertex1_index=getFarPoint(i_coord.items,i_coord_num,0);\r
+               int prev_vertex_index=(vertex1_index+i_coord_num)%i_coord_num;\r
+               int v1=getFarPoint(i_coord.items,i_coord_num,vertex1_index);\r
+               final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;\r
+\r
+               o_vertex[0] = vertex1_index;\r
+\r
+               if (!wv1.getVertex(i_coord.items,i_coord_num, vertex1_index, v1, thresh)) {\r
+                       return false;\r
+               }\r
+               if (!wv2.getVertex(i_coord.items,i_coord_num, v1,prev_vertex_index, thresh)) {\r
+                       return false;\r
+               }\r
+\r
+               int v2;\r
+               if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
+                       o_vertex[1] = wv1.vertex[0];\r
+                       o_vertex[2] = v1;\r
+                       o_vertex[3] = wv2.vertex[0];\r
+               } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {\r
+                       //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。\r
+                       if(v1>=vertex1_index){\r
+                               v2 = (v1-vertex1_index)/2+vertex1_index;\r
+                       }else{\r
+                               v2 = ((v1+i_coord_num-vertex1_index)/2+vertex1_index)%i_coord_num;\r
+                       }\r
+                       if (!wv1.getVertex(i_coord.items,i_coord_num, vertex1_index, v2, thresh)) {\r
+                               return false;\r
+                       }\r
+                       if (!wv2.getVertex(i_coord.items,i_coord_num, v2, v1, thresh)) {\r
+                               return false;\r
+                       }\r
+                       if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
+                               o_vertex[1] = wv1.vertex[0];\r
+                               o_vertex[2] = wv2.vertex[0];\r
+                               o_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+ end_of_coord)/2;\r
+                       if(v1<=prev_vertex_index){\r
+                               v2 = (v1+prev_vertex_index)/2;\r
+                       }else{\r
+                               v2 = ((v1+i_coord_num+prev_vertex_index)/2)%i_coord_num;\r
+                               \r
+                       }\r
+                       if (!wv1.getVertex(i_coord.items,i_coord_num, v1, v2, thresh)) {\r
+                               return false;\r
+                       }\r
+                       if (!wv2.getVertex(i_coord.items,i_coord_num, v2, prev_vertex_index, thresh)) {\r
+                               return false;\r
+                       }\r
+                       if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
+                               o_vertex[1] = v1;\r
+                               o_vertex[2] = wv1.vertex[0];\r
+                               o_vertex[3] = wv2.vertex[0];\r
+                       } else {\r
+                               \r
+                               return false;\r
+                       }\r
+               } else {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * i_pointの輪郭座標から、最も遠方にある輪郭座標のインデクスを探します。\r
+        * @param i_xcoord\r
+        * @param i_ycoord\r
+        * @param i_coord_num\r
+        * @return\r
+        */\r
+       private static int getFarPoint(NyARIntPoint2d[] i_coord,int i_coord_num,int i_point)\r
+       {\r
+               //\r
+               final int sx = i_coord[i_point].x;\r
+               final int sy = i_coord[i_point].y;\r
+               int d = 0;\r
+               int w, x, y;\r
+               int ret = 0;\r
+               for (int i = i_point+1; i < i_coord_num; i++) {\r
+                       x = i_coord[i].x - sx;\r
+                       y = i_coord[i].y - sy;\r
+                       w = x * x + y * y;\r
+                       if (w > d) {\r
+                               d = w;\r
+                               ret = i;\r
+                       }\r
+               }\r
+               for (int i = 0; i < i_point; i++) {\r
+                       x = i_coord[i].x - sx;\r
+                       y = i_coord[i].y - sy;\r
+                       w = x * x + y * y;\r
+                       if (w > d) {\r
+                               d = w;\r
+                               ret = i;\r
+                       }\r
+               }               \r
+               return ret;\r
+       }       \r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * get_vertex関数を切り離すためのクラス\r
+ * \r
+ */\r
+final class NyARVertexCounter\r
+{\r
+       public final int[] vertex = new int[10];// 6まで削れる\r
+\r
+       public int number_of_vertex;\r
+\r
+       private double thresh;\r
+\r
+       private NyARIntPoint2d[] _coord;\r
+\r
+\r
+       public boolean getVertex(NyARIntPoint2d[] i_coord,int i_coord_len,int st, int ed, double i_thresh)\r
+       {\r
+               this.number_of_vertex = 0;\r
+               this.thresh = i_thresh;\r
+               this._coord = i_coord;\r
+               return get_vertex(st, ed,i_coord_len);\r
+       }\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,int i_coord_len)\r
+       {\r
+               //メモ:座標値は65536を超えなければint32で扱って大丈夫なので変更。\r
+               //dmaxは4乗なのでやるとしてもint64じゃないとマズイ\r
+               int v1 = 0;\r
+               final NyARIntPoint2d[] coord = this._coord;\r
+               final int a = coord[ed].y - coord[st].y;\r
+               final int b = coord[st].x - coord[ed].x;\r
+               final int c = coord[ed].x * coord[st].y - coord[ed].y * coord[st].x;\r
+               double dmax = 0;\r
+               if(st<ed){\r
+                       //stとedが1区間\r
+                       for (int i = st + 1; i < ed; i++) {\r
+                               final double d = a * coord[i].x + b * coord[i].y + c;\r
+                               if (d * d > dmax) {\r
+                                       dmax = d * d;\r
+                                       v1 = i;\r
+                               }\r
+                       }\r
+               }else{\r
+                       //stとedが2区間\r
+                       for (int i = st + 1; i < i_coord_len; i++) {\r
+                               final double d = a * coord[i].x + b * coord[i].y + c;\r
+                               if (d * d > dmax) {\r
+                                       dmax = d * d;\r
+                                       v1 = i;\r
+                               }\r
+                       }\r
+                       for (int i = 0; i < ed; i++) {\r
+                               final double d = a * coord[i].x + b * coord[i].y + c;\r
+                               if (d * d > dmax) {\r
+                                       dmax = d * d;\r
+                                       v1 = i;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               \r
+               if (dmax / (double)(a * a + b * b) > thresh) {\r
+                       if (!get_vertex(st, v1,i_coord_len)) {\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,i_coord_len)) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquare.java b/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquare.java
new file mode 100644 (file)
index 0000000..9be21bc
--- /dev/null
@@ -0,0 +1,127 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * ARMarkerInfoに相当するクラス。 矩形情報を保持します。\r
+ * \r
+ * directionは方角を表します。\r
+ * 決定しないときはDIRECTION_UNKNOWNを設定してください。\r
+ * \r
+ */\r
+public class NyARSquare\r
+{\r
+    public NyARLinear[] line = NyARLinear.createArray(4);\r
+    public NyARDoublePoint2d[] sqvertex = NyARDoublePoint2d.createArray(4);\r
+    \r
+    /**\r
+     * 中心点を計算します。\r
+     * @param o_out\r
+     * 結果を格納するバッファ。\r
+     */\r
+    public void getCenter2d(NyARDoublePoint2d o_out)\r
+    {\r
+       o_out.x=(this.sqvertex[0].x+this.sqvertex[1].x+this.sqvertex[2].x+this.sqvertex[3].x)/4;\r
+       o_out.y=(this.sqvertex[0].y+this.sqvertex[1].y+this.sqvertex[2].y+this.sqvertex[3].y)/4;\r
+       return;\r
+    }\r
+    /**\r
+     * 頂点同士の距離から、頂点のシフト量を返します。この関数は、よく似た2つの矩形の頂点同士の対応を取るために使用します。\r
+     * @param i_square\r
+     * 比較対象の矩形\r
+     * @return\r
+     * シフト量を数値で返します。\r
+     * シフト量はthis-i_squareです。1の場合、this.sqvertex[0]とi_square.sqvertex[1]が対応点になる(shift量1)であることを示します。\r
+     */\r
+    public int checkVertexShiftValue(NyARSquare i_square)\r
+    {\r
+       NyARDoublePoint2d[] a=this.sqvertex;\r
+       NyARDoublePoint2d[] b=i_square.sqvertex;\r
+       \r
+       //3-0番目\r
+       int min_dist=Integer.MAX_VALUE;\r
+       int min_index=0;\r
+       int xd,yd;\r
+       for(int i=3;i>=0;i--){\r
+               int d=0;\r
+               for(int i2=3;i2>=0;i2--){\r
+                       xd= (int)(a[i2].x-b[(i2+i)%4].x);\r
+                       yd= (int)(a[i2].y-b[(i2+i)%4].y);\r
+                       d+=xd*xd+yd*yd;\r
+               }\r
+               if(min_dist>d){\r
+                       min_dist=d;\r
+                       min_index=i;\r
+               }\r
+       }\r
+       return min_index;\r
+    }\r
+   \r
+    \r
+    \r
+    /**\r
+     * 4とnの最大公約数テーブル\r
+     */\r
+    private final static int[] _gcd_table4={-1,1,2,1};\r
+    /**\r
+     * 頂点を左回転して、矩形を回転させます。\r
+     * @param i_shift\r
+     */\r
+    public void rotateVertexL(int i_shift)\r
+    {\r
+       assert(i_shift<4);\r
+       NyARDoublePoint2d vertext;\r
+       NyARLinear linet;\r
+       if(i_shift==0){\r
+               return;\r
+       }\r
+       int t1,t2;\r
+       int d, i, j, mk;\r
+           int ll=4-i_shift;\r
+           d = _gcd_table4[ll];//NyMath.gcn(4,ll);\r
+           mk = (4-ll) % 4;\r
+           for (i = 0; i < d; i++) {\r
+               linet=this.line[i];\r
+               vertext=this.sqvertex[i];\r
+               for (j = 1; j < 4/d; j++) {\r
+                   t1=(i + (j-1)*mk) % 4;\r
+                   t2=(i + j*mk) % 4;\r
+                       this.line[t1]=this.line[t2];\r
+                       this.sqvertex[t1]=this.sqvertex[t2];\r
+               }\r
+               t1=(i + ll) % 4;\r
+               this.line[t1]=linet;\r
+               this.sqvertex[t1]=vertext;\r
+           }\r
+    }   \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareContourDetector.java b/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareContourDetector.java
new file mode 100644 (file)
index 0000000..05451d2
--- /dev/null
@@ -0,0 +1,56 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public abstract class NyARSquareContourDetector\r
+{\r
+       /**\r
+        * @param i_raster\r
+        * @param o_square_stack\r
+        * @throws NyARException\r
+        */\r
+       public abstract void detectMarker(NyARBinRaster i_raster) throws NyARException;\r
+       /**\r
+        * 通知ハンドラです。\r
+        * この関数は、detectMarker関数のコールバック関数として機能します。\r
+        * 継承先のクラスで、矩形の発見時の処理をここに記述してください。\r
+        * @param i_coord\r
+        * @param i_coor_num\r
+        * @param i_vertex_index\r
+        * @throws NyARException\r
+        */\r
+       protected abstract void onSquareDetect(NyARIntCoordinates i_coord,int[] i_vertex_index)  throws NyARException;\r
+}\r
+\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareContourDetector_ARToolKit.java b/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareContourDetector_ARToolKit.java
new file mode 100644 (file)
index 0000000..6c5302c
--- /dev/null
@@ -0,0 +1,164 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelOverlapChecker;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntCoordinates;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+\r
+public abstract class NyARSquareContourDetector_ARToolKit extends NyARSquareContourDetector\r
+{\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
+       private final int _width;\r
+       private final int _height;\r
+\r
+       private final NyARLabeling_ARToolKit _labeling;\r
+\r
+       private final NyARLabelingImage _limage;\r
+\r
+       private final NyARLabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new NyARLabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
+       private final NyARContourPickup_ARToolKit _cpickup=new NyARContourPickup_ARToolKit();\r
+       private final NyARCoord2SquareVertexIndexes _coord2vertex=new NyARCoord2SquareVertexIndexes();\r
+\r
+       private final NyARIntCoordinates _coord;\r
+       private final int[] __detectMarker_mkvertex = new int[4];\r
+       /**\r
+        * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+        * \r
+        * @param i_param\r
+        */\r
+       public NyARSquareContourDetector_ARToolKit(NyARIntSize i_size) throws NyARException\r
+       {\r
+               this._width = i_size.w;\r
+               this._height = i_size.h;\r
+               this._labeling = new NyARLabeling_ARToolKit();\r
+               this._limage = new NyARLabelingImage(this._width, this._height);\r
+\r
+               // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
+               int number_of_coord = (this._width + this._height) * 2;\r
+\r
+               // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
+               this._coord=new NyARIntCoordinates(number_of_coord);\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * arDetectMarker2を基にした関数\r
+        * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
+        * directionの確定は行いません。\r
+        * @param i_raster\r
+        * 解析する2値ラスタイメージを指定します。\r
+        * @throws NyARException\r
+        */\r
+       public final void detectMarker(NyARBinRaster i_raster) throws NyARException\r
+       {\r
+               final NyARLabelingImage limage = this._limage;\r
+\r
+               // ラベル数が0ならここまで\r
+               final int label_num = this._labeling.labeling(i_raster,this._limage);\r
+               if (label_num < 1) {\r
+                       return;\r
+               }\r
+\r
+               final NyARLabelingLabelStack stack = limage.getLabelStack();\r
+               //ラベルをソートしておく\r
+               stack.sortByArea();\r
+               //\r
+               final NyARLabelingLabel[] labels = stack.getArray();\r
+\r
+               // デカいラベルを読み飛ばし\r
+               int i;\r
+               for (i = 0; i < label_num; i++) {\r
+                       // 検査対象内のラベルサイズになるまで無視\r
+                       if (labels[i].area <= AR_AREA_MAX) {\r
+                               break;\r
+                       }\r
+               }\r
+               final int xsize = this._width;\r
+               final int ysize = this._height;\r
+               final NyARIntCoordinates coord = this._coord;\r
+               final int[] mkvertex =this.__detectMarker_mkvertex;\r
+               \r
+               final NyARLabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
+\r
+               //重なりチェッカの最大数を設定\r
+               overlap.setMaxLabels(label_num);\r
+               for (; i < label_num; i++) {\r
+                       final NyARLabelingLabel label_pt = labels[i];\r
+                       final int label_area = label_pt.area;\r
+                       // 検査対象サイズよりも小さくなったら終了\r
+                       if (label_area < AR_AREA_MIN) {\r
+                               break;\r
+                       }\r
+                       // クリップ領域が画面の枠に接していれば除外\r
+                       if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){\r
+                               continue;\r
+                       }\r
+                       if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){\r
+                               continue;\r
+                       }\r
+                       // 既に検出された矩形との重なりを確認\r
+                       if (!overlap.check(label_pt)) {\r
+                               // 重なっているようだ。\r
+                               continue;\r
+                       }\r
+                       // 輪郭を取得\r
+                       if(!this._cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord)){\r
+                               continue;\r
+                       }\r
+                       //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得\r
+                       if (!this._coord2vertex.getVertexIndexes(coord,label_area, mkvertex)) {\r
+                               // 頂点の取得が出来なかった\r
+                               continue;\r
+                       }\r
+                       //矩形を発見したことをコールバック関数で通知\r
+                       this.onSquareDetect(coord,mkvertex);\r
+\r
+                       // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+                       overlap.push(label_pt);\r
+                       \r
+               }\r
+               return;\r
+       }\r
+\r
+}\r
+\r
+\r
+\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareContourDetector_Rle.java b/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareContourDetector_Rle.java
new file mode 100644 (file)
index 0000000..898eb53
--- /dev/null
@@ -0,0 +1,248 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelOverlapChecker;\r
+import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARGrayscaleRaster;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+\r
+public abstract class NyARSquareContourDetector_Rle extends NyARSquareContourDetector\r
+{\r
+       /**\r
+        * label_stackにソート後の結果を蓄積するクラス\r
+        */\r
+       class Labeling extends NyARLabeling_Rle\r
+       {\r
+               public NyARRleLabelFragmentInfoPtrStack label_stack;\r
+               int _right;\r
+               int _bottom;\r
+               \r
+               \r
+               public Labeling(int i_width,int i_height) throws NyARException\r
+               {\r
+                       super(i_width,i_height);\r
+                       this.label_stack=new NyARRleLabelFragmentInfoPtrStack(i_width*i_height*2048/(320*240)+32);//検出可能な最大ラベル数\r
+                       this._bottom=i_height-1;\r
+                       this._right=i_width-1;\r
+                       return;\r
+               }\r
+               public void labeling(NyARGrayscaleRaster i_raster,NyARIntRect i_area,int i_th) throws NyARException\r
+               {\r
+                       //配列初期化\r
+                       this.label_stack.clear();\r
+                       //ラベルの検出\r
+                       super.labeling(i_raster, i_area, i_th);\r
+                       //ソート\r
+                       this.label_stack.sortByArea();\r
+               }\r
+               public void labeling(NyARBinRaster i_bin_raster) throws NyARException\r
+               {\r
+                       //配列初期化\r
+                       this.label_stack.clear();\r
+                       //ラベルの検出\r
+                       super.labeling(i_bin_raster);\r
+                       //ソート\r
+                       this.label_stack.sortByArea();                  \r
+               }\r
+               \r
+               protected void onLabelFound(NyARRleLabelFragmentInfo i_label)\r
+               {\r
+                       // クリップ領域が画面の枠に接していれば除外\r
+                       if (i_label.clip_l == 0 || i_label.clip_r == this._right){\r
+                               return;\r
+                       }\r
+                       if (i_label.clip_t == 0 || i_label.clip_b == this._bottom){\r
+                               return;\r
+                       }\r
+                       this.label_stack.push(i_label);\r
+               }\r
+               \r
+       }\r
+       \r
+       private final int _width;\r
+       private final int _height;\r
+\r
+       private final Labeling _labeling;\r
+\r
+       private final NyARLabelOverlapChecker<NyARRleLabelFragmentInfo> _overlap_checker = new NyARLabelOverlapChecker<NyARRleLabelFragmentInfo>(32,NyARRleLabelFragmentInfo.class);\r
+       private final NyARContourPickup _cpickup=new NyARContourPickup();\r
+\r
+       private final NyARCoord2SquareVertexIndexes _coord2vertex=new NyARCoord2SquareVertexIndexes();\r
+       \r
+       private final NyARIntCoordinates _coord;\r
+       /**\r
+        * コンストラクタ\r
+        * @param i_size\r
+        * 入力画像のサイズ\r
+        */\r
+       public NyARSquareContourDetector_Rle(NyARIntSize i_size) throws NyARException\r
+       {\r
+               //特性確認\r
+               assert(NyARLabeling_Rle._sf_label_array_safe_reference);\r
+               this._width = i_size.w;\r
+               this._height = i_size.h;\r
+               //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。\r
+               this._labeling = new Labeling(this._width,this._height);                \r
+\r
+               // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
+               int number_of_coord = (this._width + this._height) * 2;\r
+\r
+               // 輪郭バッファ\r
+               this._coord = new NyARIntCoordinates(number_of_coord);\r
+               return;\r
+       }\r
+\r
+       private final int[] __detectMarker_mkvertex = new int[4];\r
+       public void detectMarker(NyARGrayscaleRaster i_raster,NyARIntRect i_area,int i_th) throws NyARException\r
+       {\r
+               assert(i_area.w*i_area.h>0);\r
+               \r
+               final NyARRleLabelFragmentInfoPtrStack flagment=this._labeling.label_stack;\r
+               final NyARLabelOverlapChecker<NyARRleLabelFragmentInfo> overlap = this._overlap_checker;\r
+\r
+               // ラベル数が0ならここまで\r
+               this._labeling.labeling(i_raster, i_area, i_th);\r
+               final int label_num=flagment.getLength();\r
+               if (label_num < 1) {\r
+                       return;\r
+               }\r
+\r
+               //ラベルリストを取得\r
+               NyARRleLabelFragmentInfo[] labels=flagment.getArray();\r
+\r
+               NyARIntCoordinates coord = this._coord;\r
+               final int[] mkvertex =this.__detectMarker_mkvertex;\r
+\r
+\r
+               //重なりチェッカの最大数を設定\r
+               overlap.setMaxLabels(label_num);\r
+\r
+               for (int i=0; i < label_num; i++) {\r
+                       NyARRleLabelFragmentInfo label_pt=labels[i];\r
+                       // 既に検出された矩形との重なりを確認\r
+                       if (!overlap.check(label_pt)) {\r
+                               // 重なっているようだ。\r
+                               continue;\r
+                       }\r
+                       \r
+                       //輪郭を取得\r
+                       if(!this._cpickup.getContour(i_raster,i_area, i_th,label_pt.entry_x,label_pt.clip_t,coord))\r
+                       {\r
+                               continue;\r
+                       }\r
+                       int label_area = label_pt.area;\r
+                       //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得\r
+                       if (!this._coord2vertex.getVertexIndexes(coord,label_area,mkvertex)){\r
+                               // 頂点の取得が出来なかった\r
+                               continue;\r
+                       }\r
+                       //矩形を発見したことをコールバック関数で通知\r
+                       this.onSquareDetect(coord,mkvertex);\r
+\r
+                       // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+                       overlap.push(label_pt);\r
+               \r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * @override\r
+        */\r
+       public void detectMarker(NyARBinRaster i_raster) throws NyARException\r
+       {\r
+               final NyARRleLabelFragmentInfoPtrStack flagment=this._labeling.label_stack;\r
+               final NyARLabelOverlapChecker<NyARRleLabelFragmentInfo> overlap = this._overlap_checker;\r
+\r
+               // ラベル数が0ならここまで\r
+               flagment.clear();\r
+               this._labeling.labeling(i_raster);\r
+               final int label_num=flagment.getLength();\r
+               if (label_num < 1) {\r
+                       return;\r
+               }\r
+               //ラベルをソートしておく\r
+               flagment.sortByArea();\r
+               //ラベルリストを取得\r
+               NyARRleLabelFragmentInfo[] labels=flagment.getArray();\r
+\r
+               NyARIntCoordinates coord = this._coord;\r
+               final int[] mkvertex =this.__detectMarker_mkvertex;\r
+\r
+\r
+               //重なりチェッカの最大数を設定\r
+               overlap.setMaxLabels(label_num);\r
+\r
+               for (int i=0; i < label_num; i++) {\r
+                       final NyARRleLabelFragmentInfo label_pt=labels[i];\r
+                       int label_area = label_pt.area;\r
+               \r
+                       // 既に検出された矩形との重なりを確認\r
+                       if (!overlap.check(label_pt)) {\r
+                               // 重なっているようだ。\r
+                               continue;\r
+                       }\r
+                       \r
+                       //輪郭を取得\r
+                       if(!this._cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t,coord)){\r
+                               continue;\r
+                       }\r
+                       //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得\r
+                       if (!this._coord2vertex.getVertexIndexes(coord,label_area, mkvertex)) {\r
+                               // 頂点の取得が出来なかった\r
+                               continue;\r
+                       }\r
+                       //矩形を発見したことをコールバック関数で通知\r
+                       this.onSquareDetect(coord,mkvertex);\r
+\r
+                       // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+                       overlap.push(label_pt);\r
+               \r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * デバック用API\r
+        * @return\r
+        */\r
+       public Object[] _probe()\r
+       {\r
+               Object[] ret=new Object[10];\r
+               return ret;\r
+       }\r
+\r
+}\r
+\r
+\r
+\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareStack.java b/lib/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareStack.java
new file mode 100644 (file)
index 0000000..5524c96
--- /dev/null
@@ -0,0 +1,48 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.stack.NyARObjectStack;\r
+\r
+public class NyARSquareStack extends NyARObjectStack<NyARSquare>\r
+{\r
+       public NyARSquareStack(int i_length) throws NyARException\r
+       {\r
+               super.initInstance(i_length,NyARSquare.class);\r
+\r
+       }\r
+       protected NyARSquare createElement()\r
+       {\r
+               return new NyARSquare();\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/INyARTransMat.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/INyARTransMat.java
new file mode 100644 (file)
index 0000000..98e9095
--- /dev/null
@@ -0,0 +1,63 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+\r
+\r
+/**\r
+ * This class calculates ARMatrix from square information. -- 変換行列を計算するクラス。\r
+ * \r
+ */\r
+public interface INyARTransMat\r
+{\r
+       /**\r
+        * 理想座標系の四角系から、i_offsetのパラメタで示される矩形を(0,0,0)の点から移動するための行列式を計算し、o_resultへ格納します。\r
+        * @param i_square\r
+        * @param i_offset\r
+        * @param o_result\r
+        * @throws NyARException\r
+        */\r
+       public void transMat(NyARSquare i_square,NyARRectOffset i_offset, NyARTransMatResult o_result) throws NyARException;\r
+       /**\r
+        * 理想座標系の四角系から、i_offsetのパラメタで示される矩形を(0,0,0)の点から移動するための行列式を計算し、o_resultへ格納します。\r
+        * i_prev_resultにある過去の情報を参照するため、変移が少ない場合はより高精度な値を返します。\r
+        * @param i_square\r
+        * @param i_offset\r
+        * @param i_prev_result\r
+        * 参照する過去のオブジェクトです。このオブジェクトとo_resultには同じものを指定できます。\r
+        * @param o_result\r
+        * 結果を格納するオブジェクトです。\r
+        * @throws NyARException\r
+        */\r
+       public void transMatContinue(NyARSquare i_square,NyARRectOffset i_offset,NyARTransMatResult i_prev_result,NyARTransMatResult o_result) throws NyARException;\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARRectOffset.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARRectOffset.java
new file mode 100644 (file)
index 0000000..5588819
--- /dev/null
@@ -0,0 +1,111 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 矩形の頂点情報を格納します。\r
+ */\r
+final public class NyARRectOffset\r
+{\r
+       public final NyARDoublePoint3d[] vertex=NyARDoublePoint3d.createArray(4);\r
+       public static NyARRectOffset[] createArray(int i_number)\r
+       {\r
+               NyARRectOffset[] ret=new NyARRectOffset[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARRectOffset();\r
+               }\r
+               return ret;\r
+       }       \r
+       /**\r
+        * 辺長から、オフセット情報を作成して設定します。\r
+        * 作成するオフセット情報は、マーカ中心を0,0としたi_width*i_widthのマーカです。\r
+        * @param i_width\r
+        * マーカの縦横サイズ(mm単位)\r
+        */\r
+       public void setSquare(double i_width)\r
+       {\r
+               final double w_2 = i_width / 2.0;\r
+               \r
+               NyARDoublePoint3d vertex3d_ptr;\r
+               vertex3d_ptr= this.vertex[0];\r
+               vertex3d_ptr.x = -w_2;\r
+               vertex3d_ptr.y =  w_2;\r
+               vertex3d_ptr.z = 0.0;\r
+               vertex3d_ptr= this.vertex[1];\r
+               vertex3d_ptr.x = w_2;\r
+               vertex3d_ptr.y = w_2;\r
+               vertex3d_ptr.z = 0.0;\r
+               vertex3d_ptr= this.vertex[2];\r
+               vertex3d_ptr.x =  w_2;\r
+               vertex3d_ptr.y = -w_2;\r
+               vertex3d_ptr.z = 0.0;\r
+               vertex3d_ptr= this.vertex[3];\r
+               vertex3d_ptr.x = -w_2;\r
+               vertex3d_ptr.y = -w_2;\r
+               vertex3d_ptr.z = 0.0;\r
+               return;\r
+       }\r
+       /**\r
+        * 辺長から、オフセット情報を作成して設定します。\r
+        * 作成するオフセット情報は、マーカ中心を0,0としたi_width*i_heightのマーカです。\r
+        * @param i_width\r
+        * マーカの横サイズ(mm単位)\r
+        * @param i_height\r
+        * マーカの縦サイズ(mm単位)\r
+        */\r
+       public void setSquare(double i_width,double i_height)\r
+       {\r
+               final double w_2 = i_width / 2.0;\r
+               final double h_2 = i_height / 2.0;\r
+               \r
+               NyARDoublePoint3d vertex3d_ptr;\r
+               vertex3d_ptr= this.vertex[0];\r
+               vertex3d_ptr.x = -w_2;\r
+               vertex3d_ptr.y =  h_2;\r
+               vertex3d_ptr.z = 0.0;\r
+               vertex3d_ptr= this.vertex[1];\r
+               vertex3d_ptr.x = w_2;\r
+               vertex3d_ptr.y = h_2;\r
+               vertex3d_ptr.z = 0.0;\r
+               vertex3d_ptr= this.vertex[2];\r
+               vertex3d_ptr.x =  w_2;\r
+               vertex3d_ptr.y = -h_2;\r
+               vertex3d_ptr.z = 0.0;\r
+               vertex3d_ptr= this.vertex[3];\r
+               vertex3d_ptr.x = -w_2;\r
+               vertex3d_ptr.y = -h_2;\r
+               vertex3d_ptr.z = 0.0;\r
+               return;         \r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat.java
new file mode 100644 (file)
index 0000000..6abdab8
--- /dev/null
@@ -0,0 +1,373 @@
+/* \r
+ * PROJECT: NyARToolkit (Extension)\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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.transmat.solver.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.optimize.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+\r
+/**\r
+ * This class calculates ARMatrix from square information and holds it. --\r
+ * 変換行列を計算して、結果を保持するクラス。\r
+ * \r
+ */\r
+public class NyARTransMat implements INyARTransMat\r
+{      \r
+       private NyARPerspectiveProjectionMatrix _ref_projection_mat;\r
+       protected NyARRotMatrix _rotmatrix;\r
+       protected NyARTransportVectorSolver _transsolver;\r
+       protected NyARPartialDifferentiationOptimize _mat_optimize;\r
+\r
+\r
+       private NyARCameraDistortionFactor _ref_dist_factor;\r
+\r
+       /**\r
+        * 派生クラスで自分でメンバオブジェクトを指定したい場合はこちらを使う。\r
+        *\r
+        */\r
+       protected NyARTransMat()\r
+       {\r
+               //_calculator,_rotmatrix,_mat_optimizeをコンストラクタの終了後に\r
+               //作成して割り当ててください。\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * この関数は、コンストラクタから呼び出してください。\r
+        * @param i_distfactor\r
+        * 歪みの逆矯正に使うオブジェクト。\r
+        * @param i_projmat\r
+        * @throws NyARException\r
+        */\r
+       private final void initInstance(NyARCameraDistortionFactor i_distfactor,NyARPerspectiveProjectionMatrix i_projmat) throws NyARException\r
+       {\r
+               this._transsolver=new NyARTransportVectorSolver(i_projmat,4);\r
+               //互換性が重要な時は、NyARRotMatrix_ARToolKitを使うこと。\r
+               //理屈はNyARRotMatrix_NyARToolKitもNyARRotMatrix_ARToolKitも同じだけど、少しだけ値がずれる。\r
+               this._rotmatrix = new NyARRotMatrix(i_projmat);\r
+               this._mat_optimize=new NyARPartialDifferentiationOptimize(i_projmat);\r
+               this._ref_dist_factor=i_distfactor;\r
+               this._ref_projection_mat=i_projmat;\r
+               return;\r
+       }\r
+\r
+       public NyARTransMat(NyARCameraDistortionFactor i_ref_distfactor,NyARPerspectiveProjectionMatrix i_ref_projmat) throws NyARException\r
+       {\r
+               initInstance(i_ref_distfactor,i_ref_projmat);\r
+               return;\r
+       }\r
+\r
+       public NyARTransMat(NyARParam i_param) throws NyARException\r
+       {\r
+               initInstance(i_param.getDistortionFactor(),i_param.getPerspectiveProjectionMatrix());\r
+               return;\r
+       }\r
+\r
+       private final NyARDoublePoint2d[] __transMat_vertex_2d = NyARDoublePoint2d.createArray(4);\r
+       private final NyARDoublePoint3d[] __transMat_vertex_3d = NyARDoublePoint3d.createArray(4);\r
+       private final NyARDoublePoint3d __transMat_trans=new NyARDoublePoint3d();\r
+       \r
+       /**\r
+        * 頂点情報を元に、エラー閾値を計算します。\r
+        * @param i_vertex\r
+        */\r
+       private double makeErrThreshold(NyARDoublePoint2d[] i_vertex)\r
+       {\r
+               double a,b,l1,l2;\r
+               a=i_vertex[0].x-i_vertex[2].x;\r
+               b=i_vertex[0].y-i_vertex[2].y;\r
+               l1=a*a+b*b;\r
+               a=i_vertex[1].x-i_vertex[3].x;\r
+               b=i_vertex[1].y-i_vertex[3].y;\r
+               l2=a*a+b*b;\r
+               return (Math.sqrt(l1>l2?l1:l2))/200;\r
+       }\r
+       \r
+       /**\r
+        * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )\r
+        * \r
+        * @param i_square\r
+        * 計算対象のNyARSquareオブジェクト\r
+        * @param i_direction\r
+        * @param i_width\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public void transMat(NyARSquare i_square,NyARRectOffset i_offset, NyARTransMatResult o_result_conv) throws NyARException\r
+       {\r
+               final NyARDoublePoint3d trans=this.__transMat_trans;\r
+               double err_threshold=makeErrThreshold(i_square.sqvertex);\r
+\r
+               NyARDoublePoint2d[] vertex_2d;\r
+               if(this._ref_dist_factor!=null){\r
+                       //歪み復元必要\r
+                       vertex_2d=this.__transMat_vertex_2d;\r
+                       this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4);\r
+               }else{\r
+                       //歪み復元は不要\r
+                       vertex_2d=i_square.sqvertex;\r
+               }\r
+               //平行移動量計算機に、2D座標系をセット\r
+               this._transsolver.set2dVertex(vertex_2d,4);\r
+\r
+               //回転行列を計算\r
+               this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
+               \r
+               //回転後の3D座標系から、平行移動量を計算\r
+               NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+               this._rotmatrix.getPoint3dBatch(i_offset.vertex,vertex_3d,4);\r
+               this._transsolver.solveTransportVector(vertex_3d,trans);\r
+               \r
+               //計算結果の最適化(平行移動量と回転行列の最適化)\r
+               this.optimize(this._rotmatrix, trans, this._transsolver,i_offset.vertex, vertex_2d,err_threshold,o_result_conv);\r
+               return;\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see jp.nyatla.nyartoolkit.core.transmat.INyARTransMat#transMatContinue(jp.nyatla.nyartoolkit.core.NyARSquare, int, double, jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult)\r
+        */\r
+       public final void transMatContinue(NyARSquare i_square,NyARRectOffset i_offset,NyARTransMatResult i_prev_result,NyARTransMatResult o_result) throws NyARException\r
+       {\r
+               final NyARDoublePoint3d trans=this.__transMat_trans;\r
+               // io_result_convが初期値なら、transMatで計算する。\r
+               if (!i_prev_result.has_value) {\r
+                       this.transMat(i_square,i_offset, o_result);\r
+                       return;\r
+               }\r
+               //過去のエラーレートを記録(ここれやるのは、i_prev_resultとo_resultに同じインスタンスを指定できるようにするため)\r
+               double last_error=i_prev_result.last_error;\r
+               \r
+               //最適化計算の閾値を決定\r
+               double err_threshold=makeErrThreshold(i_square.sqvertex);\r
+\r
+               \r
+               //平行移動量計算機に、2D座標系をセット\r
+               NyARDoublePoint2d[] vertex_2d;\r
+               if(this._ref_dist_factor!=null){\r
+                       vertex_2d=this.__transMat_vertex_2d;\r
+                       this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4);                \r
+               }else{\r
+                       vertex_2d=i_square.sqvertex;\r
+               }\r
+               this._transsolver.set2dVertex(vertex_2d,4);\r
+\r
+               //回転行列を計算\r
+               NyARRotMatrix rot=this._rotmatrix;\r
+               rot.initRotByPrevResult(i_prev_result);\r
+               \r
+               //回転後の3D座標系から、平行移動量を計算\r
+               NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+               rot.getPoint3dBatch(i_offset.vertex,vertex_3d,4);\r
+               this._transsolver.solveTransportVector(vertex_3d,trans);\r
+\r
+               //現在のエラーレートを計算\r
+               double min_err=errRate(this._rotmatrix,trans,i_offset.vertex, vertex_2d,4,vertex_3d);\r
+               //結果をストア\r
+               o_result.setValue(rot,trans,min_err);\r
+               //エラーレートの判定\r
+               if(min_err<last_error+err_threshold){\r
+//                     System.out.println("TR:ok");\r
+                       //最適化してみる。\r
+                       for (int i = 0;i<5; i++) {\r
+                               //変換行列の最適化\r
+                               this._mat_optimize.modifyMatrix(rot, trans, i_offset.vertex, vertex_2d, 4);\r
+                               double err=errRate(rot,trans,i_offset.vertex, vertex_2d,4,vertex_3d);\r
+                               //System.out.println("E:"+err);\r
+                               if(min_err-err<err_threshold/2){\r
+                                       //System.out.println("BREAK");\r
+                                       break;\r
+                               }\r
+                               this._transsolver.solveTransportVector(vertex_3d, trans);                               \r
+                               o_result.setValue(rot,trans,err);\r
+                               min_err=err;\r
+                       }\r
+               }else{\r
+//                     System.out.println("TR:again");\r
+                       //回転行列を計算\r
+                       rot.initRotBySquare(i_square.line,i_square.sqvertex);\r
+                       \r
+                       //回転後の3D座標系から、平行移動量を計算\r
+                       rot.getPoint3dBatch(i_offset.vertex,vertex_3d,4);\r
+                       this._transsolver.solveTransportVector(vertex_3d,trans);\r
+                       \r
+                       //計算結果の最適化(平行移動量と回転行列の最適化)\r
+                       this.optimize(rot,trans, this._transsolver,i_offset.vertex, vertex_2d,err_threshold,o_result);\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * \r
+        * @param i_square\r
+        * @param i_offset\r
+        * @param i_prev_error\r
+        *      前回のエラーレート値をしていします。\r
+        * @param io_angle\r
+        * @param io_trans\r
+        * @return\r
+        *  エラーレート値を返します。\r
+        * @throws NyARException\r
+        * \r
+        */\r
+/*     public double transMatContinue(NyARSquare i_square,NyARRectOffset i_offset,double i_prev_error,NyARDoublePoint3d io_angle,NyARDoublePoint3d io_trans) throws NyARException\r
+       {\r
+               final NyARDoublePoint3d trans=this.__transMat_trans;\r
+               \r
+               //最適化計算の閾値を決定\r
+               double err_threshold=makeErrThreshold(i_square.sqvertex);\r
+\r
+               \r
+               //平行移動量計算機に、2D座標系をセット\r
+               NyARDoublePoint2d[] vertex_2d=this.__transMat_vertex_2d;\r
+               NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+               this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4);                \r
+               this._transsolver.set2dVertex(vertex_2d,4);\r
+               \r
+               //回転行列を計算\r
+               this._rotmatrix.initRotByAngle(io_angle);\r
+               \r
+               //回転後の3D座標系から、平行移動量を計算\r
+               this._rotmatrix.getPoint3dBatch(i_offset.vertex,vertex_3d,4);\r
+               this._transsolver.solveTransportVector(vertex_3d,trans);\r
+\r
+               //現在のエラーレートを計算しておく\r
+               double min_err=errRate(this._rotmatrix,trans,i_offset.vertex, vertex_2d,4,vertex_3d);\r
+               NyARDoubleMatrix33 rot=this.__rot;\r
+               //エラーレートが前回のエラー値より閾値分大きかったらアゲイン\r
+               if(min_err<i_prev_error+err_threshold){\r
+                       rot.setValue(this._rotmatrix);\r
+                       //最適化してみる。\r
+                       for (int i = 0;i<5; i++) {\r
+                               //変換行列の最適化\r
+                               this._mat_optimize.modifyMatrix(rot, trans, i_offset.vertex, vertex_2d, 4);\r
+                               double err=errRate(rot,trans,i_offset.vertex, vertex_2d,4,vertex_3d);\r
+                               //System.out.println("E:"+err);\r
+                               if(min_err-err<err_threshold/2){\r
+                                       //System.out.println("BREAK");\r
+                                       break;\r
+                               }\r
+                               this._transsolver.solveTransportVector(vertex_3d, trans);\r
+                               this._rotmatrix.setValue(rot);\r
+                               min_err=err;\r
+                       }\r
+                       this.updateMatrixValue(this._rotmatrix,  trans,o_result_conv);\r
+               }else{\r
+                       //回転行列を計算\r
+                       this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
+                       \r
+                       //回転後の3D座標系から、平行移動量を計算\r
+                       this._rotmatrix.getPoint3dBatch(i_offset.vertex,vertex_3d,4);\r
+                       this._transsolver.solveTransportVector(vertex_3d,trans);\r
+                       \r
+                       //計算結果の最適化(平行移動量と回転行列の最適化)\r
+                       min_err=this.optimize(this._rotmatrix, trans, this._transsolver,i_offset.vertex, vertex_2d,err_threshold);\r
+                       this.updateMatrixValue(this._rotmatrix, trans,o_result_conv);\r
+               }\r
+               return min_err;\r
+       }       \r
+       \r
+*/\r
+       /**\r
+        * \r
+        * @param iw_rotmat\r
+        * @param iw_transvec\r
+        * @param i_solver\r
+        * @param i_offset_3d\r
+        * @param i_2d_vertex\r
+        * @param i_err_threshold\r
+        * @param o_result\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       private void optimize(NyARRotMatrix iw_rotmat,NyARDoublePoint3d iw_transvec,INyARTransportVectorSolver i_solver,NyARDoublePoint3d[] i_offset_3d,NyARDoublePoint2d[] i_2d_vertex,double i_err_threshold,NyARTransMatResult o_result) throws NyARException\r
+       {\r
+               //System.out.println("START");\r
+               NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+               //初期のエラー値を計算\r
+               double min_err=errRate(iw_rotmat, iw_transvec, i_offset_3d, i_2d_vertex,4,vertex_3d);\r
+               o_result.setValue(iw_rotmat,iw_transvec,min_err);\r
+\r
+               for (int i = 0;i<5; i++) {\r
+                       //変換行列の最適化\r
+                       this._mat_optimize.modifyMatrix(iw_rotmat,iw_transvec, i_offset_3d, i_2d_vertex,4);\r
+                       double err=errRate(iw_rotmat,iw_transvec, i_offset_3d, i_2d_vertex,4,vertex_3d);\r
+                       //System.out.println("E:"+err);\r
+                       if(min_err-err<i_err_threshold){\r
+                               //System.out.println("BREAK");\r
+                               break;\r
+                       }\r
+                       i_solver.solveTransportVector(vertex_3d,iw_transvec);\r
+                       o_result.setValue(iw_rotmat,iw_transvec,err);\r
+                       min_err=err;\r
+               }\r
+               //System.out.println("END");\r
+               return;\r
+       }\r
+\r
+       //エラーレート計算機\r
+       public final double errRate(NyARDoubleMatrix33 i_rot,NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d,int i_number_of_vertex,NyARDoublePoint3d[] o_rot_vertex) throws NyARException\r
+       {\r
+               NyARPerspectiveProjectionMatrix cp = this._ref_projection_mat;\r
+               final double cp00=cp.m00;\r
+               final double cp01=cp.m01;\r
+               final double cp02=cp.m02;\r
+               final double cp11=cp.m11;\r
+               final double cp12=cp.m12;\r
+\r
+               double err=0;\r
+               for(int i=0;i<i_number_of_vertex;i++){\r
+                       double x3d,y3d,z3d;\r
+                       o_rot_vertex[i].x=x3d=i_rot.m00*i_vertex3d[i].x+i_rot.m01*i_vertex3d[i].y+i_rot.m02*i_vertex3d[i].z;\r
+                       o_rot_vertex[i].y=y3d=i_rot.m10*i_vertex3d[i].x+i_rot.m11*i_vertex3d[i].y+i_rot.m12*i_vertex3d[i].z;\r
+                       o_rot_vertex[i].z=z3d=i_rot.m20*i_vertex3d[i].x+i_rot.m21*i_vertex3d[i].y+i_rot.m22*i_vertex3d[i].z;\r
+                       x3d+=i_trans.x;\r
+                       y3d+=i_trans.y;\r
+                       z3d+=i_trans.z;\r
+                       \r
+                       //射影変換\r
+                       double x2d=x3d*cp00+y3d*cp01+z3d*cp02;\r
+                       double y2d=y3d*cp11+z3d*cp12;\r
+                       double h2d=z3d;\r
+                       \r
+                       //エラーレート計算\r
+                       double t1=i_vertex2d[i].x-x2d/h2d;\r
+                       double t2=i_vertex2d[i].y-y2d/h2d;\r
+                       err+=t1*t1+t2*t2;\r
+                       \r
+               }\r
+               return err/i_number_of_vertex;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMatResult.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMatResult.java
new file mode 100644 (file)
index 0000000..a49b721
--- /dev/null
@@ -0,0 +1,89 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+\r
+/**\r
+ * NyARTransMat戻り値専用のNyARMat\r
+ * \r
+ */\r
+public class NyARTransMatResult extends NyARDoubleMatrix44\r
+{\r
+       /**\r
+        * この行列に1度でも行列をセットしたかを返します。\r
+        */\r
+       public boolean has_value = false;\r
+       /**\r
+        * 観測値とのずれを示すエラーレート値です。SetValueにより更新されます。\r
+        * {@link #has_value}がtrueの時に使用可能です。\r
+        */\r
+       public double last_error;\r
+       /**\r
+        * コンストラクタです。\r
+        */\r
+       public NyARTransMatResult()\r
+       {\r
+               this.m30=this.m31=this.m32=0;\r
+               this.m33=1.0;\r
+       }\r
+       /**\r
+        * 平行移動量と回転行列をセットします。この関数は、INyARTransmatインタフェイスのクラスが結果を保存するために使います。\r
+        * @param i_rot\r
+        * @param i_trans\r
+        */\r
+       public final void setValue(NyARDoubleMatrix33 i_rot, NyARDoublePoint3d i_trans,double i_error)\r
+       {\r
+               this.m00=i_rot.m00;\r
+               this.m01=i_rot.m01;\r
+               this.m02=i_rot.m02;\r
+               this.m03=i_trans.x;\r
+\r
+               this.m10 =i_rot.m10;\r
+               this.m11 =i_rot.m11;\r
+               this.m12 =i_rot.m12;\r
+               this.m13 =i_trans.y;\r
+\r
+               this.m20 = i_rot.m20;\r
+               this.m21 = i_rot.m21;\r
+               this.m22 = i_rot.m22;\r
+               this.m23 = i_trans.z;\r
+\r
+               this.m30=this.m31=this.m32=0;\r
+               this.m33=1.0;           \r
+               this.has_value = true;\r
+               this.last_error=i_error;\r
+               return;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat_ARToolKit.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat_ARToolKit.java
new file mode 100644 (file)
index 0000000..783446d
--- /dev/null
@@ -0,0 +1,216 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.transmat.solver.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit.INyARRotMatrixOptimize;\r
+import jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit.NyARRotMatrixOptimize_O2;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+\r
+/**\r
+ * This class calculates ARMatrix from square information and holds it. --\r
+ * 変換行列を計算して、結果を保持するクラス。\r
+ * \r
+ */\r
+public class NyARTransMat_ARToolKit implements INyARTransMat\r
+{\r
+       private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5\r
+       private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0\r
+       private final static double AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR = 1.0;\r
+\r
+       protected NyARRotMatrix_ARToolKit _rotmatrix;\r
+       protected INyARTransportVectorSolver _transsolver;\r
+       protected INyARRotMatrixOptimize _mat_optimize;\r
+       private NyARCameraDistortionFactor _ref_dist_factor;\r
+\r
+       /**\r
+        * 派生クラスで自分でメンバオブジェクトを指定したい場合はこちらを使う。\r
+        *\r
+        */\r
+       protected NyARTransMat_ARToolKit()\r
+       {\r
+               //_calculator,_rotmatrix,_mat_optimizeをコンストラクタの終了後に\r
+               //作成して割り当ててください。\r
+               return;\r
+       }\r
+       public NyARTransMat_ARToolKit(NyARCameraDistortionFactor i_ref_distfactor,NyARPerspectiveProjectionMatrix i_ref_projmat) throws NyARException\r
+       {\r
+               initInstance(i_ref_distfactor,i_ref_projmat);\r
+               return;\r
+       }       \r
+       public NyARTransMat_ARToolKit(NyARParam i_param) throws NyARException\r
+       {\r
+               initInstance(i_param.getDistortionFactor(),i_param.getPerspectiveProjectionMatrix());\r
+       }\r
+       private void initInstance(NyARCameraDistortionFactor i_ref_distfactor,NyARPerspectiveProjectionMatrix i_ref_projmat) throws NyARException\r
+       {\r
+               final NyARCameraDistortionFactor dist=i_ref_distfactor;\r
+               final NyARPerspectiveProjectionMatrix pmat=i_ref_projmat;\r
+               this._transsolver=new NyARTransportVectorSolver_ARToolKit(pmat);\r
+               //互換性が重要な時は、NyARRotMatrix_ARToolKitを使うこと。\r
+               //理屈はNyARRotMatrix_NyARToolKitもNyARRotMatrix_ARToolKitも同じだけど、少しだけ値がずれる。\r
+               this._rotmatrix = new NyARRotMatrix_ARToolKit_O2(pmat);\r
+               this._mat_optimize=new NyARRotMatrixOptimize_O2(pmat);\r
+               this._ref_dist_factor=dist;\r
+       }\r
+\r
+       private final NyARDoublePoint2d[] __transMat_vertex_2d = NyARDoublePoint2d.createArray(4);\r
+       private final NyARDoublePoint3d[] __transMat_vertex_3d = NyARDoublePoint3d.createArray(4);\r
+       private final NyARDoublePoint3d __transMat_trans=new NyARDoublePoint3d();\r
+       /**\r
+        * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )\r
+        * \r
+        * @param i_square\r
+        * 計算対象のNyARSquareオブジェクト\r
+        * @param i_width\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public final void transMat(NyARSquare i_square,NyARRectOffset i_offset, NyARTransMatResult o_result_conv) throws NyARException\r
+       {\r
+               final NyARDoublePoint3d trans=this.__transMat_trans;\r
+               \r
+               //平行移動量計算機に、2D座標系をセット\r
+               NyARDoublePoint2d[] vertex_2d;\r
+               if(this._ref_dist_factor!=null){\r
+                       //歪み復元必要\r
+                       vertex_2d=this.__transMat_vertex_2d;\r
+                       this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4);\r
+               }else{\r
+                       //歪み復元は不要\r
+                       vertex_2d=i_square.sqvertex;\r
+               }\r
+               this._transsolver.set2dVertex(vertex_2d,4);\r
+               //回転行列を計算\r
+               this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
+               \r
+               //回転後の3D座標系から、平行移動量を計算\r
+               NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+               this._rotmatrix.getPoint3dBatch(i_offset.vertex,vertex_3d,4);\r
+               this._transsolver.solveTransportVector(vertex_3d,trans);\r
+               \r
+               //計算結果の最適化(平行移動量と回転行列の最適化)\r
+               double err=this.optimize(this._rotmatrix, trans, this._transsolver,i_offset.vertex, vertex_2d);\r
+               \r
+               // マトリクスの保存\r
+               o_result_conv.setValue(this._rotmatrix,trans,err);\r
+               return;\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see jp.nyatla.nyartoolkit.core.transmat.INyARTransMat#transMatContinue(jp.nyatla.nyartoolkit.core.NyARSquare, int, double, jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult)\r
+        */\r
+       public final void transMatContinue(NyARSquare i_square,NyARRectOffset i_offset,NyARTransMatResult i_prev_result,NyARTransMatResult o_result) throws NyARException\r
+       {\r
+               final NyARDoublePoint3d trans=this.__transMat_trans;\r
+\r
+               // i_prev_resultが初期値なら、transMatで計算する。\r
+               if (!i_prev_result.has_value) {\r
+                       this.transMat(i_square, i_offset, o_result);\r
+                       return;\r
+               }\r
+               \r
+               //平行移動量計算機に、2D座標系をセット\r
+               NyARDoublePoint2d[] vertex_2d;\r
+               if(this._ref_dist_factor!=null){\r
+                       //歪み復元必要\r
+                       vertex_2d=this.__transMat_vertex_2d;\r
+                       this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4);\r
+               }else{\r
+                       //歪み復元は不要\r
+                       vertex_2d=i_square.sqvertex;\r
+               }\r
+               this._transsolver.set2dVertex(vertex_2d,4);\r
+\r
+               NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+               //回転行列を計算\r
+               this._rotmatrix.initRotByPrevResult(i_prev_result);\r
+               \r
+               //回転後の3D座標系から、平行移動量を計算\r
+               this._rotmatrix.getPoint3dBatch(i_offset.vertex,vertex_3d,4);\r
+               this._transsolver.solveTransportVector(vertex_3d,trans);\r
+               \r
+               //計算結果の最適化(平行移動量と回転行列の最適化)\r
+               double err=this.optimize(this._rotmatrix, trans, this._transsolver,i_offset.vertex, vertex_2d);\r
+               \r
+               // マトリクスの保存\r
+               o_result.setValue(this._rotmatrix,  trans, err);\r
+               \r
+               // エラー値が許容範囲でなければTransMatをやり直し\r
+               if (err > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {\r
+                       // rotationを矩形情報で初期化\r
+                       this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
+                       //回転行列の平行移動量の計算\r
+                       this._rotmatrix.getPoint3dBatch(i_offset.vertex,vertex_3d,4);\r
+                       this._transsolver.solveTransportVector(vertex_3d,trans);\r
+                       //計算結果の最適化(this._rotmatrix,trans)\r
+                       final double err2=this.optimize(this._rotmatrix, trans, this._transsolver,i_offset.vertex, vertex_2d);\r
+                       //エラー値が低かったら値を差換え\r
+                       if (err2 < err) {\r
+                               // 良い値が取れたら、差換え\r
+                               o_result.setValue(this._rotmatrix, trans, err2);\r
+                       }\r
+                       err=err2;\r
+               }\r
+               //エラー値保存\r
+               return;\r
+       }\r
+       private double optimize(NyARRotMatrix_ARToolKit io_rotmat,NyARDoublePoint3d io_transvec,INyARTransportVectorSolver i_solver,NyARDoublePoint3d[] i_offset_3d,NyARDoublePoint2d[] i_2d_vertex) throws NyARException\r
+       {\r
+               NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+               double err = -1;\r
+               //System.out.println("START");\r
+               // ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。 \r
+               for (int i = 0;; i++) {\r
+                       // <arGetTransMat3>\r
+                       err = this._mat_optimize.modifyMatrix(io_rotmat, io_transvec, i_offset_3d, i_2d_vertex);\r
+                       io_rotmat.getPoint3dBatch(i_offset_3d,vertex_3d,4);\r
+                       i_solver.solveTransportVector(vertex_3d, io_transvec);\r
+                       \r
+                       err = this._mat_optimize.modifyMatrix(io_rotmat, io_transvec, i_offset_3d, i_2d_vertex);\r
+                       //System.out.println("E:"+err*4);\r
+                       // //</arGetTransMat3>\r
+                       if (err < AR_GET_TRANS_MAT_MAX_FIT_ERROR || i == AR_GET_TRANS_MAT_MAX_LOOP_COUNT - 1) {\r
+                               break;\r
+                       }\r
+                       io_rotmat.getPoint3dBatch(i_offset_3d,vertex_3d,4);\r
+                       i_solver.solveTransportVector(vertex_3d, io_transvec);\r
+               }\r
+               //System.out.println("END");\r
+               return err;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARPartialDifferentiationOptimize.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARPartialDifferentiationOptimize.java
new file mode 100644 (file)
index 0000000..1611dd5
--- /dev/null
@@ -0,0 +1,338 @@
+/* \r
+ * PROJECT: NyARToolkit (Extension)\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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+\r
+class TSinCosValue{\r
+       public double cos_val;\r
+       public double sin_val;\r
+       public static TSinCosValue[] createArray(int i_size)\r
+       {\r
+               TSinCosValue[] result=new TSinCosValue[i_size];\r
+               for(int i=0;i<i_size;i++){\r
+                       result[i]=new TSinCosValue();\r
+               }\r
+               return result;\r
+       }\r
+}\r
+\r
+/**\r
+ * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算 を繰り返して、変換行列を最適化する。\r
+ * \r
+ */\r
+public class NyARPartialDifferentiationOptimize\r
+{\r
+       private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+\r
+       public NyARPartialDifferentiationOptimize(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+       {\r
+               this._projection_mat_ref = i_projection_mat_ref;\r
+               return;\r
+       }\r
+       /*\r
+        * 射影変換式 基本式 ox=(cosc * cosb - sinc * sina * sinb)*ix+(-sinc * cosa)*iy+(cosc * sinb + sinc * sina * cosb)*iz+i_trans.x; oy=(sinc * cosb + cosc * sina *\r
+        * sinb)*ix+(cosc * cosa)*iy+(sinc * sinb - cosc * sina * cosb)*iz+i_trans.y; oz=(-cosa * sinb)*ix+(sina)*iy+(cosb * cosa)*iz+i_trans.z;\r
+        * \r
+        * double ox=(cosc * cosb)*ix+(-sinc * sina * sinb)*ix+(-sinc * cosa)*iy+(cosc * sinb)*iz + (sinc * sina * cosb)*iz+i_trans.x; double oy=(sinc * cosb)*ix\r
+        * +(cosc * sina * sinb)*ix+(cosc * cosa)*iy+(sinc * sinb)*iz+(- cosc * sina * cosb)*iz+i_trans.y; double oz=(-cosa * sinb)*ix+(sina)*iy+(cosb *\r
+        * cosa)*iz+i_trans.z;\r
+        * \r
+        * sina,cosaについて解く cx=(cp00*(-sinc*sinb*ix+sinc*cosb*iz)+cp01*(cosc*sinb*ix-cosc*cosb*iz)+cp02*(iy))*sina\r
+        * +(cp00*(-sinc*iy)+cp01*((cosc*iy))+cp02*(-sinb*ix+cosb*iz))*cosa\r
+        * +(cp00*(i_trans.x+cosc*cosb*ix+cosc*sinb*iz)+cp01*((i_trans.y+sinc*cosb*ix+sinc*sinb*iz))+cp02*(i_trans.z));\r
+        * cy=(cp11*(cosc*sinb*ix-cosc*cosb*iz)+cp12*(iy))*sina +(cp11*((cosc*iy))+cp12*(-sinb*ix+cosb*iz))*cosa\r
+        * +(cp11*((i_trans.y+sinc*cosb*ix+sinc*sinb*iz))+cp12*(i_trans.z)); ch=(iy)*sina +(-sinb*ix+cosb*iz)*cosa +i_trans.z; sinb,cosb hx=(cp00*(-sinc *\r
+        * sina*ix+cosc*iz)+cp01*(cosc * sina*ix+sinc*iz)+cp02*(-cosa*ix))*sinb +(cp01*(sinc*ix-cosc * sina*iz)+cp00*(cosc*ix+sinc * sina*iz)+cp02*(cosa*iz))*cosb\r
+        * +(cp00*(i_trans.x+(-sinc*cosa)*iy)+cp01*(i_trans.y+(cosc * cosa)*iy)+cp02*(i_trans.z+(sina)*iy)); double hy=(cp11*(cosc *\r
+        * sina*ix+sinc*iz)+cp12*(-cosa*ix))*sinb +(cp11*(sinc*ix-cosc * sina*iz)+cp12*(cosa*iz))*cosb +(cp11*(i_trans.y+(cosc *\r
+        * cosa)*iy)+cp12*(i_trans.z+(sina)*iy)); double h =((-cosa*ix)*sinb +(cosa*iz)*cosb +i_trans.z+(sina)*iy); パラメータ返還式 L=2*Σ(d[n]*e[n]+a[n]*b[n])\r
+        * J=2*Σ(d[n]*f[n]+a[n]*c[n])/L K=2*Σ(-e[n]*f[n]+b[n]*c[n])/L M=Σ(-e[n]^2+d[n]^2-b[n]^2+a[n]^2)/L 偏微分式 +J*cos(x) +K*sin(x) -sin(x)^2 +cos(x)^2\r
+        * +2*M*cos(x)*sin(x)\r
+        */\r
+       private double optimizeParamX(double sinb,double cosb,double sinc,double cosc,NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d, int i_number_of_vertex, double i_hint_angle) throws NyARException\r
+       {\r
+               NyARPerspectiveProjectionMatrix cp = this._projection_mat_ref;\r
+               double L, J, K, M, N, O;\r
+               L = J = K = M = N = O = 0;\r
+               final double cp00 = cp.m00;\r
+               final double cp01 = cp.m01;\r
+               final double cp02 = cp.m02;\r
+               final double cp11 = cp.m11;\r
+               final double cp12 = cp.m12;\r
+\r
+               for (int i = 0; i < i_number_of_vertex; i++) {\r
+                       double ix, iy, iz;\r
+                       ix = i_vertex3d[i].x;\r
+                       iy = i_vertex3d[i].y;\r
+                       iz = i_vertex3d[i].z;\r
+\r
+                       double X0 = (cp00 * (-sinc * sinb * ix + sinc * cosb * iz) + cp01 * (cosc * sinb * ix - cosc * cosb * iz) + cp02 * (iy));\r
+                       double X1 = (cp00 * (-sinc * iy) + cp01 * ((cosc * iy)) + cp02 * (-sinb * ix + cosb * iz));\r
+                       double X2 = (cp00 * (i_trans.x + cosc * cosb * ix + cosc * sinb * iz) + cp01 * ((i_trans.y + sinc * cosb * ix + sinc * sinb * iz)) + cp02 * (i_trans.z));\r
+                       double Y0 = (cp11 * (cosc * sinb * ix - cosc * cosb * iz) + cp12 * (iy));\r
+                       double Y1 = (cp11 * ((cosc * iy)) + cp12 * (-sinb * ix + cosb * iz));\r
+                       double Y2 = (cp11 * ((i_trans.y + sinc * cosb * ix + sinc * sinb * iz)) + cp12 * (i_trans.z));\r
+                       double H0 = (iy);\r
+                       double H1 = (-sinb * ix + cosb * iz);\r
+                       double H2 = i_trans.z;\r
+\r
+                       double VX = i_vertex2d[i].x;\r
+                       double VY = i_vertex2d[i].y;\r
+\r
+                       double a, b, c, d, e, f;\r
+                       a = (VX * H0 - X0);\r
+                       b = (VX * H1 - X1);\r
+                       c = (VX * H2 - X2);\r
+                       d = (VY * H0 - Y0);\r
+                       e = (VY * H1 - Y1);\r
+                       f = (VY * H2 - Y2);\r
+\r
+                       L += d * e + a * b;\r
+                       N += d * d + a * a;\r
+                       J += d * f + a * c;\r
+                       M += e * e + b * b;\r
+                       K += e * f + b * c;\r
+                       O += f * f + c * c;\r
+\r
+               }\r
+               L *=2;\r
+               J *=2;\r
+               K *=2;\r
+\r
+               return getMinimumErrorAngleFromParam(L,J, K, M, N, O, i_hint_angle);\r
+\r
+\r
+       }\r
+\r
+       private double optimizeParamY(double sina,double cosa,double sinc,double cosc, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d, int i_number_of_vertex, double i_hint_angle) throws NyARException\r
+       {\r
+               NyARPerspectiveProjectionMatrix cp = this._projection_mat_ref;\r
+               double L, J, K, M, N, O;\r
+               L = J = K = M = N = O = 0;\r
+               final double cp00 = cp.m00;\r
+               final double cp01 = cp.m01;\r
+               final double cp02 = cp.m02;\r
+               final double cp11 = cp.m11;\r
+               final double cp12 = cp.m12;\r
+\r
+               for (int i = 0; i < i_number_of_vertex; i++) {\r
+                       double ix, iy, iz;\r
+                       ix = i_vertex3d[i].x;\r
+                       iy = i_vertex3d[i].y;\r
+                       iz = i_vertex3d[i].z;\r
+\r
+                       double X0 = (cp00 * (-sinc * sina * ix + cosc * iz) + cp01 * (cosc * sina * ix + sinc * iz) + cp02 * (-cosa * ix));\r
+                       double X1 = (cp01 * (sinc * ix - cosc * sina * iz) + cp00 * (cosc * ix + sinc * sina * iz) + cp02 * (cosa * iz));\r
+                       double X2 = (cp00 * (i_trans.x + (-sinc * cosa) * iy) + cp01 * (i_trans.y + (cosc * cosa) * iy) + cp02 * (i_trans.z + (sina) * iy));\r
+                       double Y0 = (cp11 * (cosc * sina * ix + sinc * iz) + cp12 * (-cosa * ix));\r
+                       double Y1 = (cp11 * (sinc * ix - cosc * sina * iz) + cp12 * (cosa * iz));\r
+                       double Y2 = (cp11 * (i_trans.y + (cosc * cosa) * iy) + cp12 * (i_trans.z + (sina) * iy));\r
+                       double H0 = (-cosa * ix);\r
+                       double H1 = (cosa * iz);\r
+                       double H2 = i_trans.z + (sina) * iy;\r
+\r
+                       double VX = i_vertex2d[i].x;\r
+                       double VY = i_vertex2d[i].y;\r
+\r
+                       double a, b, c, d, e, f;\r
+                       a = (VX * H0 - X0);\r
+                       b = (VX * H1 - X1);\r
+                       c = (VX * H2 - X2);\r
+                       d = (VY * H0 - Y0);\r
+                       e = (VY * H1 - Y1);\r
+                       f = (VY * H2 - Y2);\r
+\r
+                       L += d * e + a * b;\r
+                       N += d * d + a * a;\r
+                       J += d * f + a * c;\r
+                       M += e * e + b * b;\r
+                       K += e * f + b * c;\r
+                       O += f * f + c * c;\r
+\r
+               }\r
+               L *= 2;\r
+               J *= 2;\r
+               K *= 2;\r
+               return getMinimumErrorAngleFromParam(L,J, K, M, N, O, i_hint_angle);\r
+\r
+       }\r
+\r
+       private double optimizeParamZ(double sina,double cosa,double sinb,double cosb, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d, int i_number_of_vertex, double i_hint_angle) throws NyARException\r
+       {\r
+               NyARPerspectiveProjectionMatrix cp = this._projection_mat_ref;\r
+               double L, J, K, M, N, O;\r
+               L = J = K = M = N = O = 0;\r
+               final double cp00 = cp.m00;\r
+               final double cp01 = cp.m01;\r
+               final double cp02 = cp.m02;\r
+               final double cp11 = cp.m11;\r
+               final double cp12 = cp.m12;\r
+\r
+               for (int i = 0; i < i_number_of_vertex; i++) {\r
+                       double ix, iy, iz;\r
+                       ix = i_vertex3d[i].x;\r
+                       iy = i_vertex3d[i].y;\r
+                       iz = i_vertex3d[i].z;\r
+\r
+                       double X0 = (cp00 * (-sina * sinb * ix - cosa * iy + sina * cosb * iz) + cp01 * (ix * cosb + sinb * iz));\r
+                       double X1 = (cp01 * (sina * ix * sinb + cosa * iy - sina * iz * cosb) + cp00 * (cosb * ix + sinb * iz));\r
+                       double X2 = cp00 * i_trans.x + cp01 * (i_trans.y) + cp02 * (-cosa * sinb) * ix + cp02 * (sina) * iy + cp02 * ((cosb * cosa) * iz + i_trans.z);\r
+                       double Y0 = cp11 * (ix * cosb + sinb * iz);\r
+                       double Y1 = cp11 * (sina * ix * sinb + cosa * iy - sina * iz * cosb);\r
+                       double Y2 = (cp11 * i_trans.y + cp12 * (-cosa * sinb) * ix + cp12 * ((sina) * iy + (cosb * cosa) * iz + i_trans.z));\r
+                       double H0 = 0;\r
+                       double H1 = 0;\r
+                       double H2 = ((-cosa * sinb) * ix + (sina) * iy + (cosb * cosa) * iz + i_trans.z);\r
+\r
+                       double VX = i_vertex2d[i].x;\r
+                       double VY = i_vertex2d[i].y;\r
+\r
+                       double a, b, c, d, e, f;\r
+                       a = (VX * H0 - X0);\r
+                       b = (VX * H1 - X1);\r
+                       c = (VX * H2 - X2);\r
+                       d = (VY * H0 - Y0);\r
+                       e = (VY * H1 - Y1);\r
+                       f = (VY * H2 - Y2);\r
+\r
+                       L += d * e + a * b;\r
+                       N += d * d + a * a;\r
+                       J += d * f + a * c;\r
+                       M += e * e + b * b;\r
+                       K += e * f + b * c;\r
+                       O += f * f + c * c;\r
+\r
+               }\r
+               L *=2;\r
+               J *=2;\r
+               K *=2;\r
+               \r
+               return getMinimumErrorAngleFromParam(L,J, K, M, N, O, i_hint_angle);\r
+       }\r
+       private NyARDoublePoint3d __ang=new NyARDoublePoint3d();\r
+       public void modifyMatrix(NyARDoubleMatrix33 io_rot, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d, int i_number_of_vertex) throws NyARException\r
+       {\r
+               NyARDoublePoint3d ang = this.__ang;             \r
+               // ZXY系のsin/cos値を抽出\r
+               io_rot.getZXYAngle(ang);\r
+               modifyMatrix(ang,i_trans,i_vertex3d,i_vertex2d,i_number_of_vertex,ang);\r
+               io_rot.setZXYAngle(ang.x, ang.y, ang.z);\r
+               return;\r
+       }\r
+       public void modifyMatrix(NyARDoublePoint3d i_angle,NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d, int i_number_of_vertex,NyARDoublePoint3d o_angle) throws NyARException\r
+       {\r
+\r
+               // ZXY系のsin/cos値を抽出\r
+               double sinx = Math.sin(i_angle.x);\r
+               double cosx = Math.cos(i_angle.x);\r
+               double siny = Math.sin(i_angle.y);\r
+               double cosy = Math.cos(i_angle.y);\r
+               double sinz = Math.sin(i_angle.z);\r
+               double cosz = Math.cos(i_angle.z);              \r
+               o_angle.x = i_angle.x+optimizeParamX(siny,cosy,sinz,cosz, i_trans, i_vertex3d, i_vertex2d, i_number_of_vertex, i_angle.x);\r
+               o_angle.y = i_angle.y+optimizeParamY(sinx,cosx,sinz,cosz, i_trans, i_vertex3d, i_vertex2d, i_number_of_vertex, i_angle.y);\r
+               o_angle.z = i_angle.z+optimizeParamZ(sinx,cosx,siny,cosy, i_trans, i_vertex3d, i_vertex2d, i_number_of_vertex, i_angle.z);\r
+               return; \r
+       }\r
+       \r
+       private double[] __sin_table= new double[4];\r
+       /**\r
+        * エラーレートが最小になる点を得る。\r
+        */\r
+       private double getMinimumErrorAngleFromParam(double iL,double iJ, double iK, double iM, double iN, double iO, double i_hint_angle) throws NyARException\r
+       {\r
+               double[] sin_table = this.__sin_table;\r
+\r
+               double M = (iN - iM)/iL;\r
+               double J = iJ/iL;\r
+               double K = -iK/iL;\r
+\r
+               // パラメータからsinテーブルを作成\r
+               // (- 4*M^2-4)*x^4 + (4*K- 4*J*M)*x^3 + (4*M^2 -(K^2- 4)- J^2)*x^2 +(4*J*M- 2*K)*x + J^2-1 = 0\r
+               int number_of_sin = NyAREquationSolver.solve4Equation(-4 * M * M - 4, 4 * K - 4 * J * M, 4 * M * M - (K * K - 4) - J * J, 4 * J * M - 2 * K, J * J - 1, sin_table);\r
+\r
+\r
+               // 最小値2個を得ておく。\r
+               double min_ang_0 = Double.MAX_VALUE;\r
+               double min_ang_1 = Double.MAX_VALUE;\r
+               double min_err_0 = Double.MAX_VALUE;\r
+               double min_err_1 = Double.MAX_VALUE;\r
+               for (int i = 0; i < number_of_sin; i++) {\r
+                       // +-cos_v[i]が頂点候補\r
+                       double sin_rt = sin_table[i];\r
+                       double cos_rt = Math.sqrt(1 - (sin_rt * sin_rt));\r
+                       // cosを修復。微分式で0に近い方が正解\r
+                       // 0 = 2*cos(x)*sin(x)*M - sin(x)^2 + cos(x)^2 + sin(x)*K + cos(x)*J\r
+                       double a1 = 2 * cos_rt * sin_rt * M + sin_rt * (K - sin_rt) + cos_rt * (cos_rt + J);\r
+                       double a2 = 2 * (-cos_rt) * sin_rt * M + sin_rt * (K - sin_rt) + (-cos_rt) * ((-cos_rt) + J);\r
+                       // 絶対値になおして、真のcos値を得ておく。\r
+                       a1 = a1 < 0 ? -a1 : a1;\r
+                       a2 = a2 < 0 ? -a2 : a2;\r
+                       cos_rt = (a1 < a2) ? cos_rt : -cos_rt;\r
+                       double ang = Math.atan2(sin_rt, cos_rt);\r
+                       // エラー値を計算\r
+                       double err = iN * sin_rt * sin_rt + (iL*cos_rt + iJ) * sin_rt + iM * cos_rt * cos_rt + iK * cos_rt + iO;\r
+                       // 最小の2個を獲得する。\r
+                       if (min_err_0 > err) {\r
+                               min_err_1 = min_err_0;\r
+                               min_ang_1 = min_ang_0;\r
+                               min_err_0 = err;\r
+                               min_ang_0 = ang;\r
+                       } else if (min_err_1 > err) {\r
+                               min_err_1 = err;\r
+                               min_ang_1 = ang;\r
+                       }\r
+               }\r
+               // [0]をテスト\r
+               double gap_0;\r
+               gap_0 = min_ang_0 - i_hint_angle;\r
+               if (gap_0 > Math.PI) {\r
+                       gap_0 = (min_ang_0 - Math.PI * 2) - i_hint_angle;\r
+               } else if (gap_0 < -Math.PI) {\r
+                       gap_0 = (min_ang_0 + Math.PI * 2) - i_hint_angle;\r
+               }\r
+               // [1]をテスト\r
+               double gap_1;\r
+               gap_1 = min_ang_1 - i_hint_angle;\r
+               if (gap_1 > Math.PI) {\r
+                       gap_1 = (min_ang_1 - Math.PI * 2) - i_hint_angle;\r
+               } else if (gap_1 < -Math.PI) {\r
+                       gap_1 = (min_ang_1 + Math.PI * 2) - i_hint_angle;\r
+               }\r
+               return Math.abs(gap_1) < Math.abs(gap_0) ? gap_1 : gap_0;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/INyARRotMatrixOptimize.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/INyARRotMatrixOptimize.java
new file mode 100644 (file)
index 0000000..a8d126b
--- /dev/null
@@ -0,0 +1,55 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public interface INyARRotMatrixOptimize\r
+{\r
+       /**\r
+        * @param io_rot\r
+        * 初期回転行列\r
+        * @param i_trans\r
+        * 初期並進ベクトル\r
+        * @param i_vertex3d\r
+        * 初期3次元座標\r
+        * @param i_vertex2d\r
+        * 画面上の頂点群\r
+        * @return\r
+        * エラーレート\r
+        * @throws NyARException\r
+        */\r
+//     public double optimize(NyARRotMatrix io_rotmat,NyARDoublePoint3d io_transvec,INyARTransportVectorSolver i_solver,NyARDoublePoint3d[] i_offset_3d,NyARDoublePoint2d[] i_2d_vertex) throws NyARException;\r
+       public double modifyMatrix(NyARRotMatrix_ARToolKit io_rot, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException;\r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/NyARRotMatrixOptimize.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/NyARRotMatrixOptimize.java
new file mode 100644 (file)
index 0000000..d43f7b0
--- /dev/null
@@ -0,0 +1,286 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.solver.INyARTransportVectorSolver;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+/**\r
+ * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算\r
+ * を繰り返して、変換行列を最適化する。\r
+ *\r
+ */\r
+public class NyARRotMatrixOptimize implements INyARRotMatrixOptimize\r
+{\r
+       private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5\r
+       private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0\r
+       private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+       public NyARRotMatrixOptimize(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+       {\r
+               this._projection_mat_ref=i_projection_mat_ref;\r
+               return;\r
+       }\r
+       final public double optimize(NyARRotMatrix_ARToolKit io_rotmat,NyARDoublePoint3d io_transvec,INyARTransportVectorSolver i_solver,NyARDoublePoint3d[] i_offset_3d,NyARDoublePoint2d[] i_2d_vertex) throws NyARException\r
+       {\r
+               double err = -1;\r
+               /*ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。*/\r
+               for (int i = 0;; i++) {\r
+                       // <arGetTransMat3>\r
+                       err = modifyMatrix(io_rotmat,io_transvec,i_offset_3d,i_2d_vertex);\r
+                       i_solver.solveTransportVector(i_offset_3d, io_transvec);\r
+                       err = modifyMatrix(io_rotmat,io_transvec,i_offset_3d,i_2d_vertex);                      \r
+                       // //</arGetTransMat3>\r
+                       if (err < AR_GET_TRANS_MAT_MAX_FIT_ERROR || i == AR_GET_TRANS_MAT_MAX_LOOP_COUNT-1) {\r
+                               break;\r
+                       }\r
+                       i_solver.solveTransportVector(i_offset_3d, io_transvec);\r
+               }               \r
+               return err;\r
+       }\r
+       \r
+       private final double[][] __modifyMatrix_double1D = new double[8][3];\r
+       /**\r
+        * arGetRot計算を階層化したModifyMatrix 896\r
+        * \r
+        * @param nyrot\r
+        * @param trans\r
+        * @param i_vertex3d\r
+        * [m][3]\r
+        * @param i_vertex2d\r
+        * [n][2]\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public double modifyMatrix(NyARRotMatrix_ARToolKit io_rot,NyARDoublePoint3d trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) 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
+               NyARDoublePoint3d d_pt;\r
+               d_pt = i_vertex3d[0];\r
+               VX00 = d_pt.x;\r
+               VX01 = d_pt.y;\r
+               VX02 = d_pt.z;\r
+               d_pt = i_vertex3d[1];\r
+               VX10 = d_pt.x;\r
+               VX11 = d_pt.y;\r
+               VX12 = d_pt.z;\r
+               d_pt = i_vertex3d[2];\r
+               VX20 = d_pt.x;\r
+               VX21 = d_pt.y;\r
+               VX22 = d_pt.z;\r
+               d_pt = i_vertex3d[3];\r
+               VX30 = d_pt.x;\r
+               VX31 = d_pt.y;\r
+               VX32 = d_pt.z;\r
+               final double P2D00, P2D01, P2D10, P2D11, P2D20, P2D21, P2D30, P2D31;\r
+               NyARDoublePoint2d d_pt2;\r
+               d_pt2 = i_vertex2d[0];\r
+               P2D00 = d_pt2.x;\r
+               P2D01 = d_pt2.y;\r
+               d_pt2 = i_vertex2d[1];\r
+               P2D10 = d_pt2.x;\r
+               P2D11 = d_pt2.y;\r
+               d_pt2 = i_vertex2d[2];\r
+               P2D20 = d_pt2.x;\r
+               P2D21 = d_pt2.y;\r
+               d_pt2 = i_vertex2d[3];\r
+               P2D30 = d_pt2.x;\r
+               P2D31 = d_pt2.y;\r
+               final NyARPerspectiveProjectionMatrix prjmat = this._projection_mat_ref;\r
+               final double CP0, CP1, CP2, CP4, CP5, CP6, CP8, CP9, CP10;\r
+               CP0 = prjmat.m00;\r
+               CP1 = prjmat.m01;\r
+               CP2 = prjmat.m02;\r
+               CP4 = prjmat.m10;\r
+               CP5 = prjmat.m11;\r
+               CP6 = prjmat.m12;\r
+               CP8 = prjmat.m20;\r
+               CP9 = prjmat.m21;\r
+               CP10 = prjmat.m22;\r
+               combo03 = CP0 * trans.x + CP1 * trans.y + CP2 * trans.z + prjmat.m03;\r
+               combo13 = CP4 * trans.x + CP5 * trans.y + CP6 * trans.z + prjmat.m13;\r
+               combo23 = CP8 * trans.x + CP9 * trans.y + CP10 * trans.z + prjmat.m23;\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.__modifyMatrix_double1D;\r
+\r
+\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
+               //現在の角度を確保\r
+               final NyARDoublePoint3d angle = io_rot.refAngle();\r
+               a2 = angle.x;\r
+               b2 = angle.y;\r
+               c2 = angle.z;\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
+               io_rot.setAngle(ma, mb, mc);\r
+               /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+               return minerr / 4;\r
+       }       \r
+       \r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/NyARRotMatrixOptimize_Base.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/NyARRotMatrixOptimize_Base.java
new file mode 100644 (file)
index 0000000..da1d263
--- /dev/null
@@ -0,0 +1,194 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 処理構造がわかる程度に展開したNyARRotTransOptimize\r
+ * \r
+ */\r
+public class NyARRotMatrixOptimize_Base implements INyARRotMatrixOptimize\r
+{\r
+       private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+\r
+       public NyARRotMatrixOptimize_Base(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+       {\r
+               this._projection_mat_ref = i_projection_mat_ref;\r
+               return;\r
+       }\r
+       private double[] __createRotationMap_b_map=new double[6];\r
+       private double[] __createRotationMap_c_map=new double[6];\r
+       private double[] __createRotationMap_f=new double[3];\r
+       private void createRotationMap(NyARDoublePoint3d i_angle,double i_factor,NyARDoubleMatrix33[] i_rot_matrix)\r
+       {\r
+               double sina,cosa,sinb,cosb,sinc,cosc;\r
+               double CACA,SASA,SACA,SASB,CASB,SACACB,CACACB,SASACB;\r
+\r
+               \r
+               final double[] f=this.__createRotationMap_f;\r
+               final double[] b_map=this.__createRotationMap_b_map;\r
+               final double[] c_map=this.__createRotationMap_c_map;\r
+               f[0]=-i_factor;\r
+               f[1]=0;\r
+               f[2]=i_factor;\r
+               double ang1,ang2;\r
+               //BとCのsinマップを先に作成\r
+               for(int i=0;i<3;i++)\r
+               {\r
+                       ang1=i_angle.y + f[i];\r
+                       b_map[i]  =Math.sin(ang1);\r
+                       b_map[i+3]=Math.cos(ang1);\r
+                       ang2=i_angle.z + f[i];\r
+                       c_map[i]  =Math.sin(ang2);\r
+                       c_map[i+3]=Math.cos(ang2);\r
+               }\r
+               int idx=0;\r
+               int t1,t2,t3;\r
+               for (t1 = 0; t1 < 3; t1++){\r
+                       ang1=i_angle.x + f[t1];\r
+                       sina = Math.sin(ang1);\r
+                       cosa = Math.cos(ang1);                  \r
+                       CACA = cosa * cosa;\r
+                       SASA = sina * sina;\r
+                       SACA = sina * cosa;\r
+\r
+                       for (t2=0;t2<3;t2++){\r
+                               sinb = b_map[t2];\r
+                               cosb = b_map[t2+3];\r
+                               SASB = sina * sinb;\r
+                               CASB = cosa * sinb;\r
+                               SACACB = SACA * cosb;\r
+                CACACB = CACA * cosb;\r
+                SASACB = SASA * cosb;          \r
+                               for (t3=0;t3<3;t3++) {\r
+                                       sinc = c_map[t3];\r
+                                       cosc = c_map[t3+3];\r
+                                       final NyARDoubleMatrix33 mat_ptr=i_rot_matrix[idx];\r
+                                       mat_ptr.m00 = CACACB * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;\r
+                                       mat_ptr.m01 = -CACACB * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;\r
+                                       mat_ptr.m02 = CASB;\r
+                                       mat_ptr.m10 = SACACB * cosc - SACA * cosc + SASACB * sinc + CACA * sinc;\r
+                                       mat_ptr.m11 = -SACACB * sinc + SACA * sinc + SASACB * cosc + CACA * cosc;\r
+                                       mat_ptr.m12 = SASB;\r
+                                       mat_ptr.m20 = -CASB * cosc - SASB * sinc;\r
+                                       mat_ptr.m21 = CASB * sinc - SASB * cosc;\r
+                                       mat_ptr.m22 = cosb;\r
+                                       idx++;\r
+                               }\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+       private final void getNewMatrix(NyARDoubleMatrix33 i_rot, NyARDoublePoint3d i_trans, NyARDoubleMatrix34 o_combo)\r
+       {\r
+               double cp0,cp1,cp2,cp3;\r
+               NyARPerspectiveProjectionMatrix cp=this._projection_mat_ref;\r
+\r
+               cp3=cp.m03;\r
+               cp0=cp.m00;cp1=cp.m01;cp2=cp.m02;\r
+               o_combo.m00=cp0 * i_rot.m00 + cp1 * i_rot.m10 + cp2 * i_rot.m20;\r
+               o_combo.m01=cp0 * i_rot.m01 + cp1 * i_rot.m11 + cp2 * i_rot.m21;\r
+               o_combo.m02=cp0 * i_rot.m02 + cp1 * i_rot.m12 + cp2 * i_rot.m22;\r
+               o_combo.m03=cp0 * i_trans.x + cp1 * i_trans.y + cp2 * i_trans.z +cp3;\r
+\r
+               cp0=cp.m10;cp1=cp.m11;cp2=cp.m12;\r
+               o_combo.m10=cp0 * i_rot.m00 + cp1 * i_rot.m10 + cp2 * i_rot.m20;\r
+               o_combo.m11=cp0 * i_rot.m01 + cp1 * i_rot.m11 + cp2 * i_rot.m21;\r
+               o_combo.m12=cp0 * i_rot.m02 + cp1 * i_rot.m12 + cp2 * i_rot.m22;\r
+               o_combo.m13=cp0 * i_trans.x + cp1 * i_trans.y + cp2 * i_trans.z +cp3;\r
+\r
+               cp0=cp.m20;cp1=cp.m21;cp2=cp.m22;\r
+               o_combo.m20=cp0 * i_rot.m00 + cp1 * i_rot.m10 + cp2 * i_rot.m20;\r
+               o_combo.m21=cp0 * i_rot.m01 + cp1 * i_rot.m11 + cp2 * i_rot.m21;\r
+               o_combo.m22=cp0 * i_rot.m02 + cp1 * i_rot.m12 + cp2 * i_rot.m22;\r
+               o_combo.m23=cp0 * i_trans.x + cp1 * i_trans.y + cp2 * i_trans.z +cp3;\r
+               return;\r
+       }\r
+       private final NyARDoublePoint3d __modifyMatrix_angle = new NyARDoublePoint3d();\r
+       private final NyARDoubleMatrix34 __modifyMatrix_combo=new NyARDoubleMatrix34();\r
+       private final NyARDoubleMatrix33[] __modifyMatrix_next_rot_matrix=NyARDoubleMatrix33.createArray(27); \r
+       public double modifyMatrix(NyARRotMatrix_ARToolKit io_rot, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException\r
+       {\r
+               final NyARDoublePoint3d angle = this.__modifyMatrix_angle;\r
+               final NyARDoubleMatrix34 combo=this.__modifyMatrix_combo;\r
+               final NyARDoubleMatrix33[] next_rot_matrix=this.__modifyMatrix_next_rot_matrix;\r
+               double factor;\r
+               double hx, hy, h, x, y;\r
+               double err, minerr = 0;\r
+               int i,i2;\r
+               int best_idx=0;\r
+               angle.setValue(io_rot.refAngle());// arGetAngle( rot, &a, &b, &c );\r
+               factor = 10.0 * Math.PI / 180.0;\r
+               for (int j = 0; j < 10; j++){\r
+                       minerr = 1000000000.0;\r
+                       //評価用の角度マップ作成\r
+                       createRotationMap(angle,factor,next_rot_matrix);\r
+                       //評価して一番宜しいIDを保存\r
+                       best_idx=(1+1*3+1*9);\r
+                       for(i2=0;i2<27;i2++){\r
+                               this.getNewMatrix(next_rot_matrix[i2],i_trans,combo);\r
+                               err = 0.0;\r
+                               for (i = 0; i < 4; i++) {\r
+                                       hx =  combo.m00 * i_vertex3d[i].x + combo.m01 * i_vertex3d[i].y + combo.m02 * i_vertex3d[i].z + combo.m03;\r
+                                       hy = combo.m10 * i_vertex3d[i].x + combo.m11 *i_vertex3d[i].y + combo.m12 * i_vertex3d[i].z + combo.m13;\r
+                                       h = combo.m20 * i_vertex3d[i].x + combo.m21 * i_vertex3d[i].y + combo.m22 * i_vertex3d[i].z + combo.m23;\r
+                                       x = i_vertex2d[i].x-(hx / h);\r
+                                       y = i_vertex2d[i].y-(hy / h);\r
+                                       err += x*x+y*y;\r
+                               }\r
+                               if (err < minerr){\r
+                                       minerr = err;\r
+                                       best_idx=i2;\r
+                               }\r
+                               \r
+                       }\r
+                       if (best_idx==(1+1*3+1*9)){\r
+                               factor *= 0.5;                  \r
+                       }else{\r
+                               angle.z+=factor*(best_idx%3-1);\r
+                               angle.y+=factor*((best_idx/3)%3-1);\r
+                               angle.x+=factor*((best_idx/9)%3-1);                             \r
+                       }\r
+               }\r
+               io_rot.setAngle(angle.x,angle.y,angle.z);\r
+               /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+               return minerr / 4;\r
+       }\r
+\r
+\r
+\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/NyARRotMatrixOptimize_O2.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/optimize/artoolkit/NyARRotMatrixOptimize_O2.java
new file mode 100644 (file)
index 0000000..b5f4ae3
--- /dev/null
@@ -0,0 +1,236 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+/**\r
+ * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算\r
+ * を繰り返して、変換行列を最適化する。\r
+ *\r
+ */\r
+public class NyARRotMatrixOptimize_O2 implements INyARRotMatrixOptimize\r
+{\r
+       private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+       public NyARRotMatrixOptimize_O2(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+       {\r
+               this._projection_mat_ref=i_projection_mat_ref;\r
+               return;\r
+       }\r
+       private final double[][] __modifyMatrix_double1D = new double[8][3];\r
+       /**\r
+        * arGetRot計算を階層化したModifyMatrix 896\r
+        * \r
+        * @param trans\r
+        * @param i_vertex3d\r
+        * [m][3]\r
+        * @param i_vertex2d\r
+        * [n][2]\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public double modifyMatrix(NyARRotMatrix_ARToolKit io_rot,NyARDoublePoint3d trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException\r
+       {\r
+               double factor;\r
+               double a2, b2, c2;\r
+               double h, x, y;\r
+               double err, minerr = 0;\r
+               int t1, t2, t3;\r
+               int best_idx=0;\r
+\r
+               factor = 10.0 * Math.PI / 180.0;\r
+               double rot0, rot1, rot2;\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
+               VX00 = i_vertex3d[0].x;\r
+               VX01 = i_vertex3d[0].y;\r
+               VX02 = i_vertex3d[0].z;\r
+               VX10 = i_vertex3d[1].x;\r
+               VX11 = i_vertex3d[1].y;\r
+               VX12 = i_vertex3d[1].z;\r
+               VX20 = i_vertex3d[2].x;\r
+               VX21 = i_vertex3d[2].y;\r
+               VX22 = i_vertex3d[2].z;\r
+               VX30 = i_vertex3d[3].x;\r
+               VX31 = i_vertex3d[3].y;\r
+               VX32 = i_vertex3d[3].z;\r
+               final double P2D00, P2D01, P2D10, P2D11, P2D20, P2D21, P2D30, P2D31;\r
+               P2D00 = i_vertex2d[0].x;\r
+               P2D01 = i_vertex2d[0].y;\r
+               P2D10 = i_vertex2d[1].x;\r
+               P2D11 = i_vertex2d[1].y;\r
+               P2D20 = i_vertex2d[2].x;\r
+               P2D21 = i_vertex2d[2].y;\r
+               P2D30 = i_vertex2d[3].x;\r
+               P2D31 = i_vertex2d[3].y;\r
+               final NyARPerspectiveProjectionMatrix prjmat = this._projection_mat_ref;\r
+               final double CP0 = prjmat.m00,CP1 = prjmat.m01,CP2 = prjmat.m02,CP4 = prjmat.m10,CP5 = prjmat.m11,CP6 = prjmat.m12,CP8 = prjmat.m20,CP9 = prjmat.m21,CP10 = prjmat.m22;\r
+               combo03 = CP0 * trans.x + CP1 * trans.y + CP2 * trans.z + prjmat.m03;\r
+               combo13 = CP4 * trans.x + CP5 * trans.y + CP6 * trans.z + prjmat.m13;\r
+               combo23 = CP8 * trans.x + CP9 * trans.y + CP10 * trans.z + prjmat.m23;\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.__modifyMatrix_double1D;\r
+\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
+               final NyARDoublePoint3d angle = io_rot.refAngle();\r
+               a2 = angle.x;\r
+               b2 = angle.y;\r
+               c2 = angle.z;\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
+                                               rot1 = SACACBCC - SACACC + SASACB * wsin + CACA * wsin;\r
+                                               rot2 = -CASB * wcos - SASB * wsin;\r
+                                               combo00 = CP0 * rot0 + CP1 * rot1 + CP2 * rot2;\r
+                                               combo10 = CP4 * rot0 + CP5 * rot1 + CP6 * rot2;\r
+                                               combo20 = CP8 * rot0 + CP9 * rot1 + CP10 * rot2;\r
+\r
+                                               rot0 = -CACACB * wsin - SASA * wsin + SACACBCC - SACACC;\r
+                                               rot1 = -SACACBSC + SACASC + SASACB * wcos + CACA * wcos;\r
+                                               rot2 = CASB * wsin - SASB * wcos;\r
+                                               combo01 = CP0 * rot0 + CP1 * rot1 + CP2 * rot2;\r
+                                               combo11 = CP4 * rot0 + CP5 * rot1 + CP6 * rot2;\r
+                                               combo21 = CP8 * rot0 + CP9 * rot1 + CP10 * rot2;\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
+                                                       a2 = a_factor[t1];\r
+                                                       b2 = b_factor[t2];\r
+                                                       c2 = c_factor[t3];\r
+                                                       best_idx=t1+t2*3+t3*9;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+                       if (best_idx==(1+3+9)) {\r
+                               factor *= 0.5;\r
+                       }\r
+               }\r
+               io_rot.setAngle(a2, b2, c2);\r
+               /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+               return minerr /4;\r
+       }       \r
+       \r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix.java
new file mode 100644 (file)
index 0000000..204c60b
--- /dev/null
@@ -0,0 +1,158 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.rotmatrix;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARPerspectiveProjectionMatrix;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix33;\r
+/**\r
+ * 回転行列計算用の、3x3行列\r
+ *\r
+ */\r
+public class NyARRotMatrix extends NyARDoubleMatrix33\r
+{\r
+       /**\r
+        * インスタンスを準備します。\r
+        * \r
+        * @param i_param\r
+        */\r
+       public NyARRotMatrix(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException\r
+       {\r
+               this.__initRot_vec1=new NyARRotVector(i_matrix);\r
+               this.__initRot_vec2=new NyARRotVector(i_matrix);\r
+               return;\r
+       }\r
+       final private NyARRotVector __initRot_vec1;\r
+       final private NyARRotVector __initRot_vec2;\r
+       /**\r
+        * NyARTransMatResultの内容からNyARRotMatrixを復元します。\r
+        * @param i_prev_result\r
+        */\r
+       public final void initRotByPrevResult(NyARTransMatResult i_prev_result)\r
+       {\r
+\r
+               this.m00=i_prev_result.m00;\r
+               this.m01=i_prev_result.m01;\r
+               this.m02=i_prev_result.m02;\r
+\r
+               this.m10=i_prev_result.m10;\r
+               this.m11=i_prev_result.m11;\r
+               this.m12=i_prev_result.m12;\r
+\r
+               this.m20=i_prev_result.m20;\r
+               this.m21=i_prev_result.m21;\r
+               this.m22=i_prev_result.m22;\r
+               return;\r
+       }       \r
+       /**\r
+        * @param i_linear\r
+        * @param i_sqvertex\r
+        * @note\r
+        *      Cで実装するときは、配列のポインタ版関数と2重化すること\r
+        * @throws NyARException\r
+        */\r
+       public void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException\r
+       {\r
+               final NyARRotVector vec1=this.__initRot_vec1;\r
+               final NyARRotVector vec2=this.__initRot_vec2;\r
+\r
+               //向かい合った辺から、2本のベクトルを計算\r
+               \r
+               //軸1\r
+               vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);\r
+               vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);\r
+\r
+               //軸2\r
+               vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);\r
+               vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);\r
+\r
+               //回転の最適化?\r
+               NyARRotVector.checkRotation(vec1,vec2);\r
+\r
+               this.m00 =vec1.v1;\r
+               this.m10 =vec1.v2;\r
+               this.m20 =vec1.v3;\r
+               this.m01 =vec2.v1;\r
+               this.m11 =vec2.v2;\r
+               this.m21 =vec2.v3;\r
+               \r
+               //最後の軸を計算\r
+               final double w02 = vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2;\r
+               final double w12 = vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3;\r
+               final double w22 = vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1;\r
+               final double w = Math.sqrt(w02 * w02 + w12 * w12 + w22 * w22);\r
+               this.m02 = w02/w;\r
+               this.m12 = w12/w;\r
+               this.m22 = w22/w;\r
+               return;\r
+       }\r
+       public final void initRotByAngle(NyARDoublePoint3d i_angle)\r
+       {\r
+               this.setZXYAngle(i_angle);\r
+       }       \r
+       /**\r
+        * i_in_pointを変換行列で座標変換する。\r
+        * @param i_in_point\r
+        * @param i_out_point\r
+        */\r
+       public final void getPoint3d(final NyARDoublePoint3d i_in_point,final NyARDoublePoint3d i_out_point)\r
+       {\r
+               final double x=i_in_point.x;\r
+               final double y=i_in_point.y;\r
+               final double z=i_in_point.z;\r
+               i_out_point.x=this.m00 * x + this.m01 * y + this.m02 * z;\r
+               i_out_point.y=this.m10 * x + this.m11 * y + this.m12 * z;\r
+               i_out_point.z=this.m20 * x + this.m21 * y + this.m22 * z;\r
+               return;\r
+       }\r
+       /**\r
+        * 複数の頂点を一括して変換する\r
+        * @param i_in_point\r
+        * @param i_out_point\r
+        * @param i_number_of_vertex\r
+        */\r
+       public final void getPoint3dBatch(final NyARDoublePoint3d[] i_in_point,NyARDoublePoint3d[] i_out_point,int i_number_of_vertex)\r
+       {\r
+               for(int i=i_number_of_vertex-1;i>=0;i--){\r
+                       final NyARDoublePoint3d out_ptr=i_out_point[i];\r
+                       final NyARDoublePoint3d in_ptr=i_in_point[i];\r
+                       final double x=in_ptr.x;\r
+                       final double y=in_ptr.y;\r
+                       final double z=in_ptr.z;\r
+                       out_ptr.x=this.m00 * x + this.m01 * y + this.m02 * z;\r
+                       out_ptr.y=this.m10 * x + this.m11 * y + this.m12 * z;\r
+                       out_ptr.z=this.m20 * x + this.m21 * y + this.m22 * z;\r
+               }\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit.java
new file mode 100644 (file)
index 0000000..0f10622
--- /dev/null
@@ -0,0 +1,202 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.rotmatrix;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+/**\r
+ * 回転行列計算用の、3x3行列\r
+ *\r
+ */\r
+public class NyARRotMatrix_ARToolKit extends NyARRotMatrix\r
+{      \r
+       /**\r
+        * インスタンスを準備します。\r
+        * \r
+        * @param i_param\r
+        */\r
+       public NyARRotMatrix_ARToolKit(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException\r
+       {\r
+               super(i_matrix);\r
+               this._angle=new NyARDoublePoint3d();\r
+               return;\r
+       }\r
+       final protected NyARDoublePoint3d _angle;\r
+       \r
+\r
+       \r
+       public final void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException\r
+       {\r
+               super.initRotBySquare(i_linear,i_sqvertex);\r
+               //Matrixからangleをロード\r
+               this.updateAngleFromMatrix();\r
+               return;\r
+       }\r
+       public final NyARDoublePoint3d refAngle()\r
+       {\r
+               return this._angle;\r
+       }\r
+       /**\r
+        * 回転角から回転行列を計算してセットします。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_z\r
+        */\r
+       public void setAngle(final double i_x, final double i_y, final double i_z)\r
+       {\r
+               final double sina = Math.sin(i_x);\r
+               final double cosa = Math.cos(i_x);\r
+               final double sinb = Math.sin(i_y);\r
+               final double cosb = Math.cos(i_y);\r
+               final double sinc = Math.sin(i_z);\r
+               final double cosc = Math.cos(i_z);\r
+               // Optimize\r
+               final double CACA = cosa * cosa;\r
+               final double SASA = sina * sina;\r
+               final double SACA = sina * cosa;\r
+               final double SASB = sina * sinb;\r
+               final double CASB = cosa * sinb;\r
+               final double SACACB = SACA * cosb;\r
+\r
+               this.m00 = CACA * cosb * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;\r
+               this.m01 = -CACA * cosb * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;\r
+               this.m02 = CASB;\r
+               this.m10 = SACACB * cosc - SACA * cosc + SASA * cosb * sinc + CACA * sinc;\r
+               this.m11 = -SACACB * sinc + SACA * sinc + SASA * cosb * cosc + CACA * cosc;\r
+               this.m12 = SASB;\r
+               this.m20 = -CASB * cosc - SASB * sinc;\r
+               this.m21 = CASB * sinc - SASB * cosc;\r
+               this.m22 = cosb;\r
+               updateAngleFromMatrix();\r
+               return;\r
+       }\r
+       /**\r
+        * 現在のMatrixからangkeを復元する。\r
+        * @param o_angle\r
+        */\r
+       private final void updateAngleFromMatrix()\r
+       {\r
+               double a,b,c;\r
+               double sina, cosa, sinb,cosb,sinc, cosc;\r
+               \r
+               if (this.m22 > 1.0) {// <Optimize/>if( rot[2][2] > 1.0 ) {\r
+                       cosb = 1.0;// <Optimize/>rot[2][2] = 1.0;\r
+               } else if (this.m22 < -1.0) {// <Optimize/>}else if( rot[2][2] < -1.0 ) {\r
+                       cosb = -1.0;// <Optimize/>rot[2][2] = -1.0;\r
+               }else{\r
+                       cosb =this.m22;// <Optimize/>cosb = rot[2][2];\r
+               }\r
+               b = Math.acos(cosb);\r
+               sinb =Math.sin(b);\r
+               final double rot02=this.m02;\r
+               final double rot12=this.m12;\r
+               if (b >= 0.000001 || b <= -0.000001) {\r
+                       cosa = rot02 / sinb;// <Optimize/>cosa = rot[0][2] / sinb;\r
+                       sina = rot12 / sinb;// <Optimize/>sina = rot[1][2] / sinb;\r
+                       if (cosa > 1.0) {\r
+                               cosa = 1.0;\r
+                               sina = 0.0;\r
+                       }\r
+                       if (cosa < -1.0) {\r
+                               cosa = -1.0;\r
+                               sina = 0.0;\r
+                       }\r
+                       if (sina > 1.0) {\r
+                               sina = 1.0;\r
+                               cosa = 0.0;\r
+                       }\r
+                       if (sina < -1.0) {\r
+                               sina = -1.0;\r
+                               cosa = 0.0;\r
+                       }\r
+                       a = Math.acos(cosa);\r
+                       if (sina < 0) {\r
+                               a = -a;\r
+                       }\r
+                       final double tmp = (rot02 * rot02 + rot12 * rot12);\r
+                       sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;\r
+                       cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp;\r
+\r
+                       if (cosc > 1.0) {\r
+                               cosc = 1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (cosc < -1.0) {\r
+                               cosc = -1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (sinc > 1.0) {\r
+                               sinc = 1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       if (sinc < -1.0) {\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=this.m00;//cosc = rot[0];// <Optimize/>cosc = rot[0][0];\r
+                       sinc=this.m01;//sinc = rot[1];// <Optimize/>sinc = rot[1][0];\r
+                       if (cosc > 1.0) {\r
+                               cosc = 1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (cosc < -1.0) {\r
+                               cosc = -1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (sinc > 1.0) {\r
+                               sinc = 1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       if (sinc < -1.0) {\r
+                               sinc = -1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       c = Math.acos(cosc);\r
+                       if (sinc < 0) {\r
+                               c = -c;\r
+                       }\r
+               }\r
+               //angleの更新\r
+               this._angle.x = a;// wa.value=a;//*wa = a;\r
+               this._angle.y = b;// wb.value=b;//*wb = b;\r
+               this._angle.z = c;// wc.value=c;//*wc = c;\r
+               return;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit_O2.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit_O2.java
new file mode 100644 (file)
index 0000000..e015baf
--- /dev/null
@@ -0,0 +1,85 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.rotmatrix;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+/**\r
+ * 回転行列計算用の、3x3行列\r
+ * 計算方法はARToolKitと同じだが、ARToolKitにある不要な行列から角度を逆算する\r
+ * 処理を省略しているため、下位12桁目の計算値が異なる。\r
+ *\r
+ */\r
+public class NyARRotMatrix_ARToolKit_O2 extends NyARRotMatrix_ARToolKit\r
+{      \r
+       /**\r
+        * インスタンスを準備します。\r
+        * \r
+        * @param i_param\r
+        */\r
+       public NyARRotMatrix_ARToolKit_O2(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException\r
+       {\r
+               super(i_matrix);\r
+               return;\r
+       }\r
+       public final void setAngle(final double i_x, final double i_y, final double i_z)\r
+       {\r
+               final double sina = Math.sin(i_x);\r
+               final double cosa = Math.cos(i_x);\r
+               final double sinb = Math.sin(i_y);\r
+               final double cosb = Math.cos(i_y);\r
+               final double sinc = Math.sin(i_z);\r
+               final double cosc = Math.cos(i_z);\r
+               // Optimize\r
+               final double CACA = cosa * cosa;\r
+               final double SASA = sina * sina;\r
+               final double SACA = sina * cosa;\r
+               final double SASB = sina * sinb;\r
+               final double CASB = cosa * sinb;\r
+               final double SACACB = SACA * cosb;\r
+\r
+               this.m00 = CACA * cosb * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;\r
+               this.m01 = -CACA * cosb * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;\r
+               this.m02 = CASB;\r
+               this.m10 = SACACB * cosc - SACA * cosc + SASA * cosb * sinc + CACA * sinc;\r
+               this.m11 = -SACACB * sinc + SACA * sinc + SASA * cosb * cosc + CACA * cosc;\r
+               this.m12 = SASB;\r
+               this.m20 = -CASB * cosc - SASB * sinc;\r
+               this.m21 = CASB * sinc - SASB * cosc;\r
+               this.m22 = cosb;\r
+               //angleを逆計算せずに直接代入\r
+               this._angle.x=i_x;\r
+               this._angle.y=i_y;\r
+               this._angle.z=i_z;\r
+               return;\r
+       }\r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotVector.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotVector.java
new file mode 100644 (file)
index 0000000..904de3a
--- /dev/null
@@ -0,0 +1,358 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.rotmatrix;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+public class NyARRotVector\r
+{\r
+\r
+       //publicメンバ達\r
+       public double v1;\r
+\r
+       public double v2;\r
+\r
+       public double v3;\r
+\r
+       //privateメンバ達\r
+       \r
+       private NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+\r
+       private NyARDoubleMatrix44 _inv_cpara=new NyARDoubleMatrix44();\r
+\r
+       public NyARRotVector(NyARPerspectiveProjectionMatrix i_cmat) throws NyARException\r
+       {\r
+               this._inv_cpara.inverse(i_cmat);\r
+               this._projection_mat_ref = i_cmat;\r
+       }\r
+\r
+       /**\r
+        * 2直線に直交するベクトルを計算する・・・だと思う。\r
+        * @param i_linear1\r
+        * @param i_linear2\r
+        */\r
+       public void exteriorProductFromLinear(NyARLinear i_linear1, NyARLinear i_linear2)\r
+       {\r
+               //1行目\r
+               final NyARPerspectiveProjectionMatrix cmat= this._projection_mat_ref;\r
+               final double w1 = i_linear1.a * i_linear2.b - i_linear2.a * i_linear1.b;\r
+               final double w2 = i_linear1.b * i_linear2.c - i_linear2.b * i_linear1.c;\r
+               final double w3 = i_linear1.c * i_linear2.a - i_linear2.c * i_linear1.a;\r
+\r
+               final double m0 = w1 * (cmat.m01 * cmat.m12 - cmat.m02 * cmat.m11) + w2 * cmat.m11 - w3 * cmat.m01;//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
+               final double m1 = -w1 * cmat.m00 * cmat.m12 + w3 * cmat.m00;//-w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 2] + w3 * cpara[0 * 4 + 0];\r
+               final double m2 = w1 * cmat.m00 * cmat.m11;//w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 1];\r
+               final double w = Math.sqrt(m0 * m0 + m1 * m1 + m2 * m2);\r
+               this.v1 = m0 / w;\r
+               this.v2 = m1 / w;\r
+               this.v3 = m2 / w;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * static int check_dir( double dir[3], double st[2], double ed[2],double cpara[3][4] ) Optimize:STEP[526->468]\r
+        * ベクトルの開始/終了座標を指定して、ベクトルの方向を調整する。\r
+        * @param i_start_vertex\r
+        * @param i_end_vertex\r
+        * @param cpara\r
+        */\r
+       public void checkVectorByVertex(final NyARDoublePoint2d i_start_vertex, final NyARDoublePoint2d i_end_vertex) throws NyARException\r
+       {\r
+               double h;\r
+               NyARDoubleMatrix44 inv_cpara = this._inv_cpara;\r
+               //final double[] world = __checkVectorByVertex_world;// [2][3];\r
+               final double world0 = inv_cpara.m00 * i_start_vertex.x * 10.0 + inv_cpara.m01 * i_start_vertex.y * 10.0 + inv_cpara.m02 * 10.0;// mat_a->m[0]*st[0]*10.0+\r
+               final double world1 = inv_cpara.m10 * i_start_vertex.x * 10.0 + inv_cpara.m11 * i_start_vertex.y * 10.0 + inv_cpara.m12 * 10.0;// mat_a->m[3]*st[0]*10.0+\r
+               final double world2 = inv_cpara.m20 * i_start_vertex.x * 10.0 + inv_cpara.m21 * i_start_vertex.y * 10.0 + inv_cpara.m22 * 10.0;// mat_a->m[6]*st[0]*10.0+\r
+               final double world3 = world0 + this.v1;\r
+               final double world4 = world1 + this.v2;\r
+               final double world5 = world2 + this.v3;\r
+               // </Optimize>\r
+\r
+               final NyARPerspectiveProjectionMatrix cmat= this._projection_mat_ref;\r
+               h = cmat.m20 * world0 + cmat.m21 * world1 + cmat.m22 * world2;\r
+               if (h == 0.0) {\r
+                       throw new NyARException();\r
+               }\r
+               final double camera0 = (cmat.m00 * world0 + cmat.m01 * world1 + cmat.m02 * world2) / h;\r
+               final double camera1 = (cmat.m10 * world0 + cmat.m11 * world1 + cmat.m12 * world2) / h;\r
+\r
+               //h = cpara[2 * 4 + 0] * world3 + cpara[2 * 4 + 1] * world4 + cpara[2 * 4 + 2] * world5;\r
+               h = cmat.m20 * world3 + cmat.m21 * world4 + cmat.m22 * world5;\r
+               if (h == 0.0) {\r
+                       throw new NyARException();\r
+               }\r
+               final double camera2 = (cmat.m00 * world3 + cmat.m01 * world4 + cmat.m02 * world5) / h;\r
+               final double camera3 = (cmat.m10 * world3 + cmat.m11 * world4 + cmat.m12 * world5) / h;\r
+\r
+               final double v = (i_end_vertex.x - i_start_vertex.x) * (camera2 - camera0) + (i_end_vertex.y - i_start_vertex.y) * (camera3 - camera1);\r
+               if (v < 0) {\r
+                       this.v1 = -this.v1;\r
+                       this.v2 = -this.v2;\r
+                       this.v3 = -this.v3;\r
+               }\r
+       }\r
+       /**\r
+        * int check_rotation( double rot[2][3] )\r
+        * 2つのベクトル引数の調整をする?\r
+        * @param i_r\r
+        * @throws NyARException\r
+        */\r
+\r
+       public final static void checkRotation(NyARRotVector io_vec1, NyARRotVector io_vec2) throws NyARException\r
+       {\r
+               double w;\r
+               int f;\r
+\r
+               double vec10 = io_vec1.v1;\r
+               double vec11 = io_vec1.v2;\r
+               double vec12 = io_vec1.v3;\r
+               double vec20 = io_vec2.v1;\r
+               double vec21 = io_vec2.v2;\r
+               double vec22 = io_vec2.v3;\r
+               \r
+               double vec30 = vec11 * vec22 - vec12 * vec21;\r
+               double vec31 = vec12 * vec20 - vec10 * vec22;\r
+               double vec32 = vec10 * vec21 - vec11 * vec20;\r
+               w = Math.sqrt(vec30 * vec30 + vec31 * vec31 + vec32 * vec32);\r
+               if (w == 0.0) {\r
+                       throw new NyARException();\r
+               }\r
+               vec30 /= w;\r
+               vec31 /= w;\r
+               vec32 /= w;\r
+\r
+               double cb = vec10 * vec20 + vec11 * vec21 + vec12 * vec22;\r
+               if (cb < 0){\r
+                       cb=-cb;//cb *= -1.0;                    \r
+               }\r
+               final double ca = (Math.sqrt(cb + 1.0) + Math.sqrt(1.0 - cb)) * 0.5;\r
+\r
+               if (vec31 * vec10 - vec11 * vec30 != 0.0) {\r
+                       f = 0;\r
+               } else {\r
+                       if (vec32 * vec10 - vec12 * vec30 != 0.0) {\r
+                               w = vec11;vec11 = vec12;vec12 = w;\r
+                               w = vec31;vec31 = vec32;vec32 = w;\r
+                               f = 1;\r
+                       } else {\r
+                               w = vec10;vec10 = vec12;vec12 = w;\r
+                               w = vec30;vec30 = vec32;vec32 = w;\r
+                               f = 2;\r
+                       }\r
+               }\r
+               if (vec31 * vec10 - vec11 * vec30 == 0.0) {\r
+                       throw new NyARException();\r
+               }\r
+               \r
+               double 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
+               \r
+               \r
+               k1 = (vec11 * vec32 - vec31 * vec12) / (vec31 * vec10 - vec11 * vec30);\r
+               k2 = (vec31 * ca) / (vec31 * vec10 - vec11 * vec30);\r
+               k3 = (vec10 * vec32 - vec30 * vec12) / (vec30 * vec11 - vec10 * vec31);\r
+               k4 = (vec30 * ca) / (vec30 * vec11 - vec10 * vec31);\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 = vec11;vec11 = vec12;vec12 = w;\r
+                       w = vec31;vec31 = vec32;vec32 = 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 = vec10;vec10 = vec12;vec12 = w;\r
+                       w = vec30;vec30 = vec32;vec32 = w;\r
+                       f = 0;\r
+               }\r
+\r
+               if (vec31 * vec20 - vec21 * vec30 != 0.0) {\r
+                       f = 0;\r
+               } else {\r
+                       if (vec32 * vec20 - vec22 * vec30 != 0.0) {\r
+                               w = vec21;vec21 = vec22;vec22 = w;\r
+                               w = vec31;vec31 = vec32;vec32 = w;\r
+                               f = 1;\r
+                       } else {\r
+                               w = vec20;vec20 = vec22;vec22 = w;\r
+                               w = vec30;vec30 = vec32;vec32 = w;\r
+                               f = 2;\r
+                       }\r
+               }\r
+               if (vec31 * vec20 - vec21 * vec30 == 0.0) {\r
+                       throw new NyARException();\r
+               }\r
+               k1 = (vec21 * vec32 - vec31 * vec22) / (vec31 * vec20 - vec21 * vec30);\r
+               k2 = (vec31 * ca) / (vec31 * vec20 - vec21 * vec30);\r
+               k3 = (vec20 * vec32 - vec30 * vec22) / (vec30 * vec21 - vec20 * vec31);\r
+               k4 = (vec30 * ca) / (vec30 * vec21 - vec20 * vec31);\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 = vec21;vec21 = vec22;vec22 = w;\r
+                       w = vec31;vec31 = vec32;vec32 = 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 = vec20;vec20 = vec22;vec22 = w;\r
+                       w = vec30;vec30 = vec32;vec32 = w;\r
+                       f = 0;\r
+               }\r
+\r
+               double e1 = p1 * p3 + q1 * q3 + r1 * r3;\r
+               if (e1 < 0) {\r
+                       e1 = -e1;\r
+               }\r
+               double e2 = p1 * p4 + q1 * q4 + r1 * r4;\r
+               if (e2 < 0) {\r
+                       e2 = -e2;\r
+               }\r
+               double e3 = p2 * p3 + q2 * q3 + r2 * r3;\r
+               if (e3 < 0) {\r
+                       e3 = -e3;\r
+               }\r
+               double 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
+                                       io_vec1.v1 = p1;\r
+                                       io_vec1.v2 = q1;\r
+                                       io_vec1.v3 = r1;\r
+                                       io_vec2.v1 = p3;\r
+                                       io_vec2.v2 = q3;\r
+                                       io_vec2.v3 = r3;\r
+                               } else {\r
+                                       io_vec1.v1 = p2;\r
+                                       io_vec1.v2 = q2;\r
+                                       io_vec1.v3 = r2;\r
+                                       io_vec2.v1 = p4;\r
+                                       io_vec2.v2 = q4;\r
+                                       io_vec2.v3 = r4;\r
+                               }\r
+                       } else {\r
+                               if (e3 < e4) {\r
+                                       io_vec1.v1 = p2;\r
+                                       io_vec1.v2 = q2;\r
+                                       io_vec1.v3 = r2;\r
+                                       io_vec2.v1 = p3;\r
+                                       io_vec2.v2 = q3;\r
+                                       io_vec2.v3 = r3;\r
+                               } else {\r
+                                       io_vec1.v1 = p2;\r
+                                       io_vec1.v2 = q2;\r
+                                       io_vec1.v3 = r2;\r
+                                       io_vec2.v1 = p4;\r
+                                       io_vec2.v2 = q4;\r
+                                       io_vec2.v3 = r4;\r
+                               }\r
+                       }\r
+               } else {\r
+                       if (e2 < e3) {\r
+                               if (e2 < e4) {\r
+                                       io_vec1.v1 = p1;\r
+                                       io_vec1.v2 = q1;\r
+                                       io_vec1.v3 = r1;\r
+                                       io_vec2.v1 = p4;\r
+                                       io_vec2.v2 = q4;\r
+                                       io_vec2.v3 = r4;\r
+                               } else {\r
+                                       io_vec1.v1 = p2;\r
+                                       io_vec1.v2 = q2;\r
+                                       io_vec1.v3 = r2;\r
+                                       io_vec2.v1 = p4;\r
+                                       io_vec2.v2 = q4;\r
+                                       io_vec2.v3 = r4;\r
+                               }\r
+                       } else {\r
+                               if (e3 < e4) {\r
+                                       io_vec1.v1 = p2;\r
+                                       io_vec1.v2 = q2;\r
+                                       io_vec1.v3 = r2;\r
+                                       io_vec2.v1 = p3;\r
+                                       io_vec2.v2 = q3;\r
+                                       io_vec2.v3 = r3;\r
+                               } else {\r
+                                       io_vec1.v1 = p2;\r
+                                       io_vec1.v2 = q2;\r
+                                       io_vec1.v3 = r2;\r
+                                       io_vec2.v1 = p4;\r
+                                       io_vec2.v2 = q4;\r
+                                       io_vec2.v3 = r4;\r
+                               }\r
+                       }\r
+               }\r
+               return;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/solver/INyARTransportVectorSolver.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/solver/INyARTransportVectorSolver.java
new file mode 100644 (file)
index 0000000..25ad4eb
--- /dev/null
@@ -0,0 +1,56 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.solver;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+\r
+/**\r
+ * 並進ベクトル[T]を3次元座標[b]と基点の回転済行列[M]から計算するインタフェイスです。\r
+ * [M][T]=[b]\r
+ *\r
+ */\r
+public interface INyARTransportVectorSolver\r
+{\r
+       public void set2dVertex(NyARDoublePoint2d[] i_ref_vertex_2d,int i_number_of_vertex) throws NyARException;\r
+       /**\r
+        * 画面座標群と3次元座標群から、平行移動量を計算します。\r
+        * 2d座標系は、直前に実行したset2dVertexのものを使用します。\r
+        * @param i_vertex_2d\r
+        * 直前のset2dVertexコールで指定したものと同じものを指定してください。\r
+        * @param i_vertex3d\r
+        * 3次元空間の座標群を設定します。頂点の順番は、画面座標群と同じ順序で格納してください。\r
+        * @param o_transfer\r
+        * @throws NyARException\r
+        */\r
+       public void solveTransportVector(NyARDoublePoint3d[] i_vertex3d,NyARDoublePoint3d o_transfer) throws NyARException;\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/solver/NyARTransportVectorSolver.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/solver/NyARTransportVectorSolver.java
new file mode 100644 (file)
index 0000000..a18bc53
--- /dev/null
@@ -0,0 +1,161 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.solver;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARPerspectiveProjectionMatrix;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 並進ベクトル[T]を3次元座標[b]と基点の回転済行列[M]から計算します。\r
+ * \r
+ * アルゴリズムは、ARToolKit 拡張現実プログラミング入門 の、P207のものです。\r
+ * \r
+ * 計算手順\r
+ * [A]*[T]=bを、[A]T*[A]*[T]=[A]T*[b]にする。\r
+ * set2dVertexで[A]T*[A]=[M]を計算して、Aの3列目の情報だけ保存しておく。\r
+ * getTransportVectorで[M]*[T]=[A]T*[b]を連立方程式で解いて、[T]を得る。\r
+ */\r
+public class NyARTransportVectorSolver implements INyARTransportVectorSolver\r
+{\r
+       private double[] _cx;\r
+       private double[] _cy;   \r
+       private final NyARPerspectiveProjectionMatrix _projection_mat;\r
+       private int _nmber_of_vertex;\r
+       public NyARTransportVectorSolver(NyARPerspectiveProjectionMatrix i_projection_mat_ref,int i_max_vertex)\r
+       {\r
+               this._projection_mat=i_projection_mat_ref;\r
+               this._cx=new double[i_max_vertex];\r
+               this._cy=new double[i_max_vertex];      \r
+               return;\r
+       }\r
+       private double _a00,_a01_10,_a02_20,_a11,_a12_21,_a22;\r
+       /**\r
+        * 平行移動量計算のための、画面上の頂点群を指定します。\r
+        * @param i_ref_vertex_2d\r
+        * 入力パラメータ。歪み矯正済の画面上の頂点座標群への参照値を指定します。\r
+        * @param i_number_of_vertex\r
+        * i_ref_vertex_2dのデータ数を指定します。\r
+        * @throws NyARException\r
+        * \r
+        */\r
+       public void set2dVertex(NyARDoublePoint2d[] i_ref_vertex_2d,int i_number_of_vertex) throws NyARException\r
+       {\r
+               //3x2nと2n*3の行列から、最小二乗法計算するために3x3マトリクスを作る。               \r
+               //行列[A]の3列目のキャッシュ\r
+               final double[] cx=this._cx;\r
+               final double[] cy=this._cy;\r
+               \r
+               double m22;\r
+               double p00=this._projection_mat.m00;\r
+               double p01=this._projection_mat.m01;\r
+               double p11=this._projection_mat.m11;\r
+               double p12=this._projection_mat.m12;\r
+               double p02=this._projection_mat.m02;\r
+               double w1,w2,w3,w4;\r
+               \r
+               this._a00=i_number_of_vertex*p00*p00;\r
+               this._a01_10=i_number_of_vertex*p00*p01;\r
+               this._a11=i_number_of_vertex*(p01*p01+p11*p11);\r
+               \r
+               //[A]T*[A]の計算\r
+               m22=0;\r
+               w1=w2=0;\r
+               for(int i=0;i<i_number_of_vertex;i++){\r
+                       //座標を保存しておく。\r
+                       w3=p02-(cx[i]=i_ref_vertex_2d[i].x);\r
+                       w4=p12-(cy[i]=i_ref_vertex_2d[i].y);\r
+                       w1+=w3;\r
+                       w2+=w4;\r
+                       m22+=w3*w3+w4*w4;\r
+               }\r
+               this._a02_20=w1*p00;\r
+               this._a12_21=p01*w1+p11*w2;\r
+               this._a22=m22;\r
+\r
+               this._nmber_of_vertex=i_number_of_vertex;\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * 先にセットした2次元座標群と3次元座標群から、平行移動量を計算します。\r
+        * 2d座標系は、直前に実行したset2dVertexのものを使用します。\r
+        * @param i_vertex3d\r
+        * 3次元空間の座標群を設定します。頂点の順番は、画面座標群と同じ順序で格納してください。\r
+        * @param o_transfer\r
+        * @throws NyARException\r
+        */\r
+       public void solveTransportVector(NyARDoublePoint3d[] i_vertex3d,NyARDoublePoint3d o_transfer) throws NyARException\r
+       {\r
+               final int number_of_vertex=this._nmber_of_vertex;\r
+               final double p00=this._projection_mat.m00;\r
+               final double p01=this._projection_mat.m01;\r
+               final double p02=this._projection_mat.m02;\r
+               final double p11=this._projection_mat.m11;\r
+               final double p12=this._projection_mat.m12;\r
+               //行列[A]の3列目のキャッシュ\r
+               final double[] cx=this._cx;\r
+               final double[] cy=this._cy;                     \r
+               \r
+               //回転行列を元座標の頂点群に適応\r
+               //[A]T*[b]を計算\r
+               double b1=0,b2=0,b3=0;\r
+               for(int i=0;i<number_of_vertex;i++)\r
+               {\r
+                       double w1=i_vertex3d[i].z*cx[i]-p00*i_vertex3d[i].x-p01*i_vertex3d[i].y-p02*i_vertex3d[i].z;\r
+                       double w2=i_vertex3d[i].z*cy[i]-p11*i_vertex3d[i].y-p12*i_vertex3d[i].z;\r
+                       b1+=w1;\r
+                       b2+=w2;\r
+                       b3+=cx[i]*w1+cy[i]*w2;\r
+               }\r
+               //[A]T*[b]を計算\r
+               b3=p02*b1+p12*b2-b3;//順番変えたらダメよ\r
+               b2=p01*b1+p11*b2;\r
+               b1=p00*b1;\r
+               //([A]T*[A])*[T]=[A]T*[b]を方程式で解く。\r
+               //a01とa10を0と仮定しても良いんじゃないかな?\r
+               double a00=this._a00;\r
+               double a01=this._a01_10;\r
+               double a02=this._a02_20;\r
+               double a11=this._a11;\r
+               double a12=this._a12_21;\r
+               double a22=this._a22;\r
+               \r
+               double t1=a22*b2-a12*b3;\r
+               double t2=a12*b2-a11*b3;\r
+               double t3=a01*b3-a02*b2;\r
+               double t4=a12*a12-a11*a22;\r
+               double t5=a02*a12-a01*a22;\r
+               double t6=a02*a11-a01*a12;\r
+               double det=a00*t4-a01*t5 + a02*t6;\r
+               o_transfer.x= (a01*t1 - a02*t2 +b1*t4)/det;\r
+               o_transfer.y=-(a00*t1 + a02*t3 +b1*t5)/det;\r
+               o_transfer.z= (a00*t2 + a01*t3 +b1*t6)/det;\r
+               \r
+       \r
+               return;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/transmat/solver/NyARTransportVectorSolver_ARToolKit.java b/lib/src/jp/nyatla/nyartoolkit/core/transmat/solver/NyARTransportVectorSolver_ARToolKit.java
new file mode 100644 (file)
index 0000000..d054d98
--- /dev/null
@@ -0,0 +1,133 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.solver;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.param.NyARPerspectiveProjectionMatrix;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+\r
+/**\r
+ * 並進ベクトル[T]を3次元座標[b]と基点の回転済行列[M]から計算します。\r
+ * ARToolKit互換の数値を計算します。\r
+ *\r
+ */\r
+public class NyARTransportVectorSolver_ARToolKit implements INyARTransportVectorSolver\r
+{\r
+       private final NyARMat _mat_at = new NyARMat(3,8);//3,NUMBER_OF_VERTEX*2\r
+       private final NyARMat _mat_a =  new NyARMat(8,3);//NUMBER_OF_VERTEX,3\r
+       private final NyARMat _mat_t =  new NyARMat(3,3);//NUMBER_OF_VERTEX,3\r
+       private final NyARMat _mat_c =  new NyARMat(8,1);//NUMBER_OF_VERTEX * 2, 1\r
+       private final NyARMat _mat_e =  new NyARMat(3,1);\r
+       private final NyARMat _mat_f =  new NyARMat(3,1);\r
+       private double[] _cx=new double[4];\r
+       private double[] _cy=new double[4];\r
+       \r
+       private final NyARPerspectiveProjectionMatrix _projection_mat;\r
+       public NyARTransportVectorSolver_ARToolKit(final NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+       {\r
+               this._projection_mat=i_projection_mat_ref;\r
+               //aとb(aの転置行列)の固定部分を設定。\r
+               final double[][] mata = this._mat_a.getArray();\r
+               final double[][] matat = this._mat_at.getArray();\r
+\r
+               //変換用行列のcpara部分を先に作成\r
+               for (int i = 0; i < 4; i++) {\r
+                       final int x2 = i * 2;\r
+                       mata[x2][0] = matat[0][x2] = i_projection_mat_ref.m00;// mat_a->m[j*6+0]=mat_b->m[num*0+j*2] =cpara[0][0];\r
+                       mata[x2][1] = matat[1][x2] = i_projection_mat_ref.m01;// mat_a->m[j*6+1]=mat_b->m[num*2+j*2]=cpara[0][1];\r
+                       mata[x2 + 1][0] = matat[0][x2 + 1] = 0.0;// mat_a->m[j*6+3] =mat_b->m[num*0+j*2+1]= 0.0;\r
+                       mata[x2 + 1][1] = matat[1][x2 + 1] = i_projection_mat_ref.m11;// mat_a->m[j*6+4] =mat_b->m[num*2+j*2+1]= cpara[1][1];\r
+               }\r
+               return;\r
+       }\r
+       public void set2dVertex(NyARDoublePoint2d[] i_ref_vertex_2d,int i_number_of_vertex) throws NyARException\r
+       {               \r
+               assert(i_number_of_vertex==4);\r
+               final double[] cx=this._cx;\r
+               final double[] cy=this._cy;\r
+               final double cpara02=this._projection_mat.m02;\r
+               final double cpara12=this._projection_mat.m12;          \r
+               final NyARMat mat_t=this._mat_t;\r
+               final double[][] mata = this._mat_a.getArray();\r
+               final double[][] matat= this._mat_at.getArray();\r
+               for (int i = 0; i < 4; i++){\r
+                       cx[i]=i_ref_vertex_2d[i].x;\r
+                       cy[i]=i_ref_vertex_2d[i].y;\r
+                       final int x2 = i * 2;   \r
+                       mata[x2][2] = matat[2][x2] = cpara02 - i_ref_vertex_2d[i].x;// mat_a->m[j*6+2]=mat_b->m[num*4+j*2]=cpara[0][2]-pos2d[j][0];\r
+                       mata[x2 + 1][2] = matat[2][x2 + 1] = cpara12 - i_ref_vertex_2d[i].y;// mat_a->m[j*6+5]=mat_b->m[num*4+j*2+1]=cpara[1][2]-pos2d[j][1];\r
+               }\r
+               //T(3x3行列)の作成\r
+               mat_t.matrixMul(this._mat_at, this._mat_a);\r
+               mat_t.matrixSelfInv();          \r
+               return;         \r
+       }\r
+       /**\r
+        * 画面座標群と3次元座標群から、平行移動量を計算します。\r
+        * 2d座標系は、直前に実行したset2dVertexのものを使用します。\r
+        * @param i_vertex_2d\r
+        * 直前のset2dVertexコールで指定したものと同じものを指定してください。\r
+        * @param i_vertex3d\r
+        * 3次元空間の座標群を設定します。頂点の順番は、画面座標群と同じ順序で格納してください。\r
+        * @param o_transfer\r
+        * @throws NyARException\r
+        */\r
+       public void solveTransportVector(NyARDoublePoint3d[] i_vertex3d,NyARDoublePoint3d o_transfer) throws NyARException\r
+       {\r
+               final double[][] matc = this._mat_c.getArray();\r
+               final double cpara00=this._projection_mat.m00;\r
+               final double cpara01=this._projection_mat.m01;\r
+               final double cpara02=this._projection_mat.m02;\r
+               final double cpara11=this._projection_mat.m11;\r
+               final double cpara12=this._projection_mat.m12;\r
+               final double[] cx=this._cx;\r
+               final double[] cy=this._cy;\r
+               \r
+               //(3D座標?)を一括請求\r
+               for (int i = 0; i < 4; i++) {\r
+                       final int x2 = i+i;\r
+                       final NyARDoublePoint3d point3d_ptr=i_vertex3d[i];\r
+                       //透視変換?\r
+                       matc[x2][0] = point3d_ptr.z * cx[i] - cpara00 * point3d_ptr.x - cpara01 * point3d_ptr.y - cpara02 * point3d_ptr.z;// mat_c->m[j*2+0] = wz*pos2d[j][0]-cpara[0][0]*wx-cpara[0][1]*wy-cpara[0][2]*wz;\r
+                       matc[x2 + 1][0] = point3d_ptr.z * cy[i] - cpara11 * point3d_ptr.y - cpara12 * point3d_ptr.z;// mat_c->m[j*2+1]= wz*pos2d[j][1]-cpara[1][1]*wy-cpara[1][2]*wz;\r
+               }\r
+               this._mat_e.matrixMul(this._mat_at,this._mat_c);\r
+               this._mat_f.matrixMul(this._mat_t, this._mat_e);\r
+               \r
+               final double[][] matf = this._mat_f.getArray();\r
+               o_transfer.x= matf[0][0];// trans[0] = mat_f->m[0];\r
+               o_transfer.y= matf[1][0];\r
+               o_transfer.z= matf[2][0];// trans[2] = mat_f->m[2];\r
+               return;         \r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARBufferType.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARBufferType.java
new file mode 100644 (file)
index 0000000..e013f8e
--- /dev/null
@@ -0,0 +1,144 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2010 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+public class NyARBufferType\r
+{\r
+       private static final int T_BYTE1D =0x00010000;\r
+       private static final int T_INT2D  =0x00020000;\r
+       private static final int T_SHORT1D=0x00030000;\r
+       private static final int T_INT1D  =0x00040000;\r
+       private static final int T_OBJECT =0x00100000;\r
+       private static final int T_USER   =0x00FF0000;\r
+       //  24-31(8)予約\r
+       //  16-27(8)型ID\r
+       //      00:無効/01:byte[]/02:int[][]/03:short[]\r
+       //  08-15(8)ビットフォーマットID\r
+       //      00:24bit/01:32bit/02:16bit\r
+       //  00-07(8)型番号\r
+       //\r
+       /**\r
+        * RGB24フォーマットで、全ての画素が0\r
+        */\r
+       public static final int NULL_ALLZERO = 0x00000001;\r
+       /**\r
+        * USER - USER+0xFFFFはユーザー定義型。実験用に。\r
+        */\r
+       public static final int USER_DEFINE  = T_USER;\r
+\r
+       /**\r
+        * byte[]で、R8G8B8の24ビットで画素が格納されている。\r
+        */\r
+       public static final int BYTE1D_R8G8B8_24   = T_BYTE1D|0x0001;\r
+       /**\r
+        * byte[]で、B8G8R8の24ビットで画素が格納されている。\r
+        */\r
+       public static final int BYTE1D_B8G8R8_24   = T_BYTE1D|0x0002;\r
+       /**\r
+        * byte[]で、R8G8B8X8の32ビットで画素が格納されている。\r
+        */\r
+       public static final int BYTE1D_B8G8R8X8_32 = T_BYTE1D|0x0101;\r
+       /**\r
+        * byte[]で、X8R8G8B8の32ビットで画素が格納されている。\r
+        */\r
+       public static final int BYTE1D_X8R8G8B8_32 = T_BYTE1D|0x0102;\r
+\r
+       /**\r
+        * byte[]で、RGB565の16ビット(little/big endian)で画素が格納されている。\r
+        */\r
+       public static final int BYTE1D_R5G6B5_16LE = T_BYTE1D|0x0201;\r
+    public static final int BYTE1D_R5G6B5_16BE = T_BYTE1D|0x0202;\r
+       /**\r
+        * short[]で、RGB565の16ビット(little/big endian)で画素が格納されている。\r
+        */     \r
+    public static final int WORD1D_R5G6B5_16LE = T_SHORT1D|0x0201;\r
+    public static final int WORD1D_R5G6B5_16BE = T_SHORT1D|0x0202;\r
+\r
+       \r
+       /**\r
+        * int[][]で特に値範囲を定めない\r
+        */\r
+       public static final int INT2D        = T_INT2D|0x0000;\r
+       /**\r
+        * int[][]で0-255のグレイスケール画像\r
+        */\r
+       public static final int INT2D_GRAY_8 = T_INT2D|0x0001;\r
+       /**\r
+        * int[][]で0/1の2値画像\r
+        * これは、階調値1bitのBUFFERFORMAT_INT2D_GRAY_1と同じです。\r
+        */\r
+       public static final int INT2D_BIN_8  = T_INT2D|0x0002;\r
+\r
+       /**\r
+        * int[]で特に値範囲を定めない\r
+        */\r
+       public static final int INT1D        = T_INT1D|0x0000;\r
+       /**\r
+        * int[]で0-255のグレイスケール画像\r
+        */\r
+       public static final int INT1D_GRAY_8 = T_INT1D|0x0001;\r
+       /**\r
+        * int[]で0/1の2値画像\r
+        * これは、階調1bitのINT1D_GRAY_1と同じです。\r
+        */\r
+       public static final int INT1D_BIN_8  = T_INT1D|0x0002;\r
+       \r
+       \r
+       /**\r
+        * int[]で、XRGB32の32ビットで画素が格納されている。\r
+        */     \r
+    public static final int INT1D_X8R8G8B8_32=T_INT1D|0x0102;\r
+\r
+       /**\r
+        * H:9bit(0-359),S:8bit(0-255),V(0-255)\r
+        */\r
+       public static final int INT1D_X7H9S8V8_32=T_INT1D|0x0103;\r
+    \r
+\r
+    /**\r
+     * プラットフォーム固有オブジェクト\r
+     */\r
+       public static final int OBJECT_Java= T_OBJECT|0x0100;\r
+       public static final int OBJECT_CS  = T_OBJECT|0x0200;\r
+       public static final int OBJECT_AS3 = T_OBJECT|0x0300;\r
+       \r
+       /**\r
+        * JavaのBufferedImageを格納するラスタ\r
+        */\r
+       public static final int OBJECT_Java_BufferedImage= OBJECT_Java|0x01;\r
+       \r
+       \r
+       /**\r
+        * ActionScript3のBitmapDataを格納するラスタ\r
+        */\r
+       public static final int OBJECT_AS3_BitmapData= OBJECT_AS3|0x01;\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARDoublePoint2d.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARDoublePoint2d.java
new file mode 100644 (file)
index 0000000..f8acf69
--- /dev/null
@@ -0,0 +1,218 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+\r
+\r
+/**\r
+ * データ型です。\r
+ * 2次元の浮動小数点方の点を格納します。\r
+ */\r
+public class NyARDoublePoint2d\r
+{\r
+       public double x;\r
+       public double y;\r
+       /**\r
+        * 配列ファクトリ\r
+        * @param i_number\r
+        * @return\r
+        */\r
+       public static NyARDoublePoint2d[] createArray(int i_number)\r
+       {\r
+               NyARDoublePoint2d[] ret=new NyARDoublePoint2d[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARDoublePoint2d();\r
+               }\r
+               return ret;\r
+       }\r
+       public static NyARDoublePoint2d[][] create2dArray(int i_length_x,int i_length_y)\r
+       {\r
+               NyARDoublePoint2d[][] ret=new NyARDoublePoint2d[i_length_y][i_length_x];\r
+               for(int i=0;i<i_length_y;i++)\r
+               {\r
+                       for(int i2=0;i2<i_length_x;i2++)\r
+                       {\r
+                               ret[i][i2]=new NyARDoublePoint2d();\r
+                       }\r
+               }\r
+               return ret;\r
+       }\r
+       /**\r
+        * p1->p2と、p2->p3の直線の外積を計算します。\r
+        * @param p1\r
+        * @param p2\r
+        * @param p3\r
+        * @return\r
+        */\r
+       public final static double crossProduct3Point(NyARDoublePoint2d p1,NyARDoublePoint2d p2,NyARDoublePoint2d p3)\r
+       {\r
+               return (p2.x-p1.x)*(p3.y-p2.y)-(p2.y-p1.y)*(p3.x-p2.x);\r
+       }\r
+       /**\r
+        * p1->p2と、p2->p3の直線の外積を計算します。\r
+        * @param p1\r
+        * @param p2\r
+        * @param p3\r
+        * @return\r
+        */\r
+       public final static double crossProduct3Point(NyARDoublePoint2d p1,NyARDoublePoint2d p2,double p3_x,double p3_y)\r
+       {\r
+               return (p2.x-p1.x)*(p3_y-p2.y)-(p2.y-p1.y)*(p3_x-p2.x);\r
+       }\r
+\r
+       \r
+       \r
+       /**\r
+        * 頂点配列の中央値を求めます。\r
+        * @param i_points\r
+        * @param i_number_of_data\r
+        * 配列中の有効な頂点数です。\r
+        * @param o_out\r
+        */\r
+       public final static void makeCenter(NyARDoublePoint2d[] i_points,int i_number_of_data,NyARDoublePoint2d o_out)\r
+       {\r
+               double x,y;\r
+               x=y=0;\r
+               for(int i=i_number_of_data-1;i>=0;i--)\r
+               {\r
+                       x+=i_points[i].x;\r
+                       y+=i_points[i].y;\r
+               }\r
+               o_out.x=x/i_number_of_data;\r
+               o_out.x=y/i_number_of_data;\r
+       }\r
+       /**\r
+        * {@link #makeCenter}の出力型違いの関数です。\r
+        * @param i_points\r
+        * @param i_number_of_data\r
+        * @param o_out\r
+        */\r
+       public final static void makeCenter(NyARDoublePoint2d[] i_points,int i_number_of_data,NyARIntPoint2d o_out)\r
+       {\r
+               double lx,ly;\r
+               lx=ly=0;\r
+               for(int i=i_number_of_data-1;i>=0;i--)\r
+               {\r
+                       lx+=i_points[i].x;\r
+                       ly+=i_points[i].y;\r
+               }\r
+               o_out.x=(int)(lx/i_number_of_data);\r
+               o_out.y=(int)(ly/i_number_of_data);\r
+       }\r
+       \r
+       /**\r
+        * コンストラクタです。\r
+        */\r
+       public NyARDoublePoint2d()\r
+       {\r
+               this.x=0;\r
+               this.y=0;\r
+               return;\r
+       }\r
+       /**\r
+        * i_srcの値をthisへセットします。\r
+        * @param i_src\r
+        */\r
+       public NyARDoublePoint2d(double i_x,double i_y)\r
+       {\r
+               this.x=i_x;\r
+               this.y=i_y;\r
+               return;\r
+       }\r
+       /**\r
+        * i_srcの値をthisへセットします。\r
+        * @param i_src\r
+        */\r
+       public NyARDoublePoint2d(NyARDoublePoint2d i_src)\r
+       {\r
+               this.x=i_src.x;\r
+               this.y=i_src.y;\r
+               return;\r
+       }\r
+       /**\r
+        * i_srcの値をthisへセットします。\r
+        * @param i_src\r
+        */\r
+       public NyARDoublePoint2d(NyARIntPoint2d i_src)\r
+       {\r
+               this.x=(double)i_src.x;\r
+               this.y=(double)i_src.y;\r
+               return;\r
+       }\r
+       /**\r
+        * p2-p1間の距離の二乗値を計算します。\r
+        * @param i_p1\r
+        * @param i_p2\r
+        * @return\r
+        */     \r
+       public final double sqDist(NyARDoublePoint2d i_p1)\r
+       {\r
+               double x,y;\r
+               x=this.x-i_p1.x;\r
+               y=this.y-i_p1.y;\r
+               return x*x+y*y;\r
+       }\r
+       public final double sqDist(NyARIntPoint2d i_p1)\r
+       {\r
+               double x,y;\r
+               x=this.x-i_p1.x;\r
+               y=this.y-i_p1.y;\r
+               return x*x+y*y;\r
+       }       \r
+       /**\r
+        * i_srcの値をthisへセットします。\r
+        * @param i_src\r
+        */\r
+       public final void setValue(NyARDoublePoint2d i_src)\r
+       {\r
+               this.x=i_src.x;\r
+               this.y=i_src.y;\r
+               return;\r
+       }\r
+       /**\r
+        * i_srcの値をthisへセットします。\r
+        * @param i_src\r
+        */\r
+       public final void setValue(NyARIntPoint2d i_src)\r
+       {\r
+               this.x=(double)i_src.x;\r
+               this.y=(double)i_src.y;\r
+               return;\r
+       }\r
+       public final void setValue(double x,double y)\r
+       {\r
+               this.x=x;\r
+               this.y=y;\r
+               return;\r
+       }\r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARDoublePoint3d.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARDoublePoint3d.java
new file mode 100644 (file)
index 0000000..d1d7e4a
--- /dev/null
@@ -0,0 +1,72 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+public class NyARDoublePoint3d\r
+{\r
+       public double x;\r
+       public double y;\r
+       public double z;\r
+       /**\r
+        * 配列ファクトリ\r
+        * @param i_number\r
+        * @return\r
+        */\r
+       public static NyARDoublePoint3d[] createArray(int i_number)\r
+       {\r
+               NyARDoublePoint3d[] ret=new NyARDoublePoint3d[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARDoublePoint3d();\r
+               }\r
+               return ret;\r
+       }\r
+       public final void setValue(NyARDoublePoint3d i_in)\r
+       {\r
+               this.x=i_in.x;\r
+               this.y=i_in.y;\r
+               this.z=i_in.z;\r
+               return;\r
+       }\r
+       /**\r
+        * p2-p1間の距離の二乗値を計算します。\r
+        * @param i_p1\r
+        * @return\r
+        */     \r
+       public final double sqDist(NyARDoublePoint3d i_p1)\r
+       {\r
+               double x,y,z;\r
+               x=this.x-i_p1.x;\r
+               y=this.y-i_p1.y;\r
+               z=this.z-i_p1.z;\r
+               return x*x+y*y+z*z;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARHistogram.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARHistogram.java
new file mode 100644 (file)
index 0000000..6d0293a
--- /dev/null
@@ -0,0 +1,140 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2010 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+/**\r
+ * ヒストグラムを格納するクラスです。\r
+ */\r
+public class NyARHistogram\r
+{\r
+       /**\r
+        * サンプリング値の格納変数\r
+        */\r
+       public final int[] data;\r
+       /**\r
+        * 有効なサンプリング値の範囲。[0-data.length-1]\r
+        */\r
+       public int length;\r
+       /**\r
+        * 有効なサンプルの総数 data[i]\r
+        */\r
+       public int total_of_data;\r
+       \r
+       \r
+       \r
+       public NyARHistogram(int i_length)\r
+       {\r
+               this.data=new int[i_length];\r
+               this.length=i_length;\r
+               this.total_of_data=0;\r
+       }\r
+       /**\r
+        * 区間i_stからi_edまでの総データ数を返します。\r
+        * @param i_st\r
+        * @param i_ed\r
+        * @return\r
+        */\r
+       public final int getTotal(int i_st,int i_ed)\r
+       {\r
+               assert(i_st<i_ed && i_ed<this.length);\r
+               int result=0;\r
+               int[] s=this.data;\r
+               for(int i=i_st;i<=i_ed;i++){\r
+                       result+=s[i];\r
+               }\r
+               return result;\r
+       }\r
+       /**\r
+        * 指定したi_pos未満サンプルを0にします。\r
+        * @param i_pos\r
+        */\r
+       public void lowCut(int i_pos)\r
+       {\r
+               int s=0;\r
+               for(int i=0;i<i_pos;i++){\r
+                       s+=this.data[i];\r
+                       this.data[i]=0;\r
+               }\r
+               this.total_of_data-=s;\r
+       }\r
+       /**\r
+        * 指定したi_pos以上のサンプルを0にします。\r
+        * @param i_pos\r
+        */\r
+       public void highCut(int i_pos)\r
+       {\r
+               int s=0;\r
+               for(int i=this.length-1;i>=i_pos;i--){\r
+                       s+=this.data[i];\r
+                       this.data[i]=0;\r
+               }\r
+               this.total_of_data-=s;\r
+       }\r
+       /**\r
+        * 最小の値が格納されているサンプル番号を返します。\r
+        */\r
+       public int getMinSample()\r
+       {\r
+               int[] data=this.data;\r
+               int ret=this.length-1;\r
+               int min=data[ret];\r
+               for(int i=this.length-2;i>=0;i--)\r
+               {\r
+                       if(data[i]<min){\r
+                               min=data[i];\r
+                               ret=i;\r
+                       }\r
+               }\r
+               return ret;\r
+       }\r
+       /**\r
+        * サンプルの中で最小の値を返します。\r
+        * @return\r
+        */\r
+       public int getMinData()\r
+       {\r
+               return this.data[this.getMinSample()];\r
+       }\r
+       /**\r
+        * 平均値を計算します。\r
+        * @return\r
+        */\r
+       public int getAverage()\r
+       {\r
+               long sum=0;\r
+               for(int i=this.length-1;i>=0;i--)\r
+               {\r
+                       sum+=this.data[i]*i;\r
+               }\r
+               return (int)(sum/this.total_of_data);\r
+       }\r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntCoordinates.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntCoordinates.java
new file mode 100644 (file)
index 0000000..6450599
--- /dev/null
@@ -0,0 +1,111 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2010 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+/**\r
+ * 座標点配列を定義します。\r
+ * 座標点配列は、輪郭線やパスの定義に使用します。\r
+ */\r
+public class NyARIntCoordinates\r
+{\r
+       /**\r
+        * 点を格納する配列です。\r
+        */\r
+       public NyARIntPoint2d[] items;\r
+       /**\r
+        * 配列の有効な長さです。0から、items.length-1までの数を取ります。\r
+        */\r
+       public int length;\r
+       public NyARIntCoordinates(int i_length)\r
+       {\r
+               this.items=NyARIntPoint2d.createArray(i_length);\r
+               this.length=0;\r
+       }\r
+       /**\r
+        * 指定した点を結ぶ直線を計算して、輪郭に保存します。\r
+        * 動作チェックはしたけど、多分動くレベル。\r
+        * @param i_x0\r
+        * @param i_y0\r
+        * @param i_x1\r
+        * @param i_y1\r
+        * @param o_coord\r
+        * @return\r
+        * 成功するとtrueを返します。\r
+        */\r
+       public boolean setLineCoordinates(int i_x0, int i_y0, int i_x1, int i_y1)\r
+       {\r
+               NyARIntPoint2d[] ptr=this.items;\r
+               // 線分を定義\r
+               int dx = (i_x1 > i_x0) ? i_x1 - i_x0 : i_x0 - i_x1;\r
+               int dy = (i_y1 > i_y0) ? i_y1 - i_y0 : i_y0 - i_y1;\r
+               int sx = (i_x1 > i_x0) ? 1 : -1;\r
+               int sy = (i_y1 > i_y0) ? 1 : -1;\r
+\r
+               // Bresenham\r
+               int idx = 0;\r
+               if (dx >= dy) {\r
+                       // 傾きが1以下の場合\r
+                       if (dx >= ptr.length) {\r
+                               return false;\r
+                       }\r
+                       int E = -dx;\r
+                       for (int i = 0; i <= dx; i++) {\r
+                               ptr[idx].x = i_x0;\r
+                               ptr[idx].y = i_y0;\r
+                               idx++;\r
+                               i_x0 += sx;\r
+                               E += 2 * dy;\r
+                               if (E >= 0) {\r
+                                       i_y0 += sy;\r
+                                       E -= 2 * dx;\r
+                               }\r
+                       }\r
+               } else {\r
+                       // 傾きが1より大きい場合\r
+                       if (dy >= this.items.length) {\r
+                               return false;\r
+                       }\r
+                       int E = -dy;\r
+                       for (int i = 0; i <= dy; i++) {\r
+                               ptr[idx].x = i_x0;\r
+                               ptr[idx].y = i_y0;\r
+                               idx++;\r
+                               i_y0 += sy;\r
+                               E += 2 * dx;\r
+                               if (E >= 0) {\r
+                                       i_x0 += sx;\r
+                                       E -= 2 * dy;\r
+                               }\r
+                       }\r
+               }\r
+               this.length=idx;\r
+               return true;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint2d.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint2d.java
new file mode 100644 (file)
index 0000000..0edd449
--- /dev/null
@@ -0,0 +1,118 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+/**\r
+ * int型の二次元の点を格納します。\r
+ *\r
+ */\r
+public class NyARIntPoint2d\r
+{\r
+       public int x;\r
+\r
+       public int y;\r
+       /**\r
+        * 配列ファクトリ\r
+        * @param i_number\r
+        * @return\r
+        */\r
+       public static NyARIntPoint2d[] createArray(int i_number)\r
+       {\r
+               NyARIntPoint2d[] ret=new NyARIntPoint2d[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARIntPoint2d();\r
+               }\r
+               return ret;\r
+       }\r
+       /**\r
+        * i_fromからi_toへ配列をコピーします。\r
+        * @param i_from\r
+        * @param i_to\r
+        */\r
+       public static void copyArray(final NyARIntPoint2d[] i_from,NyARIntPoint2d[] i_to)\r
+       {\r
+               for(int i=i_from.length-1;i>=0;i--)\r
+               {\r
+                       i_to[i].x=i_from[i].x;\r
+                       i_to[i].y=i_from[i].y;\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * p2-p1間の距離の二乗値を計算します。\r
+        * @param i_p1\r
+        * @param i_p2\r
+        * @return\r
+        */     \r
+       public final int sqDist(NyARIntPoint2d i_p1)\r
+       {\r
+               int x=this.x-i_p1.x;\r
+               int y=this.y-i_p1.y;\r
+               return x*x+y*y;\r
+       }\r
+       \r
+       /**\r
+        * 中心位置を計算して設定する。\r
+        * @param i_point\r
+        * @param i_number_of_vertex\r
+        */\r
+       public final void setCenterPos(NyARIntPoint2d[] i_point,int i_number_of_vertex)\r
+       {\r
+               int cx,cy;\r
+               cx=cy=0;\r
+               for(int i=i_number_of_vertex-1;i>=0;i--){\r
+                       cx+=i_point[i].x;\r
+                       cy+=i_point[i].y;\r
+               }\r
+               this.x=cx/i_number_of_vertex;\r
+               this.y=cy/i_number_of_vertex;\r
+       }\r
+       /**\r
+        * i_sourceの値を、thisへセットします。\r
+        * @param i_source\r
+        */\r
+       public final void setValue(NyARIntPoint2d i_source)\r
+       {\r
+               this.x=i_source.x;\r
+               this.y=i_source.y;\r
+       }\r
+       public final void setValue(NyARDoublePoint2d i_source)\r
+       {\r
+               this.x=(int)i_source.x;\r
+               this.y=(int)i_source.y;\r
+       }\r
+       public final void setValue(int i_x,int i_y)\r
+       {\r
+               this.x=i_x;\r
+               this.y=i_y;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntRect.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntRect.java
new file mode 100644 (file)
index 0000000..720b433
--- /dev/null
@@ -0,0 +1,231 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+/**\r
+ * 基点x,yと、幅、高さで矩形を定義します。\r
+ *\r
+ */\r
+public class NyARIntRect\r
+{\r
+       public int x;\r
+\r
+       public int y;\r
+\r
+       public int w;\r
+\r
+       public int h;\r
+       /**\r
+        * 頂点を包括するRECTを計算します。\r
+        * @param i_vertex\r
+        * @param i_num_of_vertex\r
+        * @param o_rect\r
+        */\r
+       public final void setAreaRect(NyARDoublePoint2d[] i_vertex,int i_num_of_vertex)\r
+       {\r
+               //エリアを求める。\r
+               int xmax,xmin,ymax,ymin;\r
+               xmin=xmax=(int)i_vertex[i_num_of_vertex-1].x;\r
+               ymin=ymax=(int)i_vertex[i_num_of_vertex-1].y;\r
+               for(int i=i_num_of_vertex-2;i>=0;i--){\r
+                       if(i_vertex[i].x<xmin){\r
+                               xmin=(int)i_vertex[i].x;\r
+                       }else if(i_vertex[i].x>xmax){\r
+                               xmax=(int)i_vertex[i].x;\r
+                       }\r
+                       if(i_vertex[i].y<ymin){\r
+                               ymin=(int)i_vertex[i].y;\r
+                       }else if(i_vertex[i].y>ymax){\r
+                               ymax=(int)i_vertex[i].y;\r
+                       }\r
+               }\r
+               this.h=ymax-ymin+1;\r
+               this.x=xmin;\r
+               this.w=xmax-xmin+1;\r
+               this.y=ymin;\r
+       }\r
+       public final void setAreaRect(NyARIntPoint2d[] i_vertex,int i_num_of_vertex)\r
+       {\r
+               //エリアを求める。\r
+               int xmax,xmin,ymax,ymin;\r
+               xmin=xmax=(int)i_vertex[i_num_of_vertex-1].x;\r
+               ymin=ymax=(int)i_vertex[i_num_of_vertex-1].y;\r
+               for(int i=i_num_of_vertex-2;i>=0;i--){\r
+                       if(i_vertex[i].x<xmin){\r
+                               xmin=(int)i_vertex[i].x;\r
+                       }else if(i_vertex[i].x>xmax){\r
+                               xmax=(int)i_vertex[i].x;\r
+                       }\r
+                       if(i_vertex[i].y<ymin){\r
+                               ymin=(int)i_vertex[i].y;\r
+                       }else if(i_vertex[i].y>ymax){\r
+                               ymax=(int)i_vertex[i].y;\r
+                       }\r
+               }\r
+               this.h=ymax-ymin+1;\r
+               this.x=xmin;\r
+               this.w=xmax-xmin+1;\r
+               this.y=ymin;\r
+       }\r
+\r
+       /**\r
+        * 矩形を指定した領域内にクリップします。\r
+        * @param top\r
+        * @param bottom\r
+        * @param left\r
+        * @param right\r
+        */\r
+       public final void clip(int i_left,int i_top,int i_right,int i_bottom)\r
+       {\r
+               int x=this.x;\r
+               int y=this.y;\r
+               int r=x+this.w-1;\r
+               int b=y+this.h-1;\r
+               if(x<i_left){\r
+                       x=i_left;\r
+               }else if(x>i_right){\r
+                       x=i_right;      \r
+               }\r
+               if(y<i_top){\r
+                       y=i_top;\r
+               }else if(y>i_bottom){\r
+                       y=i_bottom;                     \r
+               }\r
+               int l;\r
+               l=(r>i_right)?i_right-x:r-x;\r
+               if(l<0){\r
+                       this.w=0;\r
+               }else{\r
+                       this.w=l+1;\r
+               }\r
+               l=(b>i_bottom)?i_bottom-y:b-y;\r
+               if(l<0){\r
+                       this.h=0;\r
+               }else{\r
+                       this.h=l+1;\r
+               }\r
+               this.x=x;\r
+               this.y=y;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * 点がRECTの範囲内であるか判定します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @return\r
+        */\r
+       public final boolean isInnerPoint(int i_x,int i_y)\r
+       {\r
+               int x=i_x-this.x;\r
+               int y=i_y-this.y;\r
+               \r
+               return (0<=x && x<this.w && 0<=y && y<this.h);\r
+       }\r
+       public final boolean isInnerPoint(NyARDoublePoint2d i_pos)\r
+       {\r
+               int x=(int)i_pos.x-this.x;\r
+               int y=(int)i_pos.y-this.y;\r
+               return (0<=x && x<this.w && 0<=y && y<this.h);\r
+       }\r
+       public final boolean isInnerPoint(NyARIntPoint2d i_pos)\r
+       {\r
+               int x=i_pos.x-this.x;\r
+               int y=i_pos.y-this.y;\r
+               return (0<=x && x<this.w && 0<=y && y<this.h);\r
+       }\r
+       /**\r
+        * RECTがこのRECTの範囲内であるか判定します。\r
+        * @param i_rect\r
+        * @param i_y\r
+        * @return\r
+        */\r
+       public final boolean isInnerRect(NyARIntRect i_rect)\r
+       {\r
+               assert(i_rect.w>=0 && i_rect.h>=0);\r
+               int lx=i_rect.x-this.x;\r
+               int ly=i_rect.y-this.y;\r
+               int lw=lx+i_rect.w;\r
+               int lh=ly+i_rect.h;\r
+               return (0<=lx && lx<this.w && 0<=ly && ly<this.h && lw<=this.w && lh<=this.h);\r
+       }\r
+       public final boolean isInnerRect(int i_x,int i_y,int i_w,int i_h)\r
+       {\r
+               assert(i_w>=0 && i_h>=0);\r
+               int lx=i_x-this.x;\r
+               int ly=i_y-this.y;\r
+               int lw=lx+i_w;\r
+               int lh=ly+i_h;\r
+               return (0<=lx && lx<this.w && 0<=ly && ly<this.h && lw<=this.w && lh<=this.h);\r
+       }\r
+       /**\r
+        * RECT1とRECT2の差分値を計算します。\r
+        * 差分値は、矩形同士の対角点2点(左上,右下)の距離の二乗の合計値です。\r
+        * @param i_rect1\r
+        * @param i_rect2\r
+        * @return\r
+        */\r
+       public final int sqDiagonalPointDiff(NyARIntRect i_rect2)\r
+       {\r
+               int w1,w2;\r
+               int ret;\r
+               w1=this.x-i_rect2.x;\r
+               w2=this.y-i_rect2.y;\r
+               ret=w1*w1+w2*w2;\r
+               w1+=this.w-i_rect2.w;\r
+               w2+=this.h-i_rect2.h;\r
+               ret+=w1*w1+w2*w2;\r
+               return ret;\r
+       }\r
+       /**\r
+        * 対角線の二乗距離を返します。\r
+        * @return\r
+        */\r
+       public final int getDiagonalSqDist()\r
+       {\r
+               int lh=this.h;\r
+               int lw=this.w;\r
+               return lh*lh+lw*lw;\r
+       }\r
+\r
+       /**\r
+        * i_sourceの値をthisにセットします。\r
+        * @param i_source\r
+        */\r
+       public final void setValue(NyARIntRect i_source)\r
+       {\r
+               this.x=i_source.x;\r
+               this.y=i_source.y;\r
+               this.h=i_source.h;\r
+               this.w=i_source.w;\r
+       }\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntSize.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARIntSize.java
new file mode 100644 (file)
index 0000000..3f5a4e1
--- /dev/null
@@ -0,0 +1,201 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+public class NyARIntSize\r
+{\r
+       public int h;\r
+       public int w;\r
+       public NyARIntSize()\r
+       {\r
+               this.w=0;\r
+               this.h=0;\r
+               return;         \r
+       }\r
+       public NyARIntSize(NyARIntSize i_ref_object)\r
+       {\r
+               this.w=i_ref_object.w;\r
+               this.h=i_ref_object.h;\r
+               return;         \r
+       }\r
+       public NyARIntSize(int i_width,int i_height)\r
+       {\r
+               this.w=i_width;\r
+               this.h=i_height;\r
+               return;\r
+       }\r
+       public final void setValue(int i_w,int i_h)\r
+       {\r
+               this.w=i_w;\r
+               this.h=i_h;\r
+               return;\r
+       }\r
+       /**\r
+        * サイズが同一であるかを確認する。\r
+        * \r
+        * @param i_width\r
+        * @param i_height\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public final boolean isEqualSize(int i_width, int i_height)\r
+       {\r
+               if (i_width == this.w && i_height == this.h) {\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * サイズが同一であるかを確認する。\r
+        * \r
+        * @param i_width\r
+        * @param i_height\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public final boolean isEqualSize(NyARIntSize i_size)\r
+       {\r
+               if (i_size.w == this.w && i_size.h == this.h) {\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       /**\r
+        * サイズがサイズ値の範囲であるか判定します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @return\r
+        */\r
+       public final boolean isInnerSize(int i_x,int i_y)\r
+       {\r
+               return (i_x<=this.w && i_y<=this.h);\r
+       }\r
+       /**\r
+        * サイズ値が、このサイズの範囲内であるか判定します。\r
+        * @param i_size\r
+        * @return\r
+        */\r
+       public final boolean isInnerSize(NyARIntSize i_size)\r
+       {\r
+               return (i_size.w<=this.w && i_size.h<=this.h);\r
+       }\r
+       /**\r
+        * 点が、サイズの内部にあるか判定します。\r
+        * @param i_point\r
+        * @return\r
+        */\r
+       public final boolean isInnerSize(NyARDoublePoint2d i_point)\r
+       {\r
+               return (i_point.x<this.w && i_point.y<this.h && 0<=i_point.x && 0<=i_point.y);\r
+       }\r
+       /**\r
+        * 点が、サイズの内部にあるか判定します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @return\r
+        */\r
+       public final boolean isInnerPoint(int i_x,int i_y)\r
+       {\r
+               return (i_x<this.w && i_y<this.h && 0<=i_x && 0<=i_y);\r
+       }\r
+       /**\r
+        * 点が、サイズの内部にあるか判定します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @return\r
+        */\r
+       public final boolean isInnerPoint(NyARDoublePoint2d i_pos)\r
+       {\r
+               return (i_pos.x<this.w && i_pos.y<this.h && 0<=i_pos.x && 0<=i_pos.y);\r
+       }\r
+       /**\r
+        * 点が、サイズの内部にあるか判定します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @return\r
+        */     \r
+       public final boolean isInnerPoint(NyARIntPoint2d i_pos)\r
+       {\r
+               return (i_pos.x<this.w && i_pos.y<this.h && 0<=i_pos.x && 0<=i_pos.y);\r
+       }\r
+       /**\r
+        * 頂点セットの広がりを計算して格納する。\r
+        * この関数は、頂点セットを全て包括するサイズを計算します。\r
+        * @param i_vertex\r
+        * @param i_num_of_vertex\r
+        */\r
+       public final void setAreaRect(NyARDoublePoint2d[] i_vertex,int i_num_of_vertex)\r
+       {\r
+               //エリアを求める。\r
+               int xmax,xmin,ymax,ymin;\r
+               xmin=xmax=(int)i_vertex[i_num_of_vertex-1].x;\r
+               ymin=ymax=(int)i_vertex[i_num_of_vertex-1].y;\r
+               for(int i=i_num_of_vertex-2;i>=0;i--){\r
+                       if(i_vertex[i].x<xmin){\r
+                               xmin=(int)i_vertex[i].x;\r
+                       }else if(i_vertex[i].x>xmax){\r
+                               xmax=(int)i_vertex[i].x;\r
+                       }\r
+                       if(i_vertex[i].y<ymin){\r
+                               ymin=(int)i_vertex[i].y;\r
+                       }else if(i_vertex[i].y>ymax){\r
+                               ymax=(int)i_vertex[i].y;\r
+                       }\r
+               }\r
+               this.h=ymax-ymin+1;\r
+               this.w=xmax-xmin+1;\r
+       }\r
+       public final void setAreaRect(NyARIntPoint2d[] i_vertex,int i_num_of_vertex)\r
+       {\r
+               //エリアを求める。\r
+               int xmax,xmin,ymax,ymin;\r
+               xmin=xmax=(int)i_vertex[i_num_of_vertex-1].x;\r
+               ymin=ymax=(int)i_vertex[i_num_of_vertex-1].y;\r
+               for(int i=i_num_of_vertex-2;i>=0;i--){\r
+                       if(i_vertex[i].x<xmin){\r
+                               xmin=(int)i_vertex[i].x;\r
+                       }else if(i_vertex[i].x>xmax){\r
+                               xmax=(int)i_vertex[i].x;\r
+                       }\r
+                       if(i_vertex[i].y<ymin){\r
+                               ymin=(int)i_vertex[i].y;\r
+                       }else if(i_vertex[i].y>ymax){\r
+                               ymax=(int)i_vertex[i].y;\r
+                       }\r
+               }\r
+               this.h=ymax-ymin+1;\r
+               this.w=xmax-xmin+1;\r
+       }\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java
new file mode 100644 (file)
index 0000000..7880eff
--- /dev/null
@@ -0,0 +1,402 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+\r
+/**\r
+ * 0=a*x+b*y+cのパラメータを格納します。\r
+ * x,yの増加方向は、x=L→R,y=B→Tです。 y軸が反転しているので注意してください。\r
+ *\r
+ */\r
+public class NyARLinear\r
+{\r
+       public double b;//係数b\r
+       public double a;//係数a\r
+       public double c;//切片\r
+       public static NyARLinear[] createArray(int i_number)\r
+       {\r
+               NyARLinear[] ret=new NyARLinear[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARLinear();\r
+               }\r
+               return ret;\r
+       }       \r
+       public final void copyFrom(NyARLinear i_source)\r
+       {\r
+               this.b=i_source.b;\r
+               this.a=i_source.a;\r
+               this.c=i_source.c;\r
+               return;\r
+       }\r
+       /**\r
+        * 2直線の交点を計算します。\r
+        * @param l_line_2\r
+        * @param o_point\r
+        * @return\r
+        */\r
+       public final boolean crossPos(NyARLinear l_line_2,NyARDoublePoint2d o_point)\r
+       {\r
+               final double w1 = this.a * l_line_2.b - l_line_2.a * this.b;\r
+               if (w1 == 0.0) {\r
+                       return false;\r
+               }\r
+               o_point.x = (this.b * l_line_2.c - l_line_2.b * this.c) / w1;\r
+               o_point.y = (l_line_2.a * this.c - this.a * l_line_2.c) / w1;\r
+               return true;\r
+       }\r
+       /**\r
+        * 指定したパラメータの式との交点を得る。\r
+        * @param i_a\r
+        * @param i_b\r
+        * @param i_c\r
+        * @param o_point\r
+        * @return\r
+        */\r
+       public final boolean crossPos(double i_a,double i_b,double i_c,NyARDoublePoint2d o_point)\r
+       {\r
+               final double w1 = this.a * i_b - i_a * this.b;\r
+               if (w1 == 0.0) {\r
+                       return false;\r
+               }\r
+               o_point.x = (this.b * i_c - i_b * this.c) / w1;\r
+               o_point.y = (i_a * this.c - this.a * i_c) / w1;\r
+               return true;\r
+       }\r
+       public final boolean crossPos(double i_a,double i_b,double i_c,NyARIntPoint2d o_point)\r
+       {\r
+               final double w1 = this.a * i_b - i_a * this.b;\r
+               if (w1 == 0.0) {\r
+                       return false;\r
+               }\r
+               o_point.x = (int)((this.b * i_c - i_b * this.c) / w1);\r
+               o_point.y = (int)((i_a * this.c - this.a * i_c) / w1);\r
+               return true;\r
+       }\r
+       /**\r
+        * 2直線が交差しているかを返します。\r
+        * @param l_line_2\r
+        * @return\r
+        */\r
+       public final boolean isCross(NyARLinear l_line_2)\r
+       {\r
+               final double w1 = this.a * l_line_2.b - l_line_2.a * this.b;\r
+               return (w1 == 0.0)?false:true;\r
+       }\r
+       \r
+       /**\r
+        * 2点を結ぶ直線の式を得る。この式は正規化されている。\r
+        * @param i_point1\r
+        * @param i_point2\r
+        * @return\r
+        */\r
+       public final boolean makeLinearWithNormalize(NyARIntPoint2d i_point1,NyARIntPoint2d i_point2)\r
+       {\r
+               return makeLinearWithNormalize(i_point1.x,i_point1.y,i_point2.x,i_point2.y);\r
+       }\r
+       /**\r
+        * 2点を結ぶ直線の式を得る。この式は正規化されている。\r
+        * @param i_point1\r
+        * @param i_point2\r
+        * @return\r
+        */\r
+       public final boolean makeLinearWithNormalize(NyARDoublePoint2d i_point1,NyARDoublePoint2d i_point2)\r
+       {\r
+               return makeLinearWithNormalize(i_point1.x,i_point1.y,i_point2.x,i_point2.y);\r
+       }\r
+       /**\r
+        * 2点を結ぶ直線の式を得る。この式は正規化されている。\r
+        * @param i_point1\r
+        * @param i_point2\r
+        * @return\r
+        */     \r
+       public final boolean makeLinearWithNormalize(double x1,double y1,double x2,double y2)\r
+       {\r
+               double dx=y2-y1;\r
+               double dy=x1-x2;\r
+               double sq=Math.sqrt(dx*dx+dy*dy);\r
+               if(sq==0){\r
+                       return false;\r
+               }\r
+               sq=1/sq;\r
+               this.a=dx*sq;\r
+               this.b=dy*sq;\r
+               this.c=(x1*(y1-y2)+y1*(x2-x1))*sq;\r
+               return true;\r
+       }\r
+       /**\r
+        * 傾きと通過点を入力して、その直線式をセットする。\r
+        * @param i_dx\r
+        * @param i_dy\r
+        * @param i_x\r
+        * @param i_y\r
+        */\r
+       public final void setVector(double i_dx,double i_dy,double i_x,double i_y)\r
+       {\r
+               this.a= i_dy;\r
+               this.b=-i_dx;\r
+               this.c=(i_dx*i_y-i_dy*i_x);\r
+               return;\r
+       }\r
+       public final void setVector(NyARVecLinear2d i_vector)\r
+       {\r
+               this.a= i_vector.dy;\r
+               this.b=-i_vector.dx;\r
+               this.c=(i_vector.dx*i_vector.y-i_vector.dy*i_vector.x);\r
+               return;         \r
+       }\r
+       public final boolean setVectorWithNormalize(NyARVecLinear2d i_vector)\r
+       {\r
+               double dx=i_vector.dx;\r
+               double dy=i_vector.dy;\r
+               double sq=Math.sqrt(dx*dx+dy*dy);\r
+               if(sq==0){\r
+                       return false;\r
+               }\r
+               sq=1/sq;\r
+               this.a= dy*sq;\r
+               this.b=-dx*sq;\r
+               this.c=-(this.a*i_vector.x+this.b*i_vector.y);          \r
+               return true;\r
+       }\r
+       /**\r
+        * i_x,i_yを通過する、i_linearの法線を計算して、格納します。\r
+        */\r
+       public final void normalLine(double i_x,double i_y,NyARLinear i_linear)\r
+       {\r
+               double la=i_linear.a;\r
+               double lb=i_linear.b;\r
+               this.a=lb;\r
+               this.b=-la;\r
+               this.c=-(lb*i_x-la*i_y);\r
+       }\r
+       /**\r
+        * i_x,i_yを通るこの直線の法線と、i_linearが交わる点を返します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_linear\r
+        * @param o_point\r
+        * @return\r
+        */\r
+       public final boolean normalLineCrossPos(double i_x,double i_y,NyARLinear i_linear,NyARDoublePoint2d o_point)\r
+       {\r
+               //thisを法線に変換\r
+               double la=this.b;\r
+               double lb=-this.a;\r
+               double lc=-(la*i_x+lb*i_y);\r
+               //交点を計算\r
+               final double w1 = i_linear.a * lb - la * i_linear.b;\r
+               if (w1 == 0.0) {\r
+                       return false;\r
+               }\r
+               o_point.x = ((i_linear.b * lc - lb * i_linear.c) / w1);\r
+               o_point.y = ((la * i_linear.c - i_linear.a * lc) / w1);\r
+               return true;\r
+       }\r
+       /**\r
+        * i_x,i_yを通るこの直線の法線上での、この直線とi_linearの距離の二乗値を返します。\r
+        * i_x,i_yに直線上の点を指定すると、この直線の垂線上での、もう一方の直線との距離の二乗値が得られます。\r
+        * @param i_linear\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param o_point\r
+        * @return\r
+        * 交点が無い場合、無限大を返します。\r
+        *//*\r
+       public final double sqDistWithLinear(NyARLinear i_linear, double i_x,double i_y)\r
+       {\r
+               //thisを法線に変換\r
+               double la=this.b;\r
+               double lb=-this.a;\r
+               double lc=-(la*i_x+lb*i_y);\r
+               //交点を計算\r
+               final double w1 = i_linear.a * lb - la * i_linear.b;\r
+               if (w1 == 0.0) {\r
+                       return Double.POSITIVE_INFINITY;\r
+               }\r
+               double x=i_x-((i_linear.b * lc - lb * i_linear.c) / w1);\r
+               double y=i_y-((la * i_linear.c - i_linear.a * lc) / w1);\r
+               return x*x+y*y;\r
+       }*/\r
+\r
+       /**\r
+        * この矩形を任意の範囲でクリッピングしたときの2頂点を返します。\r
+        * @param i_width\r
+        * @param i_height\r
+        * @param o_point\r
+        * @return\r
+        */\r
+       public final boolean makeSegmentLine(int i_width,int i_height,NyARIntPoint2d[] o_point)\r
+       {       \r
+               int idx=0;\r
+               NyARIntPoint2d ptr=o_point[0];\r
+               if(this.crossPos(0,-1,0,ptr) && ptr.x>=0 && ptr.x<i_width)\r
+               {\r
+                       //y=rect.yの線\r
+                       idx++;\r
+                       ptr=o_point[idx];\r
+               }\r
+               if(this.crossPos(0,-1,i_height-1,ptr) && ptr.x>=0 && ptr.x<i_width)\r
+               {\r
+                       //y=(rect.y+rect.h-1)の線\r
+                       idx++;\r
+                       if(idx==2){\r
+                               return true;\r
+                       }\r
+                       ptr=o_point[idx];\r
+               }\r
+               if(this.crossPos(-1,0,0,ptr) && ptr.y>=0 && ptr.y<i_height)\r
+               {\r
+                       //x=i_leftの線\r
+                       idx++;\r
+                       if(idx==2){\r
+                               return true;\r
+                       }\r
+                       ptr=o_point[idx];\r
+               }\r
+               if(this.crossPos(-1,0,i_width-1, ptr) && ptr.y>=0 && ptr.y<i_height)\r
+               {\r
+                       //x=i_right-1の線\r
+                       idx++;\r
+                       if(idx==2){\r
+                               return true;\r
+                       }\r
+               }\r
+               return false;\r
+       }       \r
+       /**\r
+        * この直線を、任意の矩形でクリッピングしたときに得られる線分の2頂点を返します。\r
+        * @param i_left\r
+        * @param i_top\r
+        * @param i_width\r
+        * @param i_height\r
+        * @param o_point\r
+        * @return\r
+        */\r
+       public final boolean makeSegmentLine(int i_left,int i_top,int i_width,int i_height,NyARIntPoint2d[] o_point)\r
+       {       \r
+               int bottom=i_top+i_height;\r
+               int right=i_left+i_width;\r
+               int idx=0;\r
+               NyARIntPoint2d ptr=o_point[0];\r
+               if(this.crossPos(0,-1,i_top,ptr) && ptr.x>=i_left && ptr.x<right)\r
+               {\r
+                       //y=rect.yの線\r
+                       idx++;\r
+                       ptr=o_point[idx];\r
+               }\r
+               if(this.crossPos(0,-1,bottom-1,ptr) && ptr.x>=i_left && ptr.x<right)\r
+               {\r
+                       //y=(rect.y+rect.h-1)の線\r
+                       idx++;\r
+                       if(idx==2){\r
+                               return true;\r
+                       }\r
+                       ptr=o_point[idx];\r
+               }\r
+               if(this.crossPos(-1,0,i_left,ptr) && ptr.y>=i_top && ptr.y<bottom)\r
+               {\r
+                       //x=i_leftの線\r
+                       idx++;\r
+                       if(idx==2){\r
+                               return true;\r
+                       }\r
+                       ptr=o_point[idx];\r
+               }\r
+               if(this.crossPos(-1,0,right-1, ptr) && ptr.y>=i_top && ptr.y<bottom)\r
+               {\r
+                       //x=i_right-1の線\r
+                       idx++;\r
+                       if(idx==2){\r
+                               return true;\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+       /**\r
+        * 直線と、i_sp1とi_sp2の作る線分との二乗距離値の合計を返します。計算方法は、線分の2端点を通過する直線の法線上での、2端点と直線の距離の合計です。\r
+        * 線分と直線の類似度を判定する数値になります。\r
+        * @param i_sp1\r
+        * @param i_sp2\r
+        * @param o_point\r
+        * @return\r
+        * 距離が取れないときは無限大です。\r
+        */\r
+       public final double sqDistBySegmentLineEdge(NyARDoublePoint2d i_sp1,NyARDoublePoint2d i_sp2)\r
+       {\r
+               double la,lb,lc;\r
+               double x,y,w1;\r
+               //thisを法線に変換\r
+               la=this.b;\r
+               lb=-this.a;\r
+\r
+               //交点を計算\r
+               w1 = this.a * lb - la * this.b;\r
+               if (w1 == 0.0) {\r
+                       return Double.POSITIVE_INFINITY;\r
+               }\r
+               //i_sp1と、i_linerの交点\r
+               lc=-(la*i_sp1.x+lb*i_sp1.y);\r
+               x = ((this.b * lc - lb * this.c) / w1)-i_sp1.x;\r
+               y = ((la * this.c - this.a * lc) / w1)-i_sp1.y;\r
+               double sqdist=x*x+y*y;\r
+\r
+               lc=-(la*i_sp2.x+lb*i_sp2.y);\r
+               x = ((this.b * lc - lb * this.c) / w1)-i_sp2.x;\r
+               y = ((la * this.c - this.a * lc) / w1)-i_sp2.y;\r
+\r
+               return sqdist+x*x+y*y;\r
+       }       \r
+       /**\r
+        * 最小二乗法を使用して直線を計算します。\r
+        * @param i_points\r
+        * @param i_number_of_data\r
+        * @return\r
+        */\r
+       public boolean leastSquares(NyARDoublePoint2d[] i_points,int i_number_of_data)\r
+       {\r
+               assert(i_number_of_data>1);\r
+               int i;\r
+               double sum_xy = 0, sum_x = 0, sum_y = 0, sum_x2 = 0;\r
+               for (i=0; i<i_number_of_data; i++){\r
+                       NyARDoublePoint2d ptr=i_points[i];\r
+                       double xw=ptr.x;\r
+                       sum_xy += xw * ptr.y;\r
+                       sum_x += xw;\r
+                       sum_y += ptr.y;\r
+                       sum_x2 += xw*xw;\r
+               }\r
+               this.b =-(i_number_of_data * sum_x2 - sum_x*sum_x);\r
+               this.a = (i_number_of_data * sum_xy - sum_x * sum_y);\r
+               this.c = (sum_x2 * sum_y - sum_xy * sum_x);\r
+               return true;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/NyARVecLinear2d.java b/lib/src/jp/nyatla/nyartoolkit/core/types/NyARVecLinear2d.java
new file mode 100644 (file)
index 0000000..6064bf7
--- /dev/null
@@ -0,0 +1,257 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+\r
+/**\r
+ * 定点と傾きのパラメータで、直線を表現します。\r
+ *\r
+ */\r
+public class NyARVecLinear2d\r
+{\r
+       public double x;\r
+       public double y;\r
+       public double dx;\r
+       public double dy;\r
+       public static NyARVecLinear2d[] createArray(int i_length)\r
+       {\r
+               NyARVecLinear2d[] r=new NyARVecLinear2d[i_length];\r
+               for(int i=0;i<i_length;i++){\r
+                       r[i]=new NyARVecLinear2d();\r
+               }\r
+               return r;\r
+       }\r
+       /**\r
+        * 法線ベクトルを計算します。\r
+        * @param i_src\r
+        * 元のベクトルを指定します。この値には、thisを指定できます。\r
+        */\r
+       public final void normalVec(NyARVecLinear2d i_src)\r
+       {\r
+               double w=this.dx;\r
+               this.dx=i_src.dy;\r
+               this.dy=-w;\r
+       }\r
+       public final void setValue(NyARVecLinear2d i_value)\r
+       {\r
+               this.dx=i_value.dx;\r
+               this.dy=i_value.dy;\r
+               this.x=i_value.x;\r
+               this.y=i_value.y;\r
+       }\r
+       /**\r
+        * このベクトルと指定した直線が作るCos値を返します。\r
+        * @param i_v1\r
+        * @return\r
+        */\r
+       public final double getVecCos(NyARVecLinear2d i_v1)\r
+       {\r
+               double x1=i_v1.dx;\r
+               double y1=i_v1.dy;\r
+               double x2=this.dx;\r
+               double y2=this.dy;\r
+               double d=(x1*x2+y1*y2)/Math.sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2));\r
+               return d;\r
+       }\r
+       public final double getAbsVecCos(NyARVecLinear2d i_v1)\r
+       {\r
+               double x1=i_v1.dx;\r
+               double y1=i_v1.dy;\r
+               double x2=this.dx;\r
+               double y2=this.dy;\r
+               double d=(x1*x2+y1*y2)/Math.sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2));\r
+               return d>=0?d:-d;\r
+       }\r
+       /**\r
+        * このベクトルと指定したベクトルが作るCos値を返します。\r
+        * @param i_dx\r
+        * @param i_dy\r
+        * @return\r
+        */\r
+       public final double getVecCos(double i_dx,double i_dy)\r
+       {\r
+               double x1=this.dx;\r
+               double y1=this.dy;\r
+               double d=(x1*i_dx+y1*i_dy)/Math.sqrt((x1*x1+y1*y1)*(i_dx*i_dx+i_dy*i_dy));\r
+               return d;\r
+       }\r
+       public final double getVecCos(NyARDoublePoint2d i_pos1,NyARDoublePoint2d i_pos2)\r
+       {\r
+               double d=getAbsVecCos(i_pos2.x-i_pos1.x,i_pos2.y-i_pos1.y);\r
+               return d>=0?d:-d;\r
+       }       \r
+       public final double getAbsVecCos(double i_v2_x,double i_v2_y)\r
+       {\r
+               double x1=this.dx;\r
+               double y1=this.dy;\r
+               double d=(x1*i_v2_x+y1*i_v2_y)/Math.sqrt((x1*x1+y1*y1)*(i_v2_x*i_v2_x+i_v2_y*i_v2_y));\r
+               return d>=0?d:-d;\r
+       }\r
+       /**\r
+        * このベクトルと、i_pos1-&lt;i_pos2を結ぶ線分が作るcos値の絶対値を返します。\r
+        * @param i_pos1\r
+        * @param i_pos2\r
+        * @return\r
+        */\r
+       public final double getAbsVecCos(NyARDoublePoint2d i_pos1,NyARDoublePoint2d i_pos2)\r
+       {\r
+               double d=getAbsVecCos(i_pos2.x-i_pos1.x,i_pos2.y-i_pos1.y);\r
+               return d>=0?d:-d;\r
+       }\r
+       \r
+       /**\r
+        * 交点を求めます。\r
+        * @param i_vector1\r
+        * @param i_vector2\r
+        * @param o_point\r
+        * @return\r
+        */\r
+       public final boolean crossPos(NyARVecLinear2d i_vector1,NyARDoublePoint2d o_point)\r
+       {\r
+               double a1= i_vector1.dy;\r
+               double b1=-i_vector1.dx;\r
+               double c1=(i_vector1.dx*i_vector1.y-i_vector1.dy*i_vector1.x);\r
+               double a2= this.dy;\r
+               double b2=-this.dx;\r
+               double c2=(this.dx*this.y-this.dy*this.x);\r
+               final double w1 = a1 * b2 - a2 * b1;\r
+               if (w1 == 0.0) {\r
+                       return false;\r
+               }\r
+               o_point.x = (b1 * c2 - b2 * c1) / w1;\r
+               o_point.y = (a2 * c1 - a1 * c2) / w1;\r
+               return true;\r
+       }\r
+       /**\r
+        * 直線と、i_sp1とi_sp2の作る線分との二乗距離値の合計を返します。\r
+        * 線分と直線の類似度を\r
+        * @param i_sp1\r
+        * @param i_sp2\r
+        * @param o_point\r
+        * @return\r
+        * 距離が取れないときは無限大です。\r
+        */\r
+       public final double sqDistBySegmentLineEdge(NyARDoublePoint2d i_sp1,NyARDoublePoint2d i_sp2)\r
+       {\r
+               double sa,sb,sc;\r
+               sa= this.dy;\r
+               sb=-this.dx;\r
+               sc=(this.dx*this.y-this.dy*this.x);\r
+               \r
+\r
+               double lc;\r
+               double x,y,w1;\r
+               //thisを法線に変換\r
+\r
+               //交点を計算\r
+               w1 = sa * (-sa) - sb * sb;\r
+               if (w1 == 0.0) {\r
+                       return Double.POSITIVE_INFINITY;\r
+               }\r
+               //i_sp1と、i_linerの交点\r
+               lc=-(sb*i_sp1.x-sa*i_sp1.y);\r
+               x = ((sb * lc +sa * sc) / w1)-i_sp1.x;\r
+               y = ((sb * sc - sa * lc) / w1)-i_sp1.y;\r
+               double sqdist=x*x+y*y;\r
+\r
+               lc=-(sb*i_sp2.x-sa*i_sp2.y);\r
+               x = ((sb * lc + sa * sc) / w1)-i_sp2.x;\r
+               y = ((sb * sc - sa * lc) / w1)-i_sp2.y;\r
+\r
+               return sqdist+x*x+y*y;\r
+       }\r
+\r
+       /**\r
+        * i_lineの直線をセットします。x,yの値は、(i_x,i_y)を通過するi_lineの法線とi_lineの交点をセットします。\r
+        * @param i_line\r
+        * @param i_x\r
+        * @param i_y\r
+        */\r
+       public boolean setLinear(NyARLinear i_line,double i_x,double i_y)\r
+       {\r
+               double la=i_line.b;\r
+               double lb=-i_line.a;\r
+               double lc=-(la*i_x+lb*i_y);\r
+               //交点を計算\r
+               final double w1 = -lb * lb - la * la;\r
+               if (w1 == 0.0) {\r
+                       return false;\r
+               }               \r
+               this.x=((la * lc - lb * i_line.c) / w1);\r
+               this.y= ((la * i_line.c +lb * lc) / w1);\r
+               this.dy=-lb;\r
+               this.dx=-la;\r
+               return true;\r
+       }\r
+       /**\r
+        * 点群から最小二乗法で直線を計算してセットします。\r
+        * 通過点x,yは、点群の中央値を通過する、算出された直線の法線との交点です。\r
+        * @param i_points\r
+        * @param i_number_of_data\r
+        * @return\r
+        */\r
+       public final boolean leastSquares(NyARDoublePoint2d[] i_points,int i_number_of_data)\r
+       {\r
+               int i;\r
+               double sum_xy = 0, sum_x = 0, sum_y = 0, sum_x2 = 0;\r
+               for (i=0; i<i_number_of_data; i++){\r
+                       NyARDoublePoint2d ptr=i_points[i];\r
+                       double xw=ptr.x;\r
+                       sum_xy += xw * ptr.y;\r
+                       sum_x += xw;\r
+                       sum_y += ptr.y;\r
+                       sum_x2 += xw*xw;\r
+               }\r
+               double la=-(i_number_of_data * sum_x2 - sum_x*sum_x);\r
+               double lb=-(i_number_of_data * sum_xy - sum_x * sum_y);\r
+               double cc=(sum_x2 * sum_y - sum_xy * sum_x);\r
+               double lc=-(la*sum_x+lb*sum_y)/i_number_of_data;\r
+               //交点を計算\r
+               final double w1 = -lb * lb - la * la;\r
+               if (w1 == 0.0) {\r
+                       return false;\r
+               }               \r
+               this.x=((la * lc - lb * cc) / w1);\r
+               this.y= ((la * cc +lb * lc) / w1);\r
+               this.dy=-lb;\r
+               this.dx=-la;\r
+               return true;\r
+       }\r
+       /**\r
+        * 正規化したベクトルを出力する{@link #leastSquares}です。\r
+        * @param i_points\r
+        * @param i_number_of_data\r
+        * @return\r
+        */\r
+       public final boolean leastSquaresWithNormalize(NyARDoublePoint2d[] i_points,int i_number_of_data)\r
+       {\r
+               boolean ret=this.leastSquares(i_points, i_number_of_data);\r
+               double sq=1/Math.sqrt(this.dx*this.dx+this.dy*this.dy);\r
+               this.dx*=sq;\r
+               this.dy*=sq;\r
+               return ret;\r
+       }\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/INyARDoubleMatrix.java b/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/INyARDoubleMatrix.java
new file mode 100644 (file)
index 0000000..bd44fba
--- /dev/null
@@ -0,0 +1,48 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+public interface INyARDoubleMatrix\r
+{\r
+       /**\r
+        * 配列の内容を行列に設定する。\r
+        * 遅いので余り使わないでね。\r
+        * @param o_value\r
+        */\r
+       public void setValue(double[] i_value);\r
+       /**\r
+        * 行列の内容を配列に返す。\r
+        * 遅いので余り使わないでね。\r
+        * @param o_value\r
+        */\r
+       public void getValue(double[] o_value);\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix22.java b/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix22.java
new file mode 100644 (file)
index 0000000..b44f638
--- /dev/null
@@ -0,0 +1,73 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+public class NyARDoubleMatrix22 implements INyARDoubleMatrix\r
+{\r
+       public double m00;\r
+       public double m01;\r
+       public double m10;\r
+       public double m11;\r
+       /**\r
+        * 遅いからあんまり使わないでね。\r
+        */\r
+       public void setValue(double[] i_value)\r
+       {\r
+               this.m00=i_value[0];\r
+               this.m01=i_value[1];\r
+               this.m10=i_value[3];\r
+               this.m11=i_value[4];\r
+               return;\r
+       }\r
+       /**\r
+        * 遅いからあんまり使わないでね。\r
+        */\r
+       public void getValue(double[] o_value)\r
+       {\r
+               o_value[0]=this.m00;\r
+               o_value[1]=this.m01;\r
+               o_value[3]=this.m10;\r
+               o_value[4]=this.m11;\r
+               return;\r
+       }\r
+       public boolean inverse(NyARDoubleMatrix22 i_src)\r
+       {\r
+               final double a11,a12,a21,a22;\r
+               a11=i_src.m00;\r
+               a12=i_src.m01;\r
+               a21=i_src.m10;\r
+               a22=i_src.m11;\r
+               double det=a11*a22-a12*a21;\r
+               if(det==0){\r
+                       return false;\r
+               }\r
+               det=1/det;\r
+               this.m00=a22*det;\r
+               this.m01=-a12*det;\r
+               this.m10=-a21*det;\r
+               this.m11=a11*det;\r
+               return true;\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix33.java b/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix33.java
new file mode 100644 (file)
index 0000000..04dfd2a
--- /dev/null
@@ -0,0 +1,198 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+\r
+public class NyARDoubleMatrix33 implements INyARDoubleMatrix\r
+{\r
+       public double m00;\r
+       public double m01;\r
+       public double m02;\r
+       public double m10;\r
+       public double m11;\r
+       public double m12;\r
+       public double m20;\r
+       public double m21;\r
+       public double m22;\r
+       public static NyARDoubleMatrix33[] createArray(int i_number)\r
+       {\r
+               NyARDoubleMatrix33[] ret=new NyARDoubleMatrix33[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARDoubleMatrix33();\r
+               }\r
+               return ret;\r
+       }\r
+       /**\r
+        * 遅いからあんまり使わないでね。\r
+        */\r
+       public void setValue(double[] i_value)\r
+       {\r
+               this.m00=i_value[0];\r
+               this.m01=i_value[1];\r
+               this.m02=i_value[2];\r
+               this.m10=i_value[3];\r
+               this.m11=i_value[4];\r
+               this.m12=i_value[5];\r
+               this.m20=i_value[6];\r
+               this.m21=i_value[7];\r
+               this.m22=i_value[8];\r
+               return;\r
+       }\r
+       public void setValue(NyARDoubleMatrix33 i_value)\r
+       {\r
+               this.m00=i_value.m00;\r
+               this.m01=i_value.m01;\r
+               this.m02=i_value.m02;\r
+               this.m10=i_value.m10;\r
+               this.m11=i_value.m11;\r
+               this.m12=i_value.m12;\r
+               this.m20=i_value.m20;\r
+               this.m21=i_value.m21;\r
+               this.m22=i_value.m22;\r
+               return;\r
+       }       \r
+       /**\r
+        * 遅いからあんまり使わないでね。\r
+        */\r
+       public void getValue(double[] o_value)\r
+       {\r
+               o_value[0]=this.m00;\r
+               o_value[1]=this.m01;\r
+               o_value[2]=this.m02;\r
+               o_value[3]=this.m10;\r
+               o_value[4]=this.m11;\r
+               o_value[5]=this.m12;\r
+               o_value[6]=this.m20;\r
+               o_value[7]=this.m21;\r
+               o_value[8]=this.m22;\r
+               return;\r
+       }\r
+       public boolean inverse(NyARDoubleMatrix33 i_src)\r
+       {\r
+               final double a11,a12,a13,a21,a22,a23,a31,a32,a33;\r
+               final double b11,b12,b13,b21,b22,b23,b31,b32,b33;       \r
+               a11=i_src.m00;a12=i_src.m01;a13=i_src.m02;\r
+               a21=i_src.m10;a22=i_src.m11;a23=i_src.m12;\r
+               a31=i_src.m20;a32=i_src.m21;a33=i_src.m22;\r
+               \r
+               b11=a22*a33-a23*a32;\r
+               b12=a32*a13-a33*a12;\r
+               b13=a12*a23-a13*a22;\r
+               \r
+               b21=a23*a31-a21*a33;\r
+               b22=a33*a11-a31*a13;\r
+               b23=a13*a21-a11*a23;\r
+               \r
+               b31=a21*a32-a22*a31;\r
+               b32=a31*a12-a32*a11;\r
+               b33=a11*a22-a12*a21;\r
+                               \r
+               double det_1=a11*b11+a21*b12+a31*b13;\r
+               if(det_1==0){\r
+                       return false;\r
+               }\r
+               det_1=1/det_1;\r
+\r
+               this.m00=b11*det_1;\r
+               this.m01=b12*det_1;\r
+               this.m02=b13*det_1;\r
+               \r
+               this.m10=b21*det_1;\r
+               this.m11=b22*det_1;\r
+               this.m12=b23*det_1;\r
+               \r
+               this.m20=b31*det_1;\r
+               this.m21=b32*det_1;\r
+               this.m22=b33*det_1;\r
+               \r
+               return true;\r
+       }\r
+       /**\r
+        * この関数は、0-PIの間で値を返します。\r
+        * @param o_out\r
+        */\r
+       public final void getZXYAngle(NyARDoublePoint3d o_out)\r
+       {\r
+               double sina = this.m21;\r
+               if (sina >= 1.0) {\r
+                       o_out.x = Math.PI / 2;\r
+                       o_out.y = 0;\r
+                       o_out.z = Math.atan2(-this.m10, this.m00);\r
+               } else if (sina <= -1.0) {\r
+                       o_out.x = -Math.PI / 2;\r
+                       o_out.y = 0;\r
+                       o_out.z = Math.atan2(-this.m10, this.m00);\r
+               } else {\r
+                       o_out.x = Math.asin(sina);\r
+                       o_out.z = Math.atan2(-this.m01, this.m11);\r
+                       o_out.y = Math.atan2(-this.m20, this.m22);\r
+               }\r
+       }\r
+       public final void setZXYAngle(NyARDoublePoint3d i_angle)\r
+       {\r
+               setZXYAngle(i_angle.x,i_angle.y,i_angle.z);\r
+               return;\r
+       }\r
+       public final void setZXYAngle(final double i_x, final double i_y, final double i_z)\r
+       {\r
+               final double sina = Math.sin(i_x);\r
+               final double cosa = Math.cos(i_x);\r
+               final double sinb = Math.sin(i_y);\r
+               final double cosb = Math.cos(i_y);\r
+               final double sinc = Math.sin(i_z);\r
+               final double cosc = Math.cos(i_z);\r
+               this.m00 = cosc * cosb - sinc * sina * sinb;\r
+               this.m01 = -sinc * cosa;\r
+               this.m02 = cosc * sinb + sinc * sina * cosb;\r
+               this.m10 = sinc * cosb + cosc * sina * sinb;\r
+               this.m11 = cosc * cosa;\r
+               this.m12 = sinc * sinb - cosc * sina * cosb;\r
+               this.m20 = -cosa * sinb;\r
+               this.m21 = sina;\r
+               this.m22 = cosb * cosa;\r
+               return;\r
+       }\r
+       /**\r
+        * 回転行列を適応して座標変換します。\r
+        * @param i_angle\r
+        * @param o_out\r
+        */\r
+       public final void transformVertex(NyARDoublePoint3d i_position,NyARDoublePoint3d o_out)\r
+       {\r
+               transformVertex(i_position.x,i_position.y,i_position.z,o_out);\r
+               return;\r
+       }\r
+       \r
+       public final void transformVertex(double i_x,double i_y,double i_z,NyARDoublePoint3d o_out)\r
+       {\r
+               o_out.x=this.m00*i_x+this.m01*i_y+this.m02*i_z;\r
+               o_out.y=this.m10*i_x+this.m11*i_y+this.m12*i_z;\r
+               o_out.z=this.m20*i_x+this.m21*i_y+this.m22*i_z;\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix34.java b/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix34.java
new file mode 100644 (file)
index 0000000..1f05cf9
--- /dev/null
@@ -0,0 +1,89 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+public class NyARDoubleMatrix34 implements INyARDoubleMatrix\r
+{\r
+       public double m00;\r
+       public double m01;\r
+       public double m02;\r
+       public double m03;\r
+       public double m10;\r
+       public double m11;\r
+       public double m12;\r
+       public double m13;\r
+       public double m20;\r
+       public double m21;\r
+       public double m22;\r
+       public double m23;\r
+       public void setValue(double[] i_value)\r
+       {\r
+               this.m00=i_value[0];\r
+               this.m01=i_value[1];\r
+               this.m02=i_value[2];\r
+               this.m03=i_value[3];\r
+               this.m10=i_value[4];\r
+               this.m11=i_value[5];\r
+               this.m12=i_value[6];\r
+               this.m13=i_value[7];\r
+               this.m20=i_value[8];\r
+               this.m21=i_value[9];\r
+               this.m22=i_value[10];\r
+               this.m23=i_value[11];\r
+               return;\r
+       }\r
+       public void setValue(NyARDoubleMatrix34 i_value)\r
+       {\r
+               this.m00=i_value.m00;\r
+               this.m01=i_value.m01;\r
+               this.m02=i_value.m02;\r
+               this.m03=i_value.m03;\r
+               this.m10=i_value.m10;\r
+               this.m11=i_value.m11;\r
+               this.m12=i_value.m12;\r
+               this.m13=i_value.m13;\r
+               this.m20=i_value.m20;\r
+               this.m21=i_value.m21;\r
+               this.m22=i_value.m22;\r
+               this.m23=i_value.m23;\r
+               return;\r
+       }\r
+       public void getValue(double[] o_value)\r
+       {\r
+               o_value[0]=this.m00;\r
+               o_value[1]=this.m01;\r
+               o_value[2]=this.m02;\r
+               o_value[3]=this.m03;\r
+               o_value[4]=this.m10;\r
+               o_value[5]=this.m11;\r
+               o_value[6]=this.m12;\r
+               o_value[7]=this.m13;\r
+               o_value[8]=this.m20;\r
+               o_value[9]=this.m21;\r
+               o_value[10]=this.m22;\r
+               o_value[11]=this.m23;\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix44.java b/lib/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix44.java
new file mode 100644 (file)
index 0000000..52e3aea
--- /dev/null
@@ -0,0 +1,506 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+\r
+\r
+\r
+public class NyARDoubleMatrix44 implements INyARDoubleMatrix\r
+{\r
+       public double m00;\r
+       public double m01;\r
+       public double m02;\r
+       public double m03;\r
+       public double m10;\r
+       public double m11;\r
+       public double m12;\r
+       public double m13;\r
+       public double m20;\r
+       public double m21;\r
+       public double m22;\r
+       public double m23;\r
+       public double m30;\r
+       public double m31;\r
+       public double m32;\r
+       public double m33;\r
+       public static NyARDoubleMatrix44[] createArray(int i_number)\r
+       {\r
+               NyARDoubleMatrix44[] ret=new NyARDoubleMatrix44[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARDoubleMatrix44();\r
+               }\r
+               return ret;\r
+       }\r
+       /**\r
+        * 配列の内容をセットします。順番は、00,01,02,03,10...の順です。\r
+        */\r
+       public void setValue(double[] i_value)\r
+       {\r
+               this.m00=i_value[ 0];\r
+               this.m01=i_value[ 1];\r
+               this.m02=i_value[ 2];\r
+               this.m03=i_value[ 3];\r
+               this.m10=i_value[ 4];\r
+               this.m11=i_value[ 5];\r
+               this.m12=i_value[ 6];\r
+               this.m13=i_value[ 7];\r
+               this.m20=i_value[ 8];\r
+               this.m21=i_value[ 9];\r
+               this.m22=i_value[10];\r
+               this.m23=i_value[11];\r
+               this.m30=i_value[12];\r
+               this.m31=i_value[13];\r
+               this.m32=i_value[14];\r
+               this.m33=i_value[15];\r
+               return;\r
+       }\r
+       /**\r
+        * i_valueの内容を、このインスタンスにセットします。\r
+        * @param i_value\r
+        */\r
+       public void setValue(NyARDoubleMatrix44 i_value)\r
+       {\r
+               this.m00=i_value.m00;\r
+               this.m01=i_value.m01;\r
+               this.m02=i_value.m02;\r
+               this.m03=i_value.m03;\r
+               this.m10=i_value.m10;\r
+               this.m11=i_value.m11;\r
+               this.m12=i_value.m12;\r
+               this.m13=i_value.m13;\r
+               this.m20=i_value.m20;\r
+               this.m21=i_value.m21;\r
+               this.m22=i_value.m22;\r
+               this.m23=i_value.m23;\r
+               this.m30=i_value.m30;\r
+               this.m31=i_value.m31;\r
+               this.m32=i_value.m32;\r
+               this.m33=i_value.m33;\r
+               return;\r
+       }\r
+       /**\r
+        * 行列の内容を配列に出力します。順番は、00,01,02,03,10...の順です。\r
+        */\r
+       public void getValue(double[] o_value)\r
+       {\r
+               o_value[ 0]=this.m00;\r
+               o_value[ 1]=this.m01;\r
+               o_value[ 2]=this.m02;\r
+               o_value[ 3]=this.m03;\r
+               o_value[ 4]=this.m10;\r
+               o_value[ 5]=this.m11;\r
+               o_value[ 6]=this.m12;\r
+               o_value[ 7]=this.m13;\r
+               o_value[ 8]=this.m20;\r
+               o_value[ 9]=this.m21;\r
+               o_value[10]=this.m22;\r
+               o_value[11]=this.m23;\r
+               o_value[12]=this.m30;\r
+               o_value[13]=this.m31;\r
+               o_value[14]=this.m32;\r
+               o_value[15]=this.m33;\r
+               return;\r
+       }\r
+       /**\r
+        * 行列の内容を転置してから配列に出力します。\r
+        * 順番は、00,10,20,30,01...の順です。\r
+        */     \r
+       public void getValueT(double[] o_value)\r
+       {\r
+               o_value[ 0]=this.m00;\r
+               o_value[ 1]=this.m10;\r
+               o_value[ 2]=this.m20;\r
+               o_value[ 3]=this.m30;\r
+               o_value[ 4]=this.m01;\r
+               o_value[ 5]=this.m11;\r
+               o_value[ 6]=this.m21;\r
+               o_value[ 7]=this.m31;\r
+               o_value[ 8]=this.m02;\r
+               o_value[ 9]=this.m12;\r
+               o_value[10]=this.m22;\r
+               o_value[11]=this.m32;\r
+               o_value[12]=this.m03;\r
+               o_value[13]=this.m13;\r
+               o_value[14]=this.m23;\r
+               o_value[15]=this.m33;\r
+               return;\r
+       }\r
+       /**\r
+        * 逆行列を計算して、i_srcのthisへ格納します。i_srcにはthisも指定可能です。\r
+        * @param i_src\r
+        * @return\r
+        */\r
+       public boolean inverse(NyARDoubleMatrix44 i_src)\r
+       {\r
+               final double a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34,a41,a42,a43,a44;\r
+               final double b11,b12,b13,b14,b21,b22,b23,b24,b31,b32,b33,b34,b41,b42,b43,b44;   \r
+               double t1,t2,t3,t4,t5,t6;\r
+               a11=i_src.m00;a12=i_src.m01;a13=i_src.m02;a14=i_src.m03;\r
+               a21=i_src.m10;a22=i_src.m11;a23=i_src.m12;a24=i_src.m13;\r
+               a31=i_src.m20;a32=i_src.m21;a33=i_src.m22;a34=i_src.m23;\r
+               a41=i_src.m30;a42=i_src.m31;a43=i_src.m32;a44=i_src.m33;\r
+               \r
+               t1=a33*a44-a34*a43;\r
+               t2=a34*a42-a32*a44;\r
+               t3=a32*a43-a33*a42;\r
+               t4=a34*a41-a31*a44;\r
+               t5=a31*a43-a33*a41;\r
+               t6=a31*a42-a32*a41;\r
+               \r
+               b11=a22*t1+a23*t2+a24*t3;\r
+               b21=-(a23*t4+a24*t5+a21*t1);\r
+               b31=a24*t6-a21*t2+a22*t4;\r
+               b41=-(a21*t3-a22*t5+a23*t6);\r
+               \r
+               t1=a43*a14-a44*a13;\r
+               t2=a44*a12-a42*a14;\r
+               t3=a42*a13-a43*a12;\r
+               t4=a44*a11-a41*a14;\r
+               t5=a41*a13-a43*a11;\r
+               t6=a41*a12-a42*a11;\r
+\r
+               b12=-(a32*t1+a33*t2+a34*t3);\r
+               b22=a33*t4+a34*t5+a31*t1;\r
+               b32=-(a34*t6-a31*t2+a32*t4);\r
+               b42=a31*t3-a32*t5+a33*t6;\r
+               \r
+               t1=a13*a24-a14*a23;\r
+               t2=a14*a22-a12*a24;\r
+               t3=a12*a23-a13*a22;\r
+               t4=a14*a21-a11*a24;\r
+               t5=a11*a23-a13*a21;\r
+               t6=a11*a22-a12*a21;\r
+\r
+               b13=a42*t1+a43*t2+a44*t3;\r
+               b23=-(a43*t4+a44*t5+a41*t1);\r
+               b33=a44*t6-a41*t2+a42*t4;\r
+               b43=-(a41*t3-a42*t5+a43*t6);\r
+\r
+               t1=a23*a34-a24*a33;\r
+               t2=a24*a32-a22*a34;\r
+               t3=a22*a33-a23*a32;\r
+               t4=a24*a31-a21*a34;             \r
+               t5=a21*a33-a23*a31;\r
+               t6=a21*a32-a22*a31;\r
+\r
+               b14=-(a12*t1+a13*t2+a14*t3);\r
+               b24=a13*t4+a14*t5+a11*t1;\r
+               b34=-(a14*t6-a11*t2+a12*t4);\r
+               b44=a11*t3-a12*t5+a13*t6;\r
+               \r
+               double det_1=(a11*b11+a21*b12+a31*b13+a41*b14);\r
+               if(det_1==0){\r
+                       return false;\r
+               }\r
+               det_1=1/det_1;\r
+\r
+               this.m00=b11*det_1;\r
+               this.m01=b12*det_1;\r
+               this.m02=b13*det_1;\r
+               this.m03=b14*det_1;\r
+               \r
+               this.m10=b21*det_1;\r
+               this.m11=b22*det_1;\r
+               this.m12=b23*det_1;\r
+               this.m13=b24*det_1;\r
+               \r
+               this.m20=b31*det_1;\r
+               this.m21=b32*det_1;\r
+               this.m22=b33*det_1;\r
+               this.m23=b34*det_1;\r
+               \r
+               this.m30=b41*det_1;\r
+               this.m31=b42*det_1;\r
+               this.m32=b43*det_1;\r
+               this.m33=b44*det_1;\r
+               \r
+               return true;\r
+       }\r
+       \r
+       /**\r
+        * 行列を姿勢変換行列として、3次元座標を座標変換します。4列目は1で仮定します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_z\r
+        * @param o_out\r
+        */\r
+       public final void transform3d(double i_x,double i_y,double i_z,NyARDoublePoint3d o_out)\r
+       {\r
+               o_out.x=this.m00*i_x+this.m01*i_y+this.m02*i_z+this.m03;\r
+               o_out.y=this.m10*i_x+this.m11*i_y+this.m12*i_z+this.m13;\r
+               o_out.z=this.m20*i_x+this.m21*i_y+this.m22*i_z+this.m23;\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * 行列を姿勢変換行列として、3次元座標を座標変換します。\r
+        * i_inとo_outには同一なインスタンスを指定できます。\r
+        * @param i_in\r
+        * @param o_out\r
+        */\r
+       public final void transform3d(NyARDoublePoint3d i_in,NyARDoublePoint3d o_out)\r
+       {\r
+               transform3d(i_in.x,i_in.y,i_in.z,o_out);\r
+       }\r
+       /**\r
+        * 行列を姿勢行列として、ZXY系の角度値を返します。\r
+        * この関数は、0-PIの間で値を返します。\r
+        * @param o_out\r
+        */\r
+       public final void getZXYAngle(NyARDoublePoint3d o_out)\r
+       {\r
+               double sina = this.m21;\r
+               if (sina >= 1.0) {\r
+                       o_out.x = Math.PI / 2;\r
+                       o_out.y = 0;\r
+                       o_out.z = Math.atan2(-this.m10, this.m00);\r
+               } else if (sina <= -1.0) {\r
+                       o_out.x = -Math.PI / 2;\r
+                       o_out.y = 0;\r
+                       o_out.z = Math.atan2(-this.m10, this.m00);\r
+               } else {\r
+                       o_out.x = Math.asin(sina);\r
+                       o_out.z = Math.atan2(-this.m01, this.m11);\r
+                       o_out.y = Math.atan2(-this.m20, this.m22);\r
+               }\r
+       }\r
+       /**\r
+        * 行列の掛け算を実行して、結果を格納します。i_mat_lとi_mat_rには、thisを指定しないでください。\r
+        * @param i_mat_l\r
+        * @param i_mat_r\r
+        */\r
+       public final void mul(NyARDoubleMatrix44 i_mat_l,NyARDoubleMatrix44 i_mat_r)\r
+       {\r
+               assert(this!=i_mat_l);\r
+               assert(this!=i_mat_r);\r
+               this.m00=i_mat_l.m00*i_mat_r.m00 + i_mat_l.m01*i_mat_r.m10 + i_mat_l.m02*i_mat_r.m20 + i_mat_l.m03*i_mat_r.m30;\r
+               this.m01=i_mat_l.m00*i_mat_r.m01 + i_mat_l.m01*i_mat_r.m11 + i_mat_l.m02*i_mat_r.m21 + i_mat_l.m03*i_mat_r.m31;\r
+               this.m02=i_mat_l.m00*i_mat_r.m02 + i_mat_l.m01*i_mat_r.m12 + i_mat_l.m02*i_mat_r.m22 + i_mat_l.m03*i_mat_r.m32;\r
+               this.m03=i_mat_l.m00*i_mat_r.m03 + i_mat_l.m01*i_mat_r.m13 + i_mat_l.m02*i_mat_r.m23 + i_mat_l.m03*i_mat_r.m33;\r
+\r
+               this.m10=i_mat_l.m10*i_mat_r.m00 + i_mat_l.m11*i_mat_r.m10 + i_mat_l.m12*i_mat_r.m20 + i_mat_l.m13*i_mat_r.m30;\r
+               this.m11=i_mat_l.m10*i_mat_r.m01 + i_mat_l.m11*i_mat_r.m11 + i_mat_l.m12*i_mat_r.m21 + i_mat_l.m13*i_mat_r.m31;\r
+               this.m12=i_mat_l.m10*i_mat_r.m02 + i_mat_l.m11*i_mat_r.m12 + i_mat_l.m12*i_mat_r.m22 + i_mat_l.m13*i_mat_r.m32;\r
+               this.m13=i_mat_l.m10*i_mat_r.m03 + i_mat_l.m11*i_mat_r.m13 + i_mat_l.m12*i_mat_r.m23 + i_mat_l.m13*i_mat_r.m33;\r
+\r
+               this.m20=i_mat_l.m20*i_mat_r.m00 + i_mat_l.m21*i_mat_r.m10 + i_mat_l.m22*i_mat_r.m20 + i_mat_l.m23*i_mat_r.m30;\r
+               this.m21=i_mat_l.m20*i_mat_r.m01 + i_mat_l.m21*i_mat_r.m11 + i_mat_l.m22*i_mat_r.m21 + i_mat_l.m23*i_mat_r.m31;\r
+               this.m22=i_mat_l.m20*i_mat_r.m02 + i_mat_l.m21*i_mat_r.m12 + i_mat_l.m22*i_mat_r.m22 + i_mat_l.m23*i_mat_r.m32;\r
+               this.m23=i_mat_l.m20*i_mat_r.m03 + i_mat_l.m21*i_mat_r.m13 + i_mat_l.m22*i_mat_r.m23 + i_mat_l.m23*i_mat_r.m33;\r
+\r
+               this.m30=i_mat_l.m30*i_mat_r.m00 + i_mat_l.m31*i_mat_r.m10 + i_mat_l.m32*i_mat_r.m20 + i_mat_l.m33*i_mat_r.m30;\r
+               this.m31=i_mat_l.m30*i_mat_r.m01 + i_mat_l.m31*i_mat_r.m11 + i_mat_l.m32*i_mat_r.m21 + i_mat_l.m33*i_mat_r.m31;\r
+               this.m32=i_mat_l.m30*i_mat_r.m02 + i_mat_l.m31*i_mat_r.m12 + i_mat_l.m32*i_mat_r.m22 + i_mat_l.m33*i_mat_r.m32;\r
+               this.m33=i_mat_l.m30*i_mat_r.m03 + i_mat_l.m31*i_mat_r.m13 + i_mat_l.m32*i_mat_r.m23 + i_mat_l.m33*i_mat_r.m33; \r
+               return;\r
+       }\r
+       /**\r
+        * この行列を単位行列にします。\r
+        */\r
+       public final void identity()\r
+       {\r
+               this.m00=this.m11=this.m22=this.m33=1;\r
+               this.m01=this.m02=this.m03=this.m10=this.m12=this.m13=this.m20=this.m21=this.m23=this.m30=this.m31=this.m32=0;\r
+               return;\r
+       }\r
+       /**\r
+        * 行列に、右手系のX軸回転を設定します。\r
+        * @param i_radian\r
+        */\r
+       public final void setRotateX(double i_radian)\r
+       {\r
+               double s=Math.sin(i_radian);\r
+               double c=Math.cos(i_radian);\r
+               this.identity();\r
+               this.m11=c;\r
+               this.m12=-s;\r
+               this.m21=s;\r
+               this.m22=c;\r
+               return;\r
+       }\r
+       /**\r
+        * 行列に、右手系のY軸回転を設定します。\r
+        * @param i_radian\r
+        */\r
+       public final void setRotateY(double i_radian)\r
+       {\r
+               double s=Math.sin(i_radian);\r
+               double c=Math.cos(i_radian);\r
+               this.identity();\r
+               this.m00=c;\r
+               this.m02=s;\r
+               this.m20=-s;\r
+               this.m22=c;\r
+       }       \r
+       /**\r
+        * 行列に、右手系のZ軸回転を設定します。\r
+        * @param i_radian\r
+        */\r
+       public final void setRotateZ(double i_radian)\r
+       {\r
+               double s=Math.sin(i_radian);\r
+               double c=Math.cos(i_radian);\r
+               this.identity();\r
+               this.m00=c;\r
+               this.m01=-s;\r
+               this.m10=s;\r
+               this.m11=c;\r
+               \r
+       }\r
+       /**\r
+        * 行列に、右手系の並行移動を設定します。\r
+        * @param i_radian\r
+        */\r
+       public final void setTranslate(double i_x,double i_y,double i_z)\r
+       {\r
+               this.identity();\r
+               this.m03=i_x;\r
+               this.m13=i_y;\r
+               this.m23=i_z;\r
+       }\r
+       /**\r
+        * この行列をX軸回転します。\r
+        * @param i_mat_r\r
+        */\r
+       public final void rotateX(double i_radian)\r
+       {\r
+               double s=Math.sin(i_radian);\r
+               double c=Math.cos(i_radian);\r
+               \r
+               double t1,t2;\r
+               t1=this.m01;t2=this.m02;\r
+               this.m01=t1*c + t2*s;\r
+               this.m02=t1*(-s) + t2*c;\r
+               t1=this.m11;t2=this.m12;\r
+               this.m11=t1*c + t2*s;\r
+               this.m12=t1*(-s) + t2*c;\r
+               t1=this.m21;t2=this.m22;\r
+               this.m21=t1*c + t2*s;\r
+               this.m22=t1*(-s) + t2*c;                \r
+               t1=this.m31;t2=this.m32;\r
+               this.m31=t1*c + t2*s;\r
+               this.m32=t1*(-s) + t2*c;\r
+       }\r
+       /**\r
+        * この行列をY軸回転します。\r
+        * @param i_mat_r\r
+        */\r
+       public final void rotateY(double i_radian)\r
+       {\r
+               double s=Math.sin(i_radian);\r
+               double c=Math.cos(i_radian);\r
+\r
+               double t1,t2;\r
+               t1=this.m00;t2=this.m02;\r
+               this.m00=t1*c + t2*(-s);\r
+               this.m02=t1*s + t2*c;\r
+               t1=this.m10;t2=this.m12;\r
+               this.m10=t1*c + t2*(-s);\r
+               this.m12=t1*s + t2*c;\r
+               t1=this.m20;t2=this.m22;\r
+               this.m20=t1*c + t2*(-s);\r
+               this.m22=t1*s + t2*c;\r
+               t1=this.m30;t2=this.m32;\r
+               this.m30=t1*c + t2*(-s);\r
+               this.m32=t1*s + t2*c;\r
+       }\r
+       /**\r
+        * この姿勢行列をZ軸回転します。\r
+        * @i_radian\r
+        */\r
+       public final void rotateZ(double i_radian)\r
+       {\r
+               double s=Math.sin(i_radian);\r
+               double c=Math.cos(i_radian);\r
+               \r
+               double t1,t2;\r
+               t1=this.m00;t2=this.m01;\r
+               this.m00=t1*c + t2*s;\r
+               this.m01=t1*(-s) + t2*c;\r
+\r
+               t1=this.m10;t2=this.m11;\r
+               this.m10=t1*c + t2*s;\r
+               this.m11=t1*(-s) + t2*c;\r
+\r
+               t1=this.m20;t2=this.m21;\r
+               this.m20=t1*c + t2*s;\r
+               this.m21=t1*(-s) + t2*c;\r
+\r
+               t1=this.m30;t2=this.m31;\r
+               this.m30=t1*c + t2*s;\r
+               this.m31=t1*(-s) + t2*c;\r
+               return;\r
+       }\r
+       /**\r
+        * この姿勢行列を右手系で平行移動します。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_z\r
+        */\r
+       public final void translate(double i_x,double i_y,double i_z)\r
+       {\r
+               this.m03=this.m00*i_x + this.m01*i_y + this.m02*i_z + this.m03;\r
+               this.m13=this.m10*i_x + this.m11*i_y + this.m12*i_z + this.m13;\r
+               this.m23=this.m20*i_x + this.m21*i_y + this.m22*i_z + this.m23;\r
+               this.m33=this.m30*i_x + this.m31*i_y + this.m32*i_z + this.m33;\r
+               return;\r
+       }\r
+       public static void main(String[] args)\r
+       {\r
+\r
+               try {\r
+                       NyARDoubleMatrix44 t1 = new NyARDoubleMatrix44();\r
+                       NyARDoubleMatrix44 t2 = new NyARDoubleMatrix44();\r
+                       NyARDoubleMatrix44 t3 = new NyARDoubleMatrix44();\r
+                       NyARDoubleMatrix44 t4 = new NyARDoubleMatrix44();\r
+                       t1.m00=Math.random()*100;\r
+                       t1.m01=Math.random()*100;\r
+                       t1.m02=Math.random()*100;\r
+                       t1.m03=Math.random()*100;\r
+                       t1.m10=Math.random()*100;\r
+                       t1.m11=Math.random()*100;\r
+                       t1.m12=Math.random()*100;\r
+                       t1.m13=Math.random()*100;\r
+                       t1.m20=Math.random()*100;\r
+                       t1.m21=Math.random()*100;\r
+                       t1.m22=Math.random()*100;\r
+                       t1.m23=Math.random()*100;\r
+                       t1.m30=Math.random()*100;\r
+                       t1.m31=Math.random()*100;\r
+                       t1.m32=Math.random()*100;\r
+                       t1.m33=Math.random()*100;\r
+                       t2.setValue(t1);\r
+                       t1.rotateZ(Math.PI*10/180);\r
+                       t4.setRotateZ(Math.PI*10/180);\r
+                       t3.mul(t2,t4);\r
+                       System.out.print("");\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }       \r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARIntPointStack.java b/lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARIntPointStack.java
new file mode 100644 (file)
index 0000000..a6c799f
--- /dev/null
@@ -0,0 +1,52 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.stack;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * NyARIntPoint2d型の可変長配列です。\r
+ *\r
+ */\r
+public class NyARIntPointStack extends NyARObjectStack<NyARIntPoint2d>\r
+{\r
+       public NyARIntPointStack(int i_length) throws NyARException\r
+       {\r
+               super.initInstance(i_length,NyARIntPoint2d.class);\r
+               return;\r
+       }\r
+       protected NyARIntPoint2d createElement()\r
+       {\r
+               return new NyARIntPoint2d();\r
+       }       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARIntRectStack.java b/lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARIntRectStack.java
new file mode 100644 (file)
index 0000000..449d9f9
--- /dev/null
@@ -0,0 +1,48 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.stack;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntRect;\r
+\r
+public class NyARIntRectStack extends NyARObjectStack<NyARIntRect>\r
+{\r
+       public NyARIntRectStack(int i_length) throws NyARException\r
+       {\r
+               super.initInstance(i_length,NyARIntRect.class);\r
+       }\r
+       protected NyARIntRect createElement()\r
+       {\r
+               return new NyARIntRect();\r
+       }\r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARObjectStack.java b/lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARObjectStack.java
new file mode 100644 (file)
index 0000000..84f0fe6
--- /dev/null
@@ -0,0 +1,156 @@
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.stack;\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+/**\r
+ * 可変長なオブジェクト配列です。\r
+ * 型Tのオブジェクト配列を所有し、アクセス方法を提供します。\r
+ */\r
+public class NyARObjectStack<T> extends NyARPointerStack<T>\r
+{\r
+\r
+       protected NyARObjectStack() throws NyARException\r
+       {\r
+               return;\r
+       }\r
+       /**\r
+        * パラメータが不要なインスタンスを作るためのinitInstance\r
+        * コンストラクタから呼び出します。この関数を使うときには、 createElement()をオーバライドしてください。\r
+        * @param i_length\r
+        * @param i_element_type\r
+        * @param i_param\r
+        * @throws NyARException\r
+        */\r
+       protected void initInstance(int i_length,Class<T> i_element_type) throws NyARException\r
+       {\r
+               //領域確保\r
+               super.initInstance(i_length,i_element_type);\r
+               for (int i =0; i < i_length; i++){\r
+                       this._items[i] =createElement();\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * パラメータが必要なインスタンスを作るためのinitInstance\r
+        * コンストラクタから呼び出します。この関数を使うときには、 createElement(Object i_param)をオーバライドしてください。\r
+        * @param i_length\r
+        * @param i_element_type\r
+        * @param i_param\r
+        * @throws NyARException\r
+        */\r
+       protected void initInstance(int i_length,Class<T> i_element_type,Object i_param) throws NyARException\r
+       {\r
+               //領域確保\r
+               super.initInstance(i_length,i_element_type);\r
+               for (int i =0; i < i_length; i++){\r
+                       this._items[i] =createElement(i_param);\r
+               }\r
+               return;\r
+       }\r
+       protected T createElement() throws NyARException\r
+       {\r
+               throw new NyARException();\r
+       }\r
+       protected T createElement(Object i_param) throws NyARException\r
+       {\r
+               throw new NyARException();\r
+       }\r
+       \r
+       /**\r
+        * 新しい領域を予約します。\r
+        * @return\r
+        * 失敗するとnull\r
+        * @throws NyARException\r
+        */\r
+       public final T prePush()\r
+       {\r
+               // 必要に応じてアロケート\r
+               if (this._length >= this._items.length){\r
+                       return null;\r
+               }\r
+               // 使用領域を+1して、予約した領域を返す。\r
+               T ret = this._items[this._length];\r
+               this._length++;\r
+               return ret;\r
+       }\r
+       /**\r
+        * このクラスは、オブジェクトをpushすることはできません。\r
+        * prePush()を使用してください。\r
+        */\r
+       public T push(T i_object)\r
+       {\r
+               return null;\r
+       }\r
+       /**\r
+        * スタックを初期化します。\r
+        * @param i_reserv_length\r
+        * 使用済みにするサイズ\r
+        * @return\r
+        */\r
+       public final void init(int i_reserv_length) throws NyARException\r
+       {\r
+               // 必要に応じてアロケート\r
+               if (i_reserv_length >= this._items.length){\r
+                       throw new NyARException();\r
+               }\r
+               this._length=i_reserv_length;\r
+       }       \r
+       /**\r
+        * 指定した要素を削除します。\r
+        * 削除した要素は前方詰めで詰められます。\r
+        */\r
+       public final void remove(int i_index)\r
+       {\r
+               if(i_index!=this._length-1){\r
+                       T item=this._items[i_index];\r
+                       //要素をシフト\r
+                       super.remove(i_index);\r
+                       //外したオブジェクトを末端に取り付ける\r
+                       this._items[i_index]=item;\r
+               }\r
+               this._length--;\r
+       }\r
+       /**\r
+        * 指定した要素を順序を無視して削除します。\r
+        * 削除後のスタックの順序は保証されません。\r
+        * このAPIは、最後尾の有効要素と、削除対象の要素を交換することで、削除を実現します。\r
+        * @param i_index\r
+        */\r
+       public final void removeIgnoreOrder(int i_index)\r
+       {\r
+               assert(this._length>i_index && i_index>=0);\r
+               if(i_index!=this._length-1){\r
+                       //削除対象のオブジェクトを取り外す\r
+                       T item=this._items[i_index];\r
+                       //値の交換\r
+                       this._items[i_index]=this._items[this._length-1];\r
+                       this._items[this._length-1]=item;\r
+               }\r
+               this._length--;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARPointerStack.java b/lib/src/jp/nyatla/nyartoolkit/core/types/stack/NyARPointerStack.java
new file mode 100644 (file)
index 0000000..36fcf29
--- /dev/null
@@ -0,0 +1,154 @@
+package jp.nyatla.nyartoolkit.core.types.stack;\r
+\r
+import java.lang.reflect.Array;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * 実体をもたない可変長配列です。\r
+ * このクラスは実体化できません。継承して使います。\r
+ *\r
+ * @param <T>\r
+ */\r
+public class NyARPointerStack<T>\r
+{\r
+       protected T[] _items;\r
+       protected int _length;\r
+       \r
+       /**\r
+        * このクラスは実体化できません。\r
+        * @throws NyARException\r
+        */\r
+       protected NyARPointerStack() throws NyARException\r
+       {\r
+       }\r
+\r
+       /**\r
+        * スタックのメンバ変数を初期化します。この関数は、このクラスを継承したクラスを公開するときに、コンストラクタから呼び出します。\r
+        * @param i_length\r
+        * @param i_element_type\r
+        * @throws NyARException\r
+        */\r
+       @SuppressWarnings("unchecked")\r
+       protected void initInstance(int i_length,Class<T> i_element_type) throws NyARException\r
+       {\r
+               //領域確保\r
+               this._items = (T[])Array.newInstance(i_element_type, i_length);\r
+               //使用中個数をリセット\r
+               this._length = 0;\r
+               return;         \r
+       }\r
+\r
+       /**\r
+        * スタックに参照を積みます。\r
+        * @return\r
+        * 失敗するとnull\r
+        */\r
+       public T push(T i_object)\r
+       {\r
+               // 必要に応じてアロケート\r
+               if (this._length >= this._items.length){\r
+                       return null;\r
+               }\r
+               // 使用領域を+1して、予約した領域を返す。\r
+               this._items[this._length]=i_object;\r
+               this._length++;\r
+               return i_object;\r
+       }\r
+       /**\r
+        * スタックに参照を積みます。pushとの違いは、失敗した場合にassertすることです。\r
+        * @param i_object\r
+        * @return\r
+        */\r
+       public T pushAssert(T i_object)\r
+       {\r
+               // 必要に応じてアロケート\r
+               assert(this._length < this._items.length);\r
+               // 使用領域を+1して、予約した領域を返す。\r
+               this._items[this._length]=i_object;\r
+               this._length++;\r
+               return i_object;\r
+       }\r
+       \r
+       /** \r
+        * 見かけ上の要素数を1減らして、そのオブジェクトを返します。\r
+        * @return\r
+        */\r
+       public T pop()\r
+       {\r
+               assert(this._length>=1);\r
+               this._length--;\r
+               return this._items[this._length];\r
+       }\r
+       /**\r
+        * 見かけ上の要素数をi_count個減らします。\r
+        * @param i_count\r
+        * @return\r
+        */\r
+       public final void pops(int i_count)\r
+       {\r
+               assert(this._length>=i_count);\r
+               this._length-=i_count;\r
+               return;\r
+       }       \r
+       /**\r
+        * 配列を返します。\r
+        * \r
+        * @return\r
+        */\r
+       public final T[] getArray()\r
+       {\r
+               return this._items;\r
+       }\r
+       public final T getItem(int i_index)\r
+       {\r
+               return this._items[i_index];\r
+       }\r
+       /**\r
+        * 配列の見かけ上の要素数を返却します。\r
+        * @return\r
+        */\r
+       public final int getLength()\r
+       {\r
+               return this._length;\r
+       }\r
+       /**\r
+        * 指定した要素を削除します。\r
+        * 削除した要素は前方詰めで詰められます。\r
+        */\r
+       public void remove(int i_index)\r
+       {\r
+               assert(this._length>i_index && i_index>=0);\r
+               \r
+               if(i_index!=this._length-1){\r
+                       int i;\r
+                       final int len=this._length-1;\r
+                       T[] items=this._items;\r
+                       for(i=i_index;i<len;i++)\r
+                       {\r
+                               items[i]=items[i+1];\r
+                       }\r
+               }\r
+               this._length--;\r
+       }\r
+       /**\r
+        * 指定した要素を順序を無視して削除します。\r
+        * @param i_index\r
+        */\r
+       public void removeIgnoreOrder(int i_index)\r
+       {\r
+               assert(this._length>i_index && i_index>=0);\r
+               //値の交換\r
+               if(i_index!=this._length-1){\r
+                       this._items[i_index]=this._items[this._length-1];\r
+               }\r
+               this._length--;\r
+       }\r
+       /**\r
+        * 見かけ上の要素数をリセットします。\r
+        */\r
+       public void clear()\r
+       {\r
+               this._length = 0;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARDistMap.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARDistMap.java
new file mode 100644 (file)
index 0000000..a1ba3dd
--- /dev/null
@@ -0,0 +1,187 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * 2つの点集合同士を比較して、集合の各点同士の距離が最も近くになる組み合わせを計算\r
+ * するためのクラスです。\r
+ * 点集合の2次元距離マップを作成して、そこから最適な組み合わせを計算します。\r
+ */\r
+public class NyARDistMap\r
+{\r
+       protected class DistItem\r
+       {\r
+               public int row;\r
+               public int col;\r
+               public int dist;\r
+       }\r
+       protected DistItem[] _map;\r
+\r
+       protected int _min_dist;\r
+       protected int _min_dist_index;\r
+       protected int _size_row;\r
+       protected int _size_col;\r
+\r
+       public NyARDistMap(int i_max_col,int i_max_row)\r
+       {\r
+               this._min_dist=Integer.MAX_VALUE;\r
+               this._min_dist_index=0;\r
+               this._size_col=i_max_col;\r
+               this._size_row=i_max_row;\r
+               this._map=new DistItem[i_max_col*i_max_row];\r
+               for(int i=0;i<i_max_col*i_max_row;i++){\r
+                       this._map[i]=new DistItem();\r
+               }\r
+       }\r
+       /**\r
+        * マップのサイズを再設定します。内容は不定になり、距離マップの再設定が必要です。\r
+        * @param i_col\r
+        * 列数\r
+        * @param i_row\r
+        */\r
+       public void setMapSize(int i_col,int i_row)\r
+       {\r
+               this._size_row=i_row;\r
+               this._size_col=i_col;\r
+       }\r
+       /**\r
+        * 列と行を指定して、距離値をマップに値をセットします。\r
+        * このAPIは低速です。setPointsDistsを参考に、マップに直接距離値を置く関数を検討してください。\r
+        * @param i_col\r
+        * @param i_row\r
+        * @param i_dist\r
+        */\r
+       public void setDist(int i_col,int i_row,int i_dist)\r
+       {\r
+               this._min_dist_index=this._size_col*i_row+i_col;\r
+               DistItem item=this._map[this._min_dist_index];\r
+               item.col=i_col;\r
+               item.row=i_row;\r
+               item.dist=i_dist;\r
+               //最小値・最大値の再計算\r
+               if(i_dist<this._min_dist){\r
+                       this._min_dist=i_dist;\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * 2つの点集合同士の距離を計算して、距離マップに値をセットします。\r
+        * 点の座標が他の表現で実装されている場合は、この関数をオーバーロードして実装してください。\r
+        * @param i_vertex_r\r
+        * @param i_row_len\r
+        * @param i_vertex_c\r
+        * @param i_col_len\r
+        * @param o_rowindex\r
+        */\r
+       public void setPointDists(NyARIntPoint2d[] i_vertex_r,int i_row_len,NyARIntPoint2d[] i_vertex_c,int i_col_len)\r
+       {\r
+               DistItem[] map=this._map;\r
+               //distortionMapを作成。ついでに最小値のインデクスも取得\r
+               int min_index=0;\r
+               int min_dist =Integer.MAX_VALUE;\r
+               int idx=0;\r
+               for(int r=0;r<i_row_len;r++){\r
+                       for(int c=0;c<i_col_len;c++){\r
+                               map[idx].col=c;\r
+                               map[idx].row=r;\r
+                               int d=i_vertex_r[r].sqDist(i_vertex_c[c]);\r
+                               map[idx].dist=d;\r
+                               if(min_dist>d){\r
+                                       min_index=idx;\r
+                                       min_dist=d;\r
+                               }\r
+                               idx++;\r
+                       }\r
+               }\r
+               this._min_dist=min_dist;\r
+               this._min_dist_index=min_index;\r
+               this._size_col=i_col_len;\r
+               this._size_row=i_row_len;\r
+               return;\r
+       }\r
+       /**\r
+        * 現在の距離マップから、colに対するrowの組み合わせを計算します。\r
+        * colに対して最適なものが無い場合は、o_rowindexの値に-1がセットされます。\r
+        * この関数は内部データを不可逆に変更します。計算後は、距離マップの再セットが必要です。\r
+        * @param o_rowindex\r
+        */\r
+       public void getMinimumPair(int[] o_rowindex)\r
+       {\r
+               DistItem[] map=this._map;\r
+               int map_length=this._size_col*this._size_row;\r
+               int col_len=this._size_col;\r
+               //[0]と差し替え\r
+               DistItem temp_map;\r
+               temp_map=map[0];\r
+               map[0]=map[this._min_dist_index];\r
+               map[this._min_dist_index]=temp_map;\r
+               for(int i=0;i<o_rowindex.length;i++){\r
+                       o_rowindex[i]=-1;\r
+               }\r
+               if(map_length==0){\r
+                       return;\r
+               }\r
+               //値の保管\r
+               o_rowindex[map[0].col]=map[0].row;\r
+               \r
+               //ソートして、0番目以降のデータを探す\r
+               for(int i=1;i<col_len;i++){\r
+                       int min_index=0;\r
+                       //r,cのものを除外しながら最小値を得る。\r
+                       int reject_c=map[i-1].col;\r
+                       int reject_r=map[i-1].row;\r
+                       int min_dist=Integer.MAX_VALUE;\r
+                       if(1>=map_length-col_len){\r
+                               break;\r
+                       }\r
+                       for(int i2=i;i2<map_length;){\r
+                               //除外条件?\r
+                               if(map[i2].col==reject_c || map[i2].row==reject_r){\r
+                                       //非検索対象→インスタンスの差し替えと、検索長の減算\r
+                                       temp_map=map[i2];\r
+                                       map[i2]=map[map_length-1];\r
+                                       map[map_length-1]=temp_map;\r
+                                       map_length--;\r
+                               }else{\r
+                                       int d=map[i2].dist;\r
+                                       if(min_dist>d){\r
+                                               min_index=i2;\r
+                                               min_dist=d;\r
+                                       }\r
+                                       i2++;\r
+                               }\r
+                       }\r
+                       //[i]の値の差し替え\r
+                       temp_map=map[i];\r
+                       map[i]=map[min_index];\r
+                       map[min_index]=temp_map;\r
+                       //値の保管\r
+                       o_rowindex[map[i].col]=map[i].row;\r
+               }\r
+               return;         \r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyAREquationSolver.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyAREquationSolver.java
new file mode 100644 (file)
index 0000000..6e8c111
--- /dev/null
@@ -0,0 +1,302 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import jp.nyatla.nyartoolkit.*;\r
+/**\r
+ * 方程式を解く関数を定義します。\r
+ *\r
+ */\r
+public class NyAREquationSolver\r
+{\r
+       public static int solve2Equation(double i_a, double i_b, double i_c,double[] o_result)\r
+       {\r
+               assert i_a!=0;\r
+               return solve2Equation(i_b/i_a,i_c/i_a,o_result,0);\r
+       }\r
+       \r
+       public static int solve2Equation(double i_b, double i_c,double[] o_result)\r
+       {\r
+               return solve2Equation(i_b,i_c,o_result,0);\r
+       }\r
+       \r
+       public static int solve2Equation(double i_b, double i_c,double[] o_result,int i_result_st)\r
+       {\r
+               double t=i_b*i_b-4*i_c;\r
+               if(t<0){\r
+                       //虚数根\r
+                       return 0;\r
+               }\r
+               if(t==0){\r
+                       //重根\r
+                       o_result[i_result_st+0]=-i_b/(2);\r
+                       return 1;\r
+               }\r
+               //実根2個\r
+               t=Math.sqrt(t);\r
+               o_result[i_result_st+0]=(-i_b+t)/(2);\r
+               o_result[i_result_st+1]=(-i_b-t)/(2);\r
+               return 2;\r
+       }\r
+\r
+       /**\r
+        * 3次方程式 a*x^3+b*x^2+c*x+d=0の実根を求める。   \r
+        * http://aoki2.si.gunma-u.ac.jp/JavaScript/src/3jisiki.html\r
+        * のコードを基にしてます。\r
+        * @param i_a\r
+        * X^3の係数\r
+        * @param i_b\r
+        * X^2の係数\r
+        * @param i_c\r
+        * X^1の係数\r
+        * @param i_d\r
+        * X^0の係数\r
+        * @param o_result\r
+        * 実根。double[3]を指定すること。\r
+        * @return\r
+        */\r
+       public static int solve3Equation(double i_a, double i_b, double i_c, double i_d,double[] o_result)\r
+       {\r
+               assert (i_a != 0);\r
+               return solve3Equation(i_b/i_a,i_c/i_a,i_d/i_a,o_result);\r
+       }\r
+       \r
+       /**\r
+        * 3次方程式 x^3+b*x^2+c*x+d=0の実根を求める。\r
+        * だけを求める。\r
+        * http://aoki2.si.gunma-u.ac.jp/JavaScript/src/3jisiki.html\r
+        * のコードを基にしてます。\r
+        * @param i_b\r
+        * X^2の係数\r
+        * @param i_c\r
+        * X^1の係数\r
+        * @param i_d\r
+        * X^0の係数\r
+        * @param o_result\r
+        * 実根。double[1]以上を指定すること。\r
+        * @return\r
+        */\r
+       public static int solve3Equation(double i_b, double i_c, double i_d,double[] o_result)\r
+       {\r
+               double tmp,b,   p, q;\r
+               b = i_b/(3);\r
+               p = b * b - i_c / 3;\r
+               q = (b * (i_c - 2 * b * b) - i_d) / 2;\r
+               if ((tmp = q * q - p * p * p) == 0) {\r
+                       // 重根\r
+                       q = Math.cbrt(q);\r
+                       o_result[0] = 2 * q - b;\r
+                       o_result[1] = -q - b;\r
+                       return 2;\r
+               } else if (tmp > 0) {\r
+                       // 実根1,虚根2\r
+                       double a3 = Math.cbrt(q + ((q > 0) ? 1 : -1) * Math.sqrt(tmp));\r
+                       double b3 = p / a3;\r
+                       o_result[0] = a3 + b3 - b;\r
+                       // 虚根:-0.5*(a3+b3)-b,Math.abs(a3-b3)*Math.sqrt(3.0)/2\r
+                       return 1;\r
+               } else {\r
+                       // 実根3\r
+                       tmp = 2 * Math.sqrt(p);\r
+                       double t = Math.acos(q / (p * tmp / 2));\r
+                       o_result[0] = tmp * Math.cos(t / 3) - b;\r
+                       o_result[1] = tmp * Math.cos((t + 2 * Math.PI) / 3) - b;\r
+                       o_result[2] = tmp * Math.cos((t + 4 * Math.PI) / 3) - b;\r
+                       return 3;\r
+               }\r
+       }\r
+\r
+       \r
+       \r
+       /**\r
+        * 4次方程式の実根だけを求める。\r
+        * @param i_a\r
+        * X^3の係数\r
+        * @param i_b\r
+        * X^2の係数\r
+        * @param i_c\r
+        * X^1の係数\r
+        * @param i_d\r
+        * X^0の係数\r
+        * @param o_result\r
+        * 実根。double[3]を指定すること。\r
+        * @return\r
+        */\r
+       public static int solve4Equation(double i_a, double i_b, double i_c, double i_d,double i_e,double[] o_result) throws NyARException\r
+       {\r
+               assert (i_a != 0);\r
+               double A3,A2,A1,A0,B3;\r
+               A3=i_b/i_a;\r
+               A2=i_c/i_a;\r
+               A1=i_d/i_a;\r
+               A0=i_e/i_a;\r
+               B3=A3/4;\r
+               double p,q,r;\r
+               double B3_2=B3*B3;\r
+               p=A2-6*B3_2;//A2-6*B3*B3;\r
+               q=A1+B3*(-2*A2+8*B3_2);//A1-2*A2*B3+8*B3*B3*B3;\r
+               r=A0+B3*(-A1+A2*B3)-3*B3_2*B3_2;//A0-A1*B3+A2*B3*B3-3*B3*B3*B3*B3;\r
+               if(q==0){\r
+                       double result_0,result_1;\r
+                       //複二次式\r
+                       int res=solve2Equation(p,r,o_result,0);\r
+                       switch(res){\r
+                       case 0:\r
+                               //全て虚数解\r
+                               return 0;\r
+                       case 1:\r
+                               //重根\r
+                               //解は0,1,2の何れか。\r
+                               result_0=o_result[0];\r
+                               if(result_0<0){\r
+                                       //全て虚数解\r
+                                       return 0;\r
+                               }\r
+                               //実根1個\r
+                               if(result_0==0){\r
+                                       //NC\r
+                                       o_result[0]=0-B3;\r
+                                       return 1;\r
+                               }\r
+                               //実根2個\r
+                               result_0=Math.sqrt(result_0);\r
+                               o_result[0]=result_0-B3;\r
+                               o_result[1]=-result_0-B3;\r
+                               return 2;\r
+                       case 2:\r
+                               //実根2個だからt==t2==0はありえない。(case1)\r
+                               //解は、0,2,4の何れか。\r
+                               result_0=o_result[0];\r
+                               result_1=o_result[1];\r
+                               int number_of_result=0;\r
+                               if(result_0>0){\r
+                                       //NC\r
+                                       result_0=Math.sqrt(result_0);\r
+                                       o_result[0]= result_0-B3;\r
+                                       o_result[1]=-result_0-B3;\r
+                                       number_of_result+=2;\r
+                               }\r
+                               if(result_1>0)\r
+                               {\r
+                                       //NC\r
+                                       result_1=Math.sqrt(result_1);\r
+                                       o_result[number_of_result+0]= result_1-B3;\r
+                                       o_result[number_of_result+1]=-result_1-B3;\r
+                                       number_of_result+=2;\r
+                               }\r
+                               return number_of_result;\r
+                       default:\r
+                               throw new NyARException();\r
+                       }\r
+               }else{\r
+                       //それ以外\r
+                       //最適化ポイント:\r
+                       //u^3  + (2*p)*u^2  +((- 4*r)+(p^2))*u -q^2= 0\r
+                       double u=solve3Equation_1((2*p),(- 4*r)+(p*p),-q*q);\r
+                       if(u<0){\r
+                               //全て虚数解\r
+                               return 0;\r
+                       }\r
+                       double ru=Math.sqrt(u);\r
+                       //2次方程式を解いてyを計算(最適化ポイント)\r
+                       int result_1st,result_2nd;\r
+                       result_1st=solve2Equation(-ru,(p+u)/2+ru*q/(2*u),o_result,0);\r
+                       //配列使い回しのために、変数に退避\r
+                       switch(result_1st){\r
+                       case 0:\r
+                               break;\r
+                       case 1:\r
+                               o_result[0]=o_result[0]-B3;\r
+                               break;\r
+                       case 2:\r
+                               o_result[0]=o_result[0]-B3;\r
+                               o_result[1]=o_result[1]-B3;\r
+                               break;\r
+                       default:\r
+                               throw new NyARException();\r
+                       }\r
+                       result_2nd=solve2Equation(ru,(p+u)/2-ru*q/(2*u),o_result,result_1st);\r
+                       //0,1番目に格納\r
+                       switch(result_2nd){\r
+                       case 0:\r
+                               break;\r
+                       case 1:\r
+                               o_result[result_1st+0]=o_result[result_1st+0]-B3;\r
+                               break;\r
+                       case 2:\r
+                               o_result[result_1st+0]=o_result[result_1st+0]-B3;\r
+                               o_result[result_1st+1]=o_result[result_1st+1]-B3;\r
+                               break;\r
+                       default:\r
+                               throw new NyARException();\r
+                       }\r
+                       return result_1st+result_2nd;\r
+               }\r
+       }\r
+       /**\r
+        * 3次方程式の実根を1個だけ求める。\r
+        * 4字方程式で使う。\r
+        * @param i_b\r
+        * @param i_c\r
+        * @param i_d\r
+        * @param o_result\r
+        * @return\r
+        */\r
+       private static double solve3Equation_1(double i_b, double i_c, double i_d)\r
+       {\r
+               double tmp,b,   p, q;\r
+               b = i_b/(3);\r
+               p = b * b - i_c / 3;\r
+               q = (b * (i_c - 2 * b * b) - i_d) / 2;\r
+               if ((tmp = q * q - p * p * p) == 0) {\r
+                       // 重根\r
+                       q = Math.cbrt(q);\r
+                       return 2 * q - b;\r
+               } else if (tmp > 0) {\r
+                       // 実根1,虚根2\r
+                       double a3 = Math.cbrt(q + ((q > 0) ? 1 : -1) * Math.sqrt(tmp));\r
+                       double b3 = p / a3;\r
+                       return a3 + b3 - b;\r
+               } else {\r
+                       // 実根3\r
+                       tmp = 2 * Math.sqrt(p);\r
+                       double t = Math.acos(q / (p * tmp / 2));\r
+                       return tmp * Math.cos(t / 3) - b;\r
+               }\r
+       }               \r
+/*\r
+       public static void main(String[] args)\r
+       {\r
+               NyAREquationSolver n = new NyAREquationSolver();\r
+               int l=0;\r
+               double[] r = new double[10];\r
+               try{\r
+                       l=n.solve4Equation(1, 9, -18, -68, 120, r);\r
+               }catch(Exception e){\r
+                       e.printStackTrace();\r
+               }\r
+               System.out.println(l);\r
+       }*/\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARManagedObject.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARManagedObject.java
new file mode 100644 (file)
index 0000000..6308a5d
--- /dev/null
@@ -0,0 +1,95 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+/**\r
+ * NyARManagedObjectPoolの要素クラスです。\r
+ *\r
+ */\r
+public class NyARManagedObject\r
+{\r
+       /**\r
+        * このインタフェイスは、NyARManagedObjectがPoolを操作するために使います。\r
+        */     \r
+       public interface INyARManagedObjectPoolOperater\r
+       {\r
+               public void deleteObject(NyARManagedObject i_object);   \r
+       }\r
+       /**\r
+        * オブジェクトの参照カウンタ\r
+        */\r
+       private int _count;\r
+       /**\r
+        * オブジェクトの解放関数へのポインタ\r
+        */\r
+       private INyARManagedObjectPoolOperater _pool_operater;\r
+       /**\r
+        * NyARManagedObjectPoolのcreateElement関数が呼び出すコンストラクタです。\r
+        * @param i_ref_pool_operator\r
+        * Pool操作の為のインタフェイス\r
+        */\r
+       protected NyARManagedObject(INyARManagedObjectPoolOperater i_ref_pool_operator)\r
+       {\r
+               this._count=0;\r
+               this._pool_operater=i_ref_pool_operator;\r
+       }\r
+       public final NyARManagedObject initObject()\r
+       {\r
+               assert(this._count==0);\r
+               this._count=1;\r
+               return this;\r
+       }\r
+       /**\r
+        * このオブジェクトに対する、新しい参照オブジェクトを返します。\r
+        * @return\r
+        */\r
+       public final NyARManagedObject refObject()\r
+       {\r
+               assert(this._count>0);\r
+               this._count++;\r
+               return this;\r
+       }\r
+       /**\r
+        * 参照オブジェクトを開放します。\r
+        * @return\r
+        */\r
+       public int releaseObject()\r
+       {\r
+               assert(this._count>0);\r
+               this._count--;\r
+               if(this._count==0){\r
+                       this._pool_operater.deleteObject(this);\r
+               }\r
+               return this._count;\r
+       }\r
+       /**\r
+        * 現在の参照カウンタを返します。\r
+        * @return\r
+        */\r
+       public final int getCount()\r
+       {\r
+               return this._count;\r
+       }\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARManagedObjectPool.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARManagedObjectPool.java
new file mode 100644 (file)
index 0000000..19314e8
--- /dev/null
@@ -0,0 +1,118 @@
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import java.lang.reflect.Array;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * 参照カウンタ付きのobjectPoolです。NyARManagedObjectから派生したオブジェクトを管理します。\r
+ * このクラスは、参照カウンタ付きのオブジェクト型Tのオブジェクトプールを実現します。\r
+ * \r
+ * このクラスは、NyARManagedObjectと密接に関連して動作することに注意してください。\r
+ * 要素の作成関数はこのクラスで公開しますが、要素の解放関数は要素側に公開します。\r
+ * @param <T>\r
+ */\r
+public class NyARManagedObjectPool<T extends NyARManagedObject>\r
+{\r
+       /**\r
+        * Javaの都合でバッファを所有させていますが、別にこの形で実装しなくてもかまいません。\r
+        */\r
+       public class Operator implements NyARManagedObject.INyARManagedObjectPoolOperater\r
+       {\r
+               public NyARManagedObject[] _buffer;\r
+               public NyARManagedObject[] _pool;\r
+               public int _pool_stock;\r
+               public void deleteObject(NyARManagedObject i_object)\r
+               {\r
+                       assert(i_object!=null);\r
+                       assert(this._pool_stock<this._pool.length);\r
+                       this._pool[this._pool_stock]=i_object;\r
+                       this._pool_stock++;\r
+               }\r
+       }\r
+       /**\r
+        * 公開するオペレータオブジェクトです。\r
+        * このプールに所属する要素以外からは参照しないでください。\r
+        */\r
+       public Operator _op_interface=new Operator();\r
+\r
+       /**\r
+        * プールから型Tのオブジェクトを割り当てて返します。\r
+        * @return\r
+        * 新しいオブジェクト\r
+        */\r
+       @SuppressWarnings("unchecked")\r
+       public T newObject() throws NyARException\r
+       {\r
+               Operator pool=this._op_interface;\r
+               if(pool._pool_stock<1){\r
+                       return null;\r
+               }\r
+               pool._pool_stock--;\r
+               //参照オブジェクトを作成して返す。\r
+               return (T)(pool._pool[pool._pool_stock].initObject());\r
+       }\r
+       /**\r
+        * 実体化の拒否の為に、コンストラクタを隠蔽します。\r
+        * 継承クラスを作成して、初期化処理を実装してください。\r
+        */\r
+       protected NyARManagedObjectPool()\r
+       {\r
+       }\r
+       /**\r
+        * オブジェクトを初期化します。この関数は、このクラスを継承したクラスを公開するときに、コンストラクタから呼び出します。\r
+        * @param i_length\r
+        * @param i_element_type\r
+        * @throws NyARException\r
+        */\r
+       @SuppressWarnings("unchecked")\r
+       protected void initInstance(int i_length,Class<T> i_element_type) throws NyARException\r
+       {\r
+               Operator pool=this._op_interface;\r
+               //領域確保\r
+               pool._buffer = (T[])Array.newInstance(i_element_type, i_length);\r
+               pool._pool = (T[])Array.newInstance(i_element_type, i_length);\r
+               //使用中個数をリセット\r
+               pool._pool_stock=i_length;\r
+               //オブジェクトを作成\r
+               for(int i=pool._pool.length-1;i>=0;i--)\r
+               {\r
+                       pool._buffer[i]=pool._pool[i]=createElement();\r
+               }\r
+               return;         \r
+       }\r
+\r
+       @SuppressWarnings("unchecked")\r
+       protected void initInstance(int i_length,Class<T> i_element_type,Object i_param) throws NyARException\r
+       {\r
+               Operator pool=this._op_interface;\r
+               //領域確保\r
+               pool._buffer = (T[])Array.newInstance(i_element_type, i_length);\r
+               pool._pool = (T[])Array.newInstance(i_element_type, i_length);\r
+               //使用中個数をリセット\r
+               pool._pool_stock=i_length;\r
+               //オブジェクトを作成\r
+               for(int i=pool._pool.length-1;i>=0;i--)\r
+               {\r
+                       pool._buffer[i]=pool._pool[i]=createElement(i_param);\r
+               }\r
+               return;         \r
+       }\r
+       /**\r
+        * オブジェクトを作成します。継承クラス内で、型Tのオブジェクトを作成して下さい。\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       protected T createElement() throws NyARException\r
+       {\r
+               throw new NyARException();\r
+       }\r
+       protected T createElement(Object i_param) throws NyARException\r
+       {\r
+               throw new NyARException();\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARMath.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARMath.java
new file mode 100644 (file)
index 0000000..7d70b83
--- /dev/null
@@ -0,0 +1,89 @@
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+\r
+/**\r
+ * 数学関数を定義します。\r
+ *\r
+ */\r
+public class NyARMath\r
+{\r
+       public final static int SQ_40=40*40;\r
+       public final static int SQ_20=20*20;\r
+       public final static int SQ_10=10*10;\r
+       public final static int SQ_8=8*8;\r
+       public final static int SQ_5=5*5;\r
+       public final static int SQ_2=2*2;\r
+\r
+       \r
+       public final static double COS_DEG_30=0.8660;\r
+       public final static double COS_DEG_25=0.9063;\r
+       public final static double COS_DEG_20=0.9396;\r
+       public final static double COS_DEG_15=0.9395;\r
+       public final static double COS_DEG_10=0.9848;\r
+       public final static double COS_DEG_8 =0.9902;\r
+       public final static double COS_DEG_5 =0.9961;\r
+       public static final double sqNorm(double i_p1x,double i_p1y,double i_p2x,double i_p2y)\r
+       {\r
+               double x,y;\r
+               x=i_p2x-i_p1x;\r
+               y=i_p2y-i_p1y;\r
+               return x*x+y*y;\r
+       }\r
+\r
+       \r
+       \r
+       public static final double dist(double i_x1,double i_y1,double i_x2,double i_y2)\r
+       {\r
+               return Math.sqrt(i_x1*i_y1+i_x2+i_y2);\r
+       }\r
+\r
+       \r
+       \r
+       \r
+       /**\r
+        * 3乗根を求められないシステムで、3乗根を求めます。\r
+        * http://aoki2.si.gunma-u.ac.jp/JavaScript/src/3jisiki.html\r
+        * @param i_in\r
+        * @return\r
+        */\r
+       public static double cubeRoot(double i_in)\r
+       {\r
+               double res = Math.pow(Math.abs(i_in), 1.0 / 3.0);\r
+               return (i_in >= 0) ? res : -res;\r
+       }\r
+       /**\r
+        * ユークリッドの互除法により、2変数の最大公約数を求める。\r
+        * http://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%BC%E3%82%AF%E3%83%AA%E3%83%83%E3%83%89%E3%81%AE%E4%BA%92%E9%99%A4%E6%B3%95\r
+        * @param i_x\r
+        * @param i_y\r
+        * @return\r
+        */\r
+       public static int gcd(int i_x,int i_y)\r
+       {\r
+               int x=i_x;\r
+               int y=i_y;\r
+           int r;\r
+           while (y != 0) {\r
+               r = x % y;\r
+               x = y;\r
+               y = r;\r
+           }\r
+           return x;\r
+       }\r
+//     /**\r
+//      * 格納値をベクトルとして、距離を返します。\r
+//      * @return\r
+//      */\r
+//     public static final double dist(NyARDoublePoint2d i_vec)\r
+//     {\r
+//             return Math.sqrt(i_vec.x*i_vec.x+i_vec.y+i_vec.y);\r
+//     }\r
+//     /**\r
+//      * 格納値をベクトルとして、距離を返します。\r
+//      * @return\r
+//      */\r
+//     public static final double dist(NyARDoublePoint3d i_vec)\r
+//     {\r
+//             return Math.sqrt(i_vec.x*i_vec.x+i_vec.y*i_vec.y+i_vec.z*i_vec.z);\r
+//     }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARObjectPool.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARObjectPool.java
new file mode 100644 (file)
index 0000000..0e53a4a
--- /dev/null
@@ -0,0 +1,108 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import java.lang.reflect.Array;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+/**\r
+ * このクラスは、型Tのオブジェクトプールを提供します。\r
+ *\r
+ * @param <T>\r
+ */\r
+public class NyARObjectPool<T extends Object>\r
+{\r
+       protected T[] _buffer;\r
+       protected T[] _pool;\r
+       protected int _pool_stock;\r
+\r
+       /**\r
+        * オブジェクトプールからオブジェクトを取り出します。\r
+        * @return\r
+        */\r
+       public T newObject()\r
+       {\r
+               if(this._pool_stock<1){\r
+                       return null;\r
+               }\r
+               this._pool_stock--;\r
+               return this._pool[this._pool_stock];\r
+               \r
+       }\r
+       /**\r
+        * オブジェクトプールへオブジェクトを返却します。\r
+        * @return\r
+        */\r
+       public void deleteObject(T i_object)\r
+       {\r
+               assert(i_object!=null);\r
+               assert(this._pool_stock<this._pool.length);\r
+               //自身の提供したオブジェクトかを確認するのは省略。\r
+               this._pool[this._pool_stock]=i_object;\r
+               this._pool_stock++;\r
+       }\r
+\r
+       /**\r
+        * このクラスは実体化できません。\r
+        * @throws NyARException\r
+        */\r
+       public NyARObjectPool() throws NyARException\r
+       {\r
+       }\r
+       /**\r
+        * オブジェクトを初期化します。この関数は、このクラスを継承したクラスを公開するときに、コンストラクタから呼び出します。\r
+        * @param i_length\r
+        * @param i_element_type\r
+        * @throws NyARException\r
+        */\r
+       @SuppressWarnings("unchecked")\r
+       protected void initInstance(int i_length,Class<T> i_element_type) throws NyARException\r
+       {\r
+               //領域確保\r
+               this._buffer = (T[])Array.newInstance(i_element_type, i_length);\r
+               this._pool = (T[])Array.newInstance(i_element_type, i_length);\r
+               //使用中個数をリセット\r
+               this._pool_stock=i_length;\r
+               //オブジェクトを作成\r
+               for(int i=this._pool.length-1;i>=0;i--)\r
+               {\r
+                       this._buffer[i]=this._pool[i]=createElement();\r
+               }\r
+               return;         \r
+       }\r
+       /**\r
+        * オブジェクトを作成します。\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       protected T createElement() throws NyARException\r
+       {\r
+               throw new NyARException();\r
+       }\r
+       \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator.java
new file mode 100644 (file)
index 0000000..6909f03
--- /dev/null
@@ -0,0 +1,138 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 遠近法を用いたPerspectiveパラメータを計算するクラスのテンプレートです。\r
+ * 任意頂点四角系と矩形から、遠近法の変形パラメータを計算します。\r
+ * このクラスはリファレンス実装のため、パフォーマンスが良くありません。実際にはNyARPerspectiveParamGenerator_O1を使ってください。\r
+ */\r
+public abstract class NyARPerspectiveParamGenerator\r
+{\r
+       protected int _local_x;\r
+       protected int _local_y;\r
+       /**\r
+        * コンストラクタです。\r
+        * @param i_local_x\r
+        * パラメータ計算の基準点を指定します。\r
+        * @param i_local_y\r
+        * パラメータ計算の基準点を指定します。\r
+        */\r
+       public NyARPerspectiveParamGenerator(int i_local_x,int i_local_y)\r
+       {\r
+               this._local_x=i_local_x;\r
+               this._local_y=i_local_y;\r
+               return;\r
+       }\r
+       /**\r
+        * 遠近法のパラメータを計算します。\r
+        * @param i_size\r
+        * 変換先の矩形のサイズを指定します。\r
+        * @param i_vertex\r
+        * 変換元の頂点を指定します。要素数は4でなければなりません。\r
+        * @param o_param\r
+        * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。\r
+        * @return\r
+        * 成功するとtrueを返します。\r
+        * @throws NyARException\r
+        */\r
+       public final boolean getParam(NyARIntSize i_size,NyARIntPoint2d[] i_vertex,double[] o_param)throws NyARException\r
+       {\r
+               assert(i_vertex.length==4);\r
+               return this.getParam(i_size.w,i_size.h,i_vertex[0].x,i_vertex[0].y,i_vertex[1].x,i_vertex[1].y,i_vertex[2].x,i_vertex[2].y,i_vertex[3].x,i_vertex[3].y, o_param);\r
+       }\r
+       /**\r
+        * 遠近法のパラメータを計算します。\r
+        * @param i_size\r
+        * 変換先の矩形のサイズを指定します。\r
+        * @param i_vertex\r
+        * 変換元の頂点を指定します。要素数は4でなければなりません。\r
+        * @param o_param\r
+        * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。\r
+        * @return\r
+        * 成功するとtrueを返します。\r
+        * @throws NyARException\r
+        */\r
+       public final boolean getParam(NyARIntSize i_size,NyARDoublePoint2d[] i_vertex,double[] o_param)throws NyARException\r
+       {\r
+               return this.getParam(i_size.w,i_size.h,i_vertex[0].x,i_vertex[0].y,i_vertex[1].x,i_vertex[1].y,i_vertex[2].x,i_vertex[2].y,i_vertex[3].x,i_vertex[3].y, o_param);\r
+       }\r
+       /**\r
+        * 遠近法のパラメータを計算します。\r
+        * @param i_width\r
+        * 変換先の矩形のサイズを指定します。\r
+        * @param i_height\r
+        * 変換先の矩形のサイズを指定します。\r
+        * @param i_vertex\r
+        * 変換元の頂点を指定します。要素数は4でなければなりません。\r
+        * @param o_param\r
+        * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。\r
+        * @return\r
+        * 成功するとtrueを返します。\r
+        * @throws NyARException\r
+        */\r
+       public final boolean getParam(int i_width,int i_height,NyARDoublePoint2d[] i_vertex,double[] o_param)throws NyARException\r
+       {\r
+               return this.getParam(i_width,i_height,i_vertex[0].x,i_vertex[0].y,i_vertex[1].x,i_vertex[1].y,i_vertex[2].x,i_vertex[2].y,i_vertex[3].x,i_vertex[3].y, o_param);\r
+       }\r
+       /**\r
+        * 遠近法のパラメータを計算します。\r
+        * @param i_width\r
+        * 変換先の矩形のサイズを指定します。\r
+        * @param i_height\r
+        * 変換先の矩形のサイズを指定します。\r
+        * @param i_vertex\r
+        * 変換元の頂点を指定します。要素数は4でなければなりません。\r
+        * @param o_param\r
+        * 射影変換パラメータの出力インスタンスを指定します。要素数は8でなければなりません。\r
+        * @return\r
+        * 成功するとtrueを返します。\r
+        * @throws NyARException\r
+        */\r
+       public final boolean getParam(int i_width,int i_height,NyARIntPoint2d[] i_vertex,double[] o_param)throws NyARException\r
+       {\r
+               return this.getParam(i_width,i_height,i_vertex[0].x,i_vertex[0].y,i_vertex[1].x,i_vertex[1].y,i_vertex[2].x,i_vertex[2].y,i_vertex[3].x,i_vertex[3].y, o_param);\r
+       }\r
+       /**\r
+        * 遠近法のパラメータを計算します。継承クラスで実装してください。\r
+        * @param i_dest_w\r
+        * @param i_dest_h\r
+        * @param x1\r
+        * @param y1\r
+        * @param x2\r
+        * @param y2\r
+        * @param x3\r
+        * @param y3\r
+        * @param x4\r
+        * @param y4\r
+        * @param o_param\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public abstract boolean getParam(int i_dest_w,int i_dest_h,double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4,double[] o_param)throws NyARException;\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator_O1.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator_O1.java
new file mode 100644 (file)
index 0000000..f3dd52f
--- /dev/null
@@ -0,0 +1,233 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+/**\r
+ * NyARPerspectiveParamGeneratorを最適化したクラスです。\r
+ */\r
+public class NyARPerspectiveParamGenerator_O1 extends NyARPerspectiveParamGenerator\r
+{\r
+       /**\r
+        * コンストラクタです。\r
+        * @param i_local_x\r
+        * パラメータ計算の基準点を指定します。\r
+        * @param i_local_y\r
+        * パラメータ計算の基準点を指定します。\r
+        */\r
+       public NyARPerspectiveParamGenerator_O1(int i_local_x, int i_local_y)\r
+       {\r
+               super(i_local_x,i_local_y);\r
+               return;\r
+       }\r
+\r
+       \r
+       public final boolean getParam(int i_dest_w,int i_dest_h,double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4,double[] o_param)throws NyARException\r
+       {\r
+               double ltx=this._local_x;\r
+               double lty=this._local_y;\r
+               double rbx=ltx+i_dest_w;\r
+               double rby=lty+i_dest_h;\r
+               double det_1;\r
+               double a13, a14, a23, a24, a33, a34, a43, a44;\r
+               double b11, b12, b13, b14, b21, b22, b23, b24, b31, b32, b33, b34, b41, b42, b43, b44;\r
+               double t1, t2, t3, t4, t5, t6;\r
+               double kx0, kx1, kx2, kx3, kx4, kx5, kx6, kx7;\r
+               double ky0, ky1, ky2, ky3, ky4, ky5, ky6, ky7;\r
+               {\r
+                       a13 = -ltx * x1;\r
+                       a14 = -lty * x1;\r
+                       a23 = -rbx * x2;\r
+                       a24 = -lty * x2;\r
+                       a33 = -rbx * x3;\r
+                       a34 = -rby * x3;\r
+                       a43 = -ltx * x4;\r
+                       a44 = -rby * x4;\r
+\r
+                       t1 = a33 * a44 - a34 * a43;\r
+                       t4 = a34 * ltx - rbx * a44;\r
+                       t5 = rbx * a43 - a33 * ltx;\r
+                       t2 = rby * (a34 - a44);\r
+                       t3 = rby * (a43 - a33);\r
+                       t6 = rby * (rbx - ltx);\r
+\r
+                       b21 = -a23 * t4 - a24 * t5 - rbx * t1;\r
+                       b11 = (a23 * t2 + a24 * t3) + lty * t1;\r
+                       b31 = (a24 * t6 - rbx * t2) + lty * t4;\r
+                       b41 = (-rbx * t3 - a23 * t6) + lty * t5;\r
+\r
+                       t1 = a43 * a14 - a44 * a13;\r
+                       t2 = a44 * lty - rby * a14;\r
+                       t3 = rby * a13 - a43 * lty;\r
+                       t4 = ltx * (a44 - a14);\r
+                       t5 = ltx * (a13 - a43);\r
+                       t6 = ltx * (lty - rby);\r
+\r
+                       b12 = -rby * t1 - a33 * t2 - a34 * t3;\r
+                       b22 = (a33 * t4 + a34 * t5) + rbx * t1;\r
+                       b32 = (-a34 * t6 - rby * t4) + rbx * t2;\r
+                       b42 = (-rby * t5 + a33 * t6) + rbx * t3;\r
+\r
+                       t1 = a13 * a24 - a14 * a23;\r
+                       t4 = a14 * rbx - ltx * a24;\r
+                       t5 = ltx * a23 - a13 * rbx;\r
+                       t2 = lty * (a14 - a24);\r
+                       t3 = lty * (a23 - a13);\r
+                       t6 = lty * (ltx - rbx);\r
+\r
+                       b23 = -a43 * t4 - a44 * t5 - ltx * t1;\r
+                       b13 = (a43 * t2 + a44 * t3) + rby * t1;\r
+                       b33 = (a44 * t6 - ltx * t2) + rby * t4;\r
+                       b43 = (-ltx * t3 - a43 * t6) + rby * t5;\r
+\r
+                       t1 = a23 * a34 - a24 * a33;\r
+                       t2 = a24 * rby - lty * a34;\r
+                       t3 = lty * a33 - a23 * rby;\r
+                       t4 = rbx * (a24 - a34);\r
+                       t5 = rbx * (a33 - a23);\r
+                       t6 = rbx * (rby - lty);\r
+\r
+                       b14 = -lty * t1 - a13 * t2 - a14 * t3;\r
+                       b24 = a13 * t4 + a14 * t5 + ltx * t1;\r
+                       b34 = -a14 * t6 - lty * t4 + ltx * t2;\r
+                       b44 = -lty * t5 + a13 * t6 + ltx * t3;\r
+\r
+                       det_1 = (ltx * (b11 + b14) + rbx * (b12 + b13));\r
+                       if (det_1 == 0) {\r
+                               det_1=0.0001;\r
+                               //System.out.println("Could not get inverse matrix(1).");                                       \r
+                               //return false;\r
+                       }\r
+                       det_1 = 1 / det_1;\r
+\r
+                       kx0 = (b11 * x1 + b12 * x2 + b13 * x3 + b14 * x4) * det_1;\r
+                       kx1 = (b11 + b12 + b13 + b14) * det_1;\r
+                       kx2 = (b21 * x1 + b22 * x2 + b23 * x3 + b24 * x4) * det_1;\r
+                       kx3 = (b21 + b22 + b23 + b24) * det_1;\r
+                       kx4 = (b31 * x1 + b32 * x2 + b33 * x3 + b34 * x4) * det_1;\r
+                       kx5 = (b31 + b32 + b33 + b34) * det_1;\r
+                       kx6 = (b41 * x1 + b42 * x2 + b43 * x3 + b44 * x4) * det_1;\r
+                       kx7 = (b41 + b42 + b43 + b44) * det_1;\r
+               }\r
+               {\r
+                       a13 = -ltx * y1;\r
+                       a14 = -lty * y1;\r
+                       a23 = -rbx * y2;\r
+                       a24 = -lty * y2;\r
+                       a33 = -rbx * y3;\r
+                       a34 = -rby * y3;\r
+                       a43 = -ltx * y4;\r
+                       a44 = -rby * y4;\r
+\r
+                       t1 = a33 * a44 - a34 * a43;\r
+                       t4 = a34 * ltx - rbx * a44;\r
+                       t5 = rbx * a43 - a33 * ltx;\r
+                       t2 = rby * (a34 - a44);\r
+                       t3 = rby * (a43 - a33);\r
+                       t6 = rby * (rbx - ltx);\r
+\r
+                       b21 = -a23 * t4 - a24 * t5 - rbx * t1;\r
+                       b11 = (a23 * t2 + a24 * t3) + lty * t1;\r
+                       b31 = (a24 * t6 - rbx * t2) + lty * t4;\r
+                       b41 = (-rbx * t3 - a23 * t6) + lty * t5;\r
+\r
+                       t1 = a43 * a14 - a44 * a13;\r
+                       t2 = a44 * lty - rby * a14;\r
+                       t3 = rby * a13 - a43 * lty;\r
+                       t4 = ltx * (a44 - a14);\r
+                       t5 = ltx * (a13 - a43);\r
+                       t6 = ltx * (lty - rby);\r
+\r
+                       b12 = -rby * t1 - a33 * t2 - a34 * t3;\r
+                       b22 = (a33 * t4 + a34 * t5) + rbx * t1;\r
+                       b32 = (-a34 * t6 - rby * t4) + rbx * t2;\r
+                       b42 = (-rby * t5 + a33 * t6) + rbx * t3;\r
+\r
+                       t1 = a13 * a24 - a14 * a23;\r
+                       t4 = a14 * rbx - ltx * a24;\r
+                       t5 = ltx * a23 - a13 * rbx;\r
+                       t2 = lty * (a14 - a24);\r
+                       t3 = lty * (a23 - a13);\r
+                       t6 = lty * (ltx - rbx);\r
+\r
+                       b23 = -a43 * t4 - a44 * t5 - ltx * t1;\r
+                       b13 = (a43 * t2 + a44 * t3) + rby * t1;\r
+                       b33 = (a44 * t6 - ltx * t2) + rby * t4;\r
+                       b43 = (-ltx * t3 - a43 * t6) + rby * t5;\r
+\r
+                       t1 = a23 * a34 - a24 * a33;\r
+                       t2 = a24 * rby - lty * a34;\r
+                       t3 = lty * a33 - a23 * rby;\r
+                       t4 = rbx * (a24 - a34);\r
+                       t5 = rbx * (a33 - a23);\r
+                       t6 = rbx * (rby - lty);\r
+\r
+                       b14 = -lty * t1 - a13 * t2 - a14 * t3;\r
+                       b24 = a13 * t4 + a14 * t5 + ltx * t1;\r
+                       b34 = -a14 * t6 - lty * t4 + ltx * t2;\r
+                       b44 = -lty * t5 + a13 * t6 + ltx * t3;\r
+\r
+                       det_1 = (ltx * (b11 + b14) + rbx * (b12 + b13));\r
+                       if (det_1 == 0) {\r
+                               det_1=0.0001;\r
+                               //System.out.println("Could not get inverse matrix(2).");                               \r
+                               //return false;\r
+                       }\r
+                       det_1 = 1 / det_1;\r
+\r
+                       ky0 = (b11 * y1 + b12 * y2 + b13 * y3 + b14 * y4) * det_1;\r
+                       ky1 = (b11 + b12 + b13 + b14) * det_1;\r
+                       ky2 = (b21 * y1 + b22 * y2 + b23 * y3 + b24 * y4) * det_1;\r
+                       ky3 = (b21 + b22 + b23 + b24) * det_1;\r
+                       ky4 = (b31 * y1 + b32 * y2 + b33 * y3 + b34 * y4) * det_1;\r
+                       ky5 = (b31 + b32 + b33 + b34) * det_1;\r
+                       ky6 = (b41 * y1 + b42 * y2 + b43 * y3 + b44 * y4) * det_1;\r
+                       ky7 = (b41 + b42 + b43 + b44) * det_1;\r
+               }\r
+\r
+               det_1 = kx5 * (-ky7) - (-ky5) * kx7;\r
+               if (det_1 == 0) {\r
+                       det_1=0.0001;\r
+                       //System.out.println("Could not get inverse matrix(3).");\r
+                       //return false;\r
+               }\r
+               det_1 = 1 / det_1;\r
+\r
+               double C, F;\r
+               o_param[2] = C = (-ky7 * det_1) * (kx4 - ky4) + (ky5 * det_1) * (kx6 - ky6); // C\r
+               o_param[5] = F = (-kx7 * det_1) * (kx4 - ky4) + (kx5 * det_1) * (kx6 - ky6); // F\r
+               o_param[6] = kx4 - C * kx5;\r
+               o_param[7] = kx6 - C * kx7;\r
+               o_param[0] = kx0 - C * kx1;\r
+               o_param[1] = kx2 - C * kx3;\r
+               o_param[3] = ky0 - F * ky1;\r
+               o_param[4] = ky2 - F * ky3;\r
+               return true;\r
+       }\r
+\r
+\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator_Reference.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator_Reference.java
new file mode 100644 (file)
index 0000000..6943028
--- /dev/null
@@ -0,0 +1,112 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+\r
+/**\r
+ * 遠近法を用いたPerspectiveパラメータを計算するクラスです。\r
+ * 任意頂点四角系と矩形から、遠近法の変形パラメータを計算します。\r
+ * このクラスはリファレンス実装のため、パフォーマンスが良くありません。NyARPerspectiveParamGenerator_O1を使ってください。\r
+ */\r
+public class NyARPerspectiveParamGenerator_Reference extends NyARPerspectiveParamGenerator\r
+{\r
+       /**\r
+        * コンストラクタです。\r
+        * @param i_local_x\r
+        * パラメータ計算の基準点を指定します。\r
+        * @param i_local_y\r
+        * パラメータ計算の基準点を指定します。\r
+        */\r
+       public NyARPerspectiveParamGenerator_Reference(int i_local_x,int i_local_y)\r
+       {\r
+               super(i_local_x,i_local_y);\r
+               return;\r
+       }\r
+\r
+       \r
+       public final boolean getParam(int i_dest_w,int i_dest_h,double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4,double[] o_param)throws NyARException\r
+       {\r
+               double ltx=this._local_x;\r
+               double lty=this._local_y;\r
+               double rbx=ltx+i_dest_w;\r
+               double rby=lty+i_dest_h;                \r
+               \r
+               NyARDoubleMatrix44 mat_x=new NyARDoubleMatrix44();\r
+               mat_x.m00=ltx;  mat_x.m01=lty;  mat_x.m02=-ltx*x1;      mat_x.m03=-lty*x1;\r
+               mat_x.m10=rbx;  mat_x.m11=lty;  mat_x.m12=-rbx*x2;      mat_x.m13=-lty*x2;\r
+               mat_x.m20=rbx;  mat_x.m21=rby;  mat_x.m22=-rbx*x3;      mat_x.m23=-rby*x3;\r
+               mat_x.m30=ltx;  mat_x.m31=rby;  mat_x.m32=-ltx*x4;      mat_x.m33=-rby*x4;\r
+               mat_x.inverse(mat_x);\r
+               NyARDoubleMatrix44 mat_y=new NyARDoubleMatrix44();\r
+               mat_y.m00=ltx;  mat_y.m01=lty;  mat_y.m02=-ltx*y1;      mat_y.m03=-lty*y1;\r
+               mat_y.m10=rbx;  mat_y.m11=lty;  mat_y.m12=-rbx*y2;      mat_y.m13=-lty*y2;\r
+               mat_y.m20=rbx;  mat_y.m21=rby;  mat_y.m22=-rbx*y3;      mat_y.m23=-rby*y3;\r
+               mat_y.m30=ltx;  mat_y.m31=rby;  mat_y.m32=-ltx*y4;      mat_y.m33=-rby*y4;\r
+               mat_y.inverse(mat_y);\r
+               double a=mat_x.m20*x1+mat_x.m21*x2+mat_x.m22*x3+mat_x.m23*x4;\r
+               double b=mat_x.m20+mat_x.m21+mat_x.m22+mat_x.m23;\r
+               double d=mat_x.m30*x1+mat_x.m31*x2+mat_x.m32*x3+mat_x.m33*x4;\r
+               double f=mat_x.m30+mat_x.m31+mat_x.m32+mat_x.m33;\r
+               \r
+               double g=mat_y.m20*y1+mat_y.m21*y2+mat_y.m22*y3+mat_y.m23*y4;\r
+               double h=mat_y.m20+mat_y.m21+mat_y.m22+mat_y.m23;\r
+               double i=mat_y.m30*y1+mat_y.m31*y2+mat_y.m32*y3+mat_y.m33*y4;\r
+               double j=mat_y.m30+mat_y.m31+mat_y.m32+mat_y.m33;\r
+               \r
+               NyARDoubleMatrix22 tm=new NyARDoubleMatrix22();\r
+               tm.m00=b;\r
+               tm.m01=-h;\r
+               tm.m10=f;\r
+               tm.m11=-j;\r
+               tm.inverse(tm);\r
+\r
+               \r
+               double A,B,C,D,E,F,G,H;\r
+\r
+               C=tm.m00*(a-g)+tm.m01*(d-i);    //C\r
+               F=tm.m10*(a-g)+tm.m11*(d-i);    //F\r
+               G=a-C*b;\r
+               H=d-C*f;\r
+               A=(mat_x.m00*x1+mat_x.m01*x2+mat_x.m02*x3+mat_x.m03*x4)-C*(mat_x.m00+mat_x.m01+mat_x.m02+mat_x.m03);\r
+               B=(mat_x.m10*x1+mat_x.m11*x2+mat_x.m12*x3+mat_x.m13*x4)-C*(mat_x.m10+mat_x.m11+mat_x.m12+mat_x.m13);\r
+               D=(mat_y.m00*y1+mat_y.m01*y2+mat_y.m02*y3+mat_y.m03*y4)-F*(mat_y.m00+mat_y.m01+mat_y.m02+mat_y.m03);\r
+               E=(mat_y.m10*y1+mat_y.m11*y2+mat_y.m12*y3+mat_y.m13*y4)-F*(mat_y.m10+mat_y.m11+mat_y.m12+mat_y.m13);\r
+\r
+               o_param[0]=A;\r
+               o_param[1]=B;\r
+               o_param[2]=C;\r
+               o_param[3]=D;\r
+               o_param[4]=E;\r
+               o_param[5]=F;\r
+               o_param[6]=G;\r
+               o_param[7]=H;\r
+               \r
+\r
+               return true;\r
+\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARSystemOfLinearEquationsProcessor.java b/lib/src/jp/nyatla/nyartoolkit/core/utils/NyARSystemOfLinearEquationsProcessor.java
new file mode 100644 (file)
index 0000000..a4d840d
--- /dev/null
@@ -0,0 +1,143 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+/**\r
+ * 連立方程式を解くためのプロセッサクラスです。\r
+ *\r
+ */\r
+public class NyARSystemOfLinearEquationsProcessor\r
+{\r
+       /**\r
+        * i_reftとi_rightの整合性を確認します。\r
+        * @param i_left\r
+        * @param i_right\r
+        * @return\r
+        */\r
+       private static boolean isValid2dArray(double[][] i_left,double[] i_right)\r
+       {               \r
+               final int sm=i_left.length;\r
+               final int sn=i_left[0].length;\r
+               if(i_left.length!=sm){\r
+                       return false;\r
+               }\r
+               if(i_right.length!=sm){\r
+                       return false;\r
+               }\r
+               for(int i=1;i<sm;i++){\r
+                       if(i_left[i].length!=sn){\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * [i_left_src]=[i_right_src]の式にガウスの消去法を実行して、[x][x]の要素が1になるように基本変形します。\r
+        * i_mとi_nが等しくない時は、最終行までの[x][x]要素までを1になるように変形します。\r
+        * @param i_left\r
+        * 連立方程式の左辺値を指定します。[i_m][i_n]の配列を指定してください。\r
+        * @param i_right\r
+        * 連立方程式の右辺値を指定します。[i_m][i_n]の配列を指定してください。\r
+        * @param i_n\r
+        * 連立方程式の係数の数を指定します。\r
+        * @param i_m\r
+        * 連立方程式の数を指定します。\r
+        * @return\r
+        * 最終行まで基本変形ができてばtrueを返します。\r
+        */\r
+       public static boolean doGaussianElimination(double[][] i_left,double[] i_right,int i_n,int i_m)\r
+       {\r
+               //整合性を確認する.\r
+               assert isValid2dArray(i_left,i_right);\r
+               \r
+\r
+               //1行目以降\r
+               for(int solve_row=0;solve_row<i_m;solve_row++)\r
+               {\r
+                       {//ピボット操作\r
+                               int pivod=solve_row;\r
+                               double pivod_value=Math.abs(i_left[pivod][pivod]);\r
+                               for(int i=solve_row+1;i<i_m;i++){\r
+                                       final double pivod_2=Math.abs(i_left[i][pivod]);\r
+                                       if(pivod_value<Math.abs(pivod_2)){\r
+                                               pivod=i;\r
+                                               pivod_value=pivod_2;\r
+                                       }\r
+                               }\r
+                               if(solve_row!=pivod){\r
+                                       //行の入れ替え(Cの時はポインタテーブル使って!)\r
+                                       final double[] t=i_left[solve_row];\r
+                                       i_left[solve_row]=i_left[pivod];\r
+                                       i_left[pivod]=t;\r
+                                       final double t2=i_right[solve_row];\r
+                                       i_right[solve_row]=i_right[pivod];\r
+                                       i_right[pivod]=t2;\r
+                               }\r
+                       }\r
+                       final double[] dest_l_n=i_left[solve_row];\r
+                       final double dest_l_nn=i_left[solve_row][solve_row];\r
+                       if(dest_l_nn==0.0){\r
+                               //選択後の対角要素が0になってしまったら失敗する。\r
+                               return false;\r
+                       }                       \r
+\r
+                       //消去計算(0 - solve_row-1項までの消去)\r
+                       for(int i=0;i<solve_row;i++){\r
+                               double s=dest_l_n[i];\r
+                               for(int i2=0;i2<i_n;i2++)\r
+                               {\r
+                                       final double p=i_left[i][i2]*s;\r
+                                       dest_l_n[i2]=dest_l_n[i2]-p;\r
+                               }\r
+                               final double k=i_right[i]*s;\r
+                               i_right[solve_row]=i_right[solve_row]-k;\r
+                               \r
+                       }\r
+                       //消去法の実行(割り算)\r
+                       final double d=dest_l_n[solve_row];\r
+                       for(int i2=0;i2<solve_row;i2++){\r
+                               dest_l_n[i2]=0;\r
+                       }\r
+                       if(d!=1.0){\r
+                               dest_l_n[solve_row]=1.0;\r
+                               for(int i=solve_row+1;i<i_n;i++){\r
+                                       dest_l_n[i]/=d;\r
+                               }\r
+                               i_right[solve_row]/=d;\r
+                       }\r
+               }\r
+               return true;    \r
+       }\r
+       /**\r
+        * i_leftとi_rightの連立方程式を解いて、i_left,i_right内容を更新します。\r
+        * i_right[n]の内容が、i_left[x][n]番目の係数の解になります。\r
+        * @return\r
+        * 方程式が解ければtrueを返します。\r
+        */\r
+       public static boolean solve(double[][] i_left,double[] i_right,int i_number_of_system)\r
+       {\r
+               return doGaussianElimination(i_left,i_right,i_number_of_system,i_number_of_system);\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/detector/NyARCustomSingleDetectMarker.java b/lib/src/jp/nyatla/nyartoolkit/detector/NyARCustomSingleDetectMarker.java
new file mode 100644 (file)
index 0000000..62a6fb6
--- /dev/null
@@ -0,0 +1,253 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.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.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+\r
+\r
+\r
+/**\r
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
+ * 変換行列を求めるには、detectMarkerLite関数にラスタイメージを入力して、計算対象の矩形を特定します。\r
+ * detectMarkerLiteが成功すると、getTransmationMatrix等の関数が使用可能な状態になり、変換行列を求めることができます。\r
+ * \r
+ * \r
+ */\r
+public class NyARCustomSingleDetectMarker\r
+{\r
+       /** 一致率*/\r
+       private double _confidence;\r
+       private NyARSquare _square=new NyARSquare();\r
+       \r
+       //参照インスタンス\r
+       private INyARRgbRaster _ref_raster;\r
+       //所有インスタンス\r
+       private INyARColorPatt _inst_patt;\r
+       private NyARMatchPattDeviationColorData _deviation_data;\r
+       private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;\r
+       private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+       private NyARCoord2Linear _coordline;\r
+       \r
+\r
+       private NyARIntPoint2d[] __ref_vertex=new NyARIntPoint2d[4];\r
+\r
+       /**\r
+        * 矩形が見付かるたびに呼び出されます。\r
+        * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+        */\r
+       protected void updateSquareInfo(NyARIntCoordinates i_coord,int[] i_vertex_index) throws NyARException\r
+       {\r
+               NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+               //輪郭座標から頂点リストに変換\r
+               NyARIntPoint2d[] vertex=this.__ref_vertex;      //C言語ならポインタ扱いで実装\r
+               vertex[0]=i_coord.items[i_vertex_index[0]];\r
+               vertex[1]=i_coord.items[i_vertex_index[1]];\r
+               vertex[2]=i_coord.items[i_vertex_index[2]];\r
+               vertex[3]=i_coord.items[i_vertex_index[3]];\r
+       \r
+               //画像を取得\r
+               if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){\r
+                       return;\r
+               }\r
+               //取得パターンをカラー差分データに変換して評価する。\r
+               this._deviation_data.setRaster(this._inst_patt);\r
+               if(!this._match_patt.evaluate(this._deviation_data,mr)){\r
+                       return;\r
+               }\r
+               //現在の一致率より低ければ終了\r
+               if (this._confidence > mr.confidence){\r
+                       return;\r
+               }\r
+               //一致率の高い矩形があれば、方位を考慮して頂点情報を作成\r
+               NyARSquare sq=this._square;\r
+               this._confidence = mr.confidence;\r
+               //directionを考慮して、squareを更新する。\r
+               for(int i=0;i<4;i++){\r
+                       int idx=(i+4 - mr.direction) % 4;\r
+                       this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coord,sq.line[i]);\r
+               }\r
+               //ちょっと、ひっくり返してみようか。\r
+               for (int i = 0; i < 4; i++) {\r
+                       //直線同士の交点計算\r
+                       if(!sq.line[i].crossPos(sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+                               throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+                       }\r
+               }\r
+       }\r
+\r
+       \r
+       private boolean _is_continue = false;\r
+       private NyARSquareContourDetector _square_detect;\r
+       protected INyARTransMat _transmat;\r
+       //画処理用\r
+       private NyARBinRaster _bin_raster;\r
+       protected INyARRasterFilter_Rgb2Bin _tobin_filter;\r
+\r
+       private NyARRectOffset _offset; \r
+\r
+\r
+       protected NyARCustomSingleDetectMarker()\r
+       {\r
+               return;\r
+       }\r
+       protected void initInstance(\r
+               INyARColorPatt i_patt_inst,\r
+               NyARSquareContourDetector i_sqdetect_inst,\r
+               INyARTransMat i_transmat_inst,\r
+               INyARRasterFilter_Rgb2Bin i_filter,\r
+               NyARParam       i_ref_param,\r
+               NyARCode        i_ref_code,\r
+               double          i_marker_width) throws NyARException\r
+       {\r
+               final NyARIntSize scr_size=i_ref_param.getScreenSize();         \r
+               // 解析オブジェクトを作る\r
+               this._square_detect = i_sqdetect_inst;\r
+               this._transmat = i_transmat_inst;\r
+               this._tobin_filter=i_filter;\r
+               //2値画像バッファを作る\r
+               this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
+               //パターンの一致検索処理用\r
+               this._inst_patt=i_patt_inst;\r
+               this._deviation_data=new NyARMatchPattDeviationColorData(i_ref_code.getWidth(),i_ref_code.getHeight());\r
+               this._coordline=new NyARCoord2Linear(i_ref_param.getScreenSize(),i_ref_param.getDistortionFactor());\r
+               this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code);\r
+               //オフセットを作成\r
+               this._offset=new NyARRectOffset();\r
+               this._offset.setSquare(i_marker_width);\r
+               return;\r
+               \r
+       }\r
+\r
+       \r
+\r
+       \r
+       /**\r
+        * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+        * \r
+        * @param i_raster\r
+        * マーカーを検出するイメージを指定します。イメージサイズは、カメラパラメータ\r
+        * と一致していなければなりません。\r
+        * @return マーカーが検出できたかを真偽値で返します。\r
+        * @throws NyARException\r
+        */\r
+       public boolean detectMarkerLite(INyARRgbRaster i_raster) throws NyARException\r
+       {\r
+               //サイズチェック\r
+               if(!this._bin_raster.getSize().isEqualSize(i_raster.getSize())){\r
+                       throw new NyARException();\r
+               }\r
+\r
+               //ラスタを2値イメージに変換する.\r
+               this._tobin_filter.doFilter(i_raster,this._bin_raster);\r
+\r
+               //コールバックハンドラの準備\r
+               this._confidence=0;\r
+               this._ref_raster=i_raster;\r
+\r
+               //矩形を探す(戻り値はコールバック関数で受け取る。)\r
+               this._square_detect.detectMarker(this._bin_raster);\r
+               if(this._confidence==0){\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。\r
+        * 直前に実行したdetectMarkerLiteが成功していないと使えません。\r
+        * \r
+        * @param o_result\r
+        * 変換行列を受け取るオブジェクトを指定します。\r
+        * @throws NyARException\r
+        */\r
+       public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException\r
+       {\r
+               // 一番一致したマーカーの位置とかその辺を計算\r
+               if (this._is_continue) {\r
+                       this._transmat.transMatContinue(this._square,this._offset,o_result, o_result);\r
+               } else {\r
+                       this._transmat.transMat(this._square,this._offset, o_result);\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * 現在の矩形を返します。\r
+        * @return\r
+        */\r
+       public NyARSquare refSquare()\r
+       {\r
+               return this._square;\r
+       }\r
+       /**\r
+        * 検出したマーカーの一致度を返します。\r
+        * \r
+        * @return マーカーの一致度を返します。0~1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。\r
+        * @throws NyARException\r
+        */\r
+       public double getConfidence()\r
+       {\r
+               return this._confidence;\r
+       }\r
+       /**\r
+        * getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。\r
+        * \r
+        * @param i_is_continue\r
+        * TRUEなら、transMatCont互換の計算をします。 FALSEなら、transMat互換の計算をします。\r
+        */\r
+       public void setContinueMode(boolean i_is_continue)\r
+       {\r
+               this._is_continue = i_is_continue;\r
+       }\r
+       /**\r
+        * プローブ関数\r
+        * @return\r
+        */\r
+       public Object[] _getProbe()\r
+       {\r
+               Object[] r=new Object[1];\r
+               r[0]=this._inst_patt;\r
+               return r;\r
+       }       \r
+       \r
+       \r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/detector/NyARDetectMarker.java b/lib/src/jp/nyatla/nyartoolkit/detector/NyARDetectMarker.java
new file mode 100644 (file)
index 0000000..0743ac0
--- /dev/null
@@ -0,0 +1,324 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.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.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARCoord2Linear;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareContourDetector_Rle;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.stack.NyARObjectStack;\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * 複数のマーカーを検出し、それぞれに最も一致するARコードを、コンストラクタで登録したARコードから 探すクラスです。最大300個を認識しますが、ゴミラベルを認識したりするので100個程度が限界です。\r
+ * \r
+ */\r
+public class NyARDetectMarker\r
+{\r
+       private class RleDetector extends NyARSquareContourDetector_Rle\r
+       {\r
+               //公開プロパティ\r
+               public NyARDetectMarkerResultStack result_stack=new NyARDetectMarkerResultStack(NyARDetectMarker.AR_SQUARE_MAX);\r
+               //参照インスタンス\r
+               public INyARRgbRaster _ref_raster;\r
+               //所有インスタンス\r
+               private INyARColorPatt _inst_patt;\r
+               private NyARMatchPattDeviationColorData _deviation_data;\r
+               private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt;\r
+               private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+               private NyARCoord2Linear _coordline;\r
+\r
+               public RleDetector(INyARColorPatt i_inst_patt,NyARCode[] i_ref_code,int i_num_of_code,NyARParam i_param) throws NyARException\r
+               {\r
+                       super(i_param.getScreenSize());\r
+                       final int cw = i_ref_code[0].getWidth();\r
+                       final int ch = i_ref_code[0].getHeight();\r
+                       //NyARMatchPatt_Color_WITHOUT_PCA[]の作成\r
+                       this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA[i_num_of_code];\r
+                       this._match_patt[0]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[0]);\r
+                       for (int i = 1; i < i_num_of_code; i++){\r
+                               //解像度チェック\r
+                               if (cw != i_ref_code[i].getWidth() || ch != i_ref_code[i].getHeight()) {\r
+                                       throw new NyARException();\r
+                               }\r
+                               this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);\r
+                       }\r
+                       this._inst_patt=i_inst_patt;\r
+                       this._coordline=new NyARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+                       this._deviation_data=new NyARMatchPattDeviationColorData(cw,ch);\r
+                       return;\r
+               }\r
+               private NyARIntPoint2d[] __ref_vertex=new NyARIntPoint2d[4];\r
+               /**\r
+                * 矩形が見付かるたびに呼び出されます。\r
+                * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+                */\r
+               protected void onSquareDetect(NyARIntCoordinates i_coord,int[] i_vertex_index) throws NyARException\r
+               {\r
+                       NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+                       //輪郭座標から頂点リストに変換\r
+                       NyARIntPoint2d[] vertex=this.__ref_vertex;\r
+                       vertex[0]=i_coord.items[i_vertex_index[0]];\r
+                       vertex[1]=i_coord.items[i_vertex_index[1]];\r
+                       vertex[2]=i_coord.items[i_vertex_index[2]];\r
+                       vertex[3]=i_coord.items[i_vertex_index[3]];\r
+               \r
+                       //画像を取得\r
+                       if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){\r
+                               return;\r
+                       }\r
+                       //取得パターンをカラー差分データに変換して評価する。\r
+                       this._deviation_data.setRaster(this._inst_patt);\r
+\r
+                       //最も一致するパターンを割り当てる。\r
+                       int square_index,direction;\r
+                       double confidence;\r
+                       this._match_patt[0].evaluate(this._deviation_data,mr);\r
+                       square_index=0;\r
+                       direction=mr.direction;\r
+                       confidence=mr.confidence;\r
+                       //2番目以降\r
+                       for(int i=1;i<this._match_patt.length;i++){\r
+                               this._match_patt[i].evaluate(this._deviation_data,mr);\r
+                               if (confidence > mr.confidence) {\r
+                                       continue;\r
+                               }\r
+                               // もっと一致するマーカーがあったぽい\r
+                               square_index = i;\r
+                               direction = mr.direction;\r
+                               confidence = mr.confidence;\r
+                       }\r
+                       //最も一致したマーカ情報を、この矩形の情報として記録する。\r
+                       final NyARDetectMarkerResult result = this.result_stack.prePush();\r
+                       result.arcode_id = square_index;\r
+                       result.confidence = confidence;\r
+\r
+                       final NyARSquare sq=result.square;\r
+                       //directionを考慮して、squareを更新する。\r
+                       for(int i=0;i<4;i++){\r
+                               int idx=(i+4 - direction) % 4;\r
+                               this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coord,sq.line[i]);\r
+                       }\r
+                       for (int i = 0; i < 4; i++) {\r
+                               //直線同士の交点計算\r
+                               if(!sq.line[i].crossPos(sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+                                       throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+                               }\r
+                       }\r
+               }\r
+               public void init(INyARRgbRaster i_raster)\r
+               {\r
+                       this._ref_raster=i_raster;\r
+                       this.result_stack.clear();\r
+                       \r
+               }\r
+       }       \r
+       private static final int AR_SQUARE_MAX = 300;\r
+       private boolean _is_continue = false;\r
+       private RleDetector _square_detect;\r
+       protected INyARTransMat _transmat;\r
+       private NyARRectOffset[] _offset;       \r
+\r
+\r
+       /**\r
+        * 複数のマーカーを検出し、最も一致するARCodeをi_codeから検索するオブジェクトを作ります。\r
+        * \r
+        * @param i_param\r
+        * カメラパラメータを指定します。\r
+        * @param i_code\r
+        * 検出するマーカーのARCode配列を指定します。\r
+        * 配列要素のインデックス番号が、そのままgetARCodeIndex関数で得られるARCodeインデックスになります。 \r
+        * 例えば、要素[1]のARCodeに一致したマーカーである場合は、getARCodeIndexは1を返します。\r
+        * @param i_marker_width\r
+        * i_codeのマーカーサイズをミリメートルで指定した配列を指定します。 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。\r
+        * @param i_number_of_code\r
+        * i_codeに含まれる、ARCodeの数を指定します。\r
+        * @param i_input_raster_type\r
+        * 入力ラスタのピクセルタイプを指定します。この値は、INyARBufferReaderインタフェイスのgetBufferTypeの戻り値を指定します。\r
+        * @throws NyARException\r
+        */\r
+       public NyARDetectMarker(NyARParam i_param,NyARCode[] i_code,double[] i_marker_width, int i_number_of_code,int i_input_raster_type) throws NyARException\r
+       {\r
+               initInstance(i_param,i_code,i_marker_width,i_number_of_code,i_input_raster_type);\r
+               return;\r
+       }\r
+       protected void initInstance(\r
+               NyARParam       i_ref_param,\r
+               NyARCode[]      i_ref_code,\r
+               double[]        i_marker_width,\r
+               int                     i_number_of_code,\r
+               int i_input_raster_type) throws NyARException\r
+       {\r
+\r
+               final NyARIntSize scr_size=i_ref_param.getScreenSize();\r
+               // 解析オブジェクトを作る\r
+               final int cw = i_ref_code[0].getWidth();\r
+               final int ch = i_ref_code[0].getHeight();\r
+\r
+               this._transmat = new NyARTransMat(i_ref_param);\r
+               //NyARToolkitプロファイル\r
+               this._square_detect =new RleDetector(new NyARColorPatt_Perspective_O2(cw, ch,4,25,i_input_raster_type),i_ref_code,i_number_of_code,i_ref_param);\r
+               this._tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100,i_input_raster_type);\r
+\r
+               //実サイズ保存\r
+               this._offset = NyARRectOffset.createArray(i_number_of_code);\r
+               for(int i=0;i<i_number_of_code;i++){\r
+                       this._offset[i].setSquare(i_marker_width[i]);\r
+               }\r
+               //2値画像バッファを作る\r
+               this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
+               return;         \r
+       }\r
+       \r
+       private NyARBinRaster _bin_raster;\r
+\r
+       private INyARRasterFilter_Rgb2Bin _tobin_filter;\r
+\r
+       /**\r
+        * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+        * \r
+        * @param i_raster\r
+        * マーカーを検出するイメージを指定します。\r
+        * @param i_thresh\r
+        * 検出閾値を指定します。0~255の範囲で指定してください。 通常は100~130くらいを指定します。\r
+        * @return 見つかったマーカーの数を返します。 マーカーが見つからない場合は0を返します。\r
+        * @throws NyARException\r
+        */\r
+       public int detectMarkerLite(INyARRgbRaster i_raster, int i_threshold) throws NyARException\r
+       {\r
+               // サイズチェック\r
+               if (!this._bin_raster.getSize().isEqualSize(i_raster.getSize())) {\r
+                       throw new NyARException();\r
+               }\r
+\r
+               // ラスタを2値イメージに変換する.\r
+               ((NyARRasterFilter_ARToolkitThreshold)this._tobin_filter).setThreshold(i_threshold);\r
+               this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
+\r
+               //detect\r
+               this._square_detect.init(i_raster);\r
+               this._square_detect.detectMarker(this._bin_raster);\r
+\r
+               //見付かった数を返す。\r
+               return this._square_detect.result_stack.getLength();\r
+       }\r
+\r
+       /**\r
+        * i_indexのマーカーに対する変換行列を計算し、結果値をo_resultへ格納します。 直前に実行したdetectMarkerLiteが成功していないと使えません。\r
+        * \r
+        * @param i_index\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._square_detect.result_stack.getItem(i_index);\r
+               // 一番一致したマーカーの位置とかその辺を計算\r
+               if (_is_continue) {\r
+                       _transmat.transMatContinue(result.square, this._offset[result.arcode_id], o_result,o_result);\r
+               } else {\r
+                       _transmat.transMat(result.square, this._offset[result.arcode_id], o_result);\r
+               }\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * i_indexのマーカーの一致度を返します。\r
+        * \r
+        * @param i_index\r
+        * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+        * @return マーカーの一致度を返します。0~1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。\r
+        * @throws NyARException\r
+        */\r
+       public double getConfidence(int i_index)\r
+       {\r
+               return this._square_detect.result_stack.getItem(i_index).confidence;\r
+       }\r
+       /**\r
+        * i_indexのマーカーのARCodeインデックスを返します。\r
+        * \r
+        * @param i_index\r
+        * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+        * @return\r
+        */\r
+       public int getARCodeIndex(int i_index)\r
+       {\r
+               return this._square_detect.result_stack.getItem(i_index).arcode_id;\r
+       }\r
+\r
+       /**\r
+        * getTransmationMatrixの計算モードを設定します。\r
+        * \r
+        * @param i_is_continue\r
+        * TRUEなら、transMatContinueを使用します。 FALSEなら、transMatを使用します。\r
+        */\r
+       public void setContinueMode(boolean i_is_continue)\r
+       {\r
+               this._is_continue = i_is_continue;\r
+       }\r
+}\r
+\r
+class NyARDetectMarkerResult\r
+{\r
+       public int arcode_id;\r
+       public double confidence;\r
+\r
+       public NyARSquare square=new NyARSquare();\r
+}\r
+\r
+\r
+class NyARDetectMarkerResultStack extends NyARObjectStack<NyARDetectMarkerResult>\r
+{\r
+       public NyARDetectMarkerResultStack(int i_length) throws NyARException\r
+       {\r
+               super();\r
+               this.initInstance(i_length,NyARDetectMarkerResult.class);\r
+               return;\r
+       }\r
+       protected NyARDetectMarkerResult createElement()\r
+       {\r
+               return new NyARDetectMarkerResult();\r
+       }       \r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/detector/NyARSingleDetectMarker.java b/lib/src/jp/nyatla/nyartoolkit/detector/NyARSingleDetectMarker.java
new file mode 100644 (file)
index 0000000..64862a5
--- /dev/null
@@ -0,0 +1,182 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.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.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.pickup.INyARColorPatt;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+/**\r
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
+ * \r
+ */\r
+public class NyARSingleDetectMarker extends NyARCustomSingleDetectMarker\r
+{\r
+       public final static int PF_ARTOOLKIT_COMPATIBLE=1;\r
+       public final static int PF_NYARTOOLKIT=2;\r
+       public final static int PF_NYARTOOLKIT_ARTOOLKIT_FITTING=100;\r
+       public final static int PF_TEST2=201;\r
+       \r
+       /**\r
+        * Rleラ矩形Detectorのブリッジ\r
+        *\r
+        */\r
+       class RleDetector extends NyARSquareContourDetector_Rle\r
+       {\r
+               NyARCustomSingleDetectMarker _parent;\r
+               public RleDetector(NyARCustomSingleDetectMarker i_parent,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       super(i_size);\r
+                       this._parent=i_parent;\r
+               }\r
+               protected void onSquareDetect(NyARIntCoordinates i_coord,int[] i_vertex_index) throws NyARException\r
+               {\r
+                       this._parent.updateSquareInfo(i_coord, i_vertex_index);\r
+               }       \r
+       }\r
+       /**\r
+        * ARTK矩形Detectorのブリッジ\r
+        *\r
+        */\r
+       class ARTKDetector extends NyARSquareContourDetector_ARToolKit\r
+       {\r
+               NyARCustomSingleDetectMarker _parent;\r
+               public ARTKDetector(NyARCustomSingleDetectMarker i_parent,NyARIntSize i_size) throws NyARException\r
+               {\r
+                       super(i_size);\r
+                       this._parent=i_parent;\r
+               }\r
+               protected void onSquareDetect(NyARIntCoordinates i_coord,int[] i_vertex_index) throws NyARException\r
+               {\r
+                       this._parent.updateSquareInfo(i_coord, i_vertex_index);\r
+               }       \r
+       }       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       /**\r
+        * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。\r
+        * \r
+        * @param i_param\r
+        * カメラパラメータを指定します。\r
+        * @param i_code\r
+        * 検出するARCodeを指定します。\r
+        * @param i_marker_width\r
+        * ARコードの物理サイズを、ミリメートルで指定します。\r
+        * @param i_input_raster_type\r
+        * 入力ラスタのピクセルタイプを指定します。この値は、INyARBufferReaderインタフェイスのgetBufferTypeの戻り値を指定します。\r
+        * @throws NyARException\r
+        */\r
+       public NyARSingleDetectMarker(NyARParam i_param, NyARCode i_code, double i_marker_width,int i_input_raster_type,int i_profile_id) throws NyARException\r
+       {\r
+               super();\r
+               initialize(i_param,i_code,i_marker_width,i_input_raster_type,i_profile_id);\r
+               return;\r
+       }\r
+       public NyARSingleDetectMarker(NyARParam i_param, NyARCode i_code, double i_marker_width,int i_input_raster_type) throws NyARException\r
+       {\r
+               super();\r
+               initialize(i_param,i_code,i_marker_width,i_input_raster_type,PF_NYARTOOLKIT);\r
+               return;\r
+       }\r
+       /**\r
+        * コンストラクタから呼び出す関数です。\r
+        * @param i_ref_param\r
+        * @param i_ref_code\r
+        * @param i_marker_width\r
+        * @param i_input_raster_type\r
+        * @param i_profile_id\r
+        * @throws NyARException\r
+        */\r
+       private void initialize(\r
+               NyARParam       i_ref_param,\r
+               NyARCode        i_ref_code,\r
+               double          i_marker_width,\r
+               int i_input_raster_type,\r
+               int i_profile_id) throws NyARException\r
+       {\r
+               final NyARRasterFilter_ARToolkitThreshold th=new NyARRasterFilter_ARToolkitThreshold(100,i_input_raster_type);\r
+               INyARColorPatt patt_inst;\r
+               NyARSquareContourDetector sqdetect_inst;\r
+               INyARTransMat transmat_inst;\r
+\r
+               switch(i_profile_id){\r
+               case PF_ARTOOLKIT_COMPATIBLE:\r
+                       patt_inst=new NyARColorPatt_O3(i_ref_code.getWidth(), i_ref_code.getHeight());\r
+                       sqdetect_inst=new ARTKDetector(this,i_ref_param.getScreenSize());\r
+                       transmat_inst=new NyARTransMat_ARToolKit(i_ref_param);\r
+                       break;\r
+               case PF_NYARTOOLKIT_ARTOOLKIT_FITTING:\r
+                       patt_inst=new NyARColorPatt_Perspective_O2(i_ref_code.getWidth(), i_ref_code.getHeight(),4,25,i_input_raster_type);\r
+                       sqdetect_inst=new RleDetector(this,i_ref_param.getScreenSize());\r
+                       transmat_inst=new NyARTransMat_ARToolKit(i_ref_param);\r
+                       break;\r
+               case PF_NYARTOOLKIT://default\r
+//                     patt_inst=new NyARColorPatt_Perspective(i_ref_code.getWidth(), i_ref_code.getHeight(),4,25);\r
+                       patt_inst=new NyARColorPatt_Perspective_O2(i_ref_code.getWidth(), i_ref_code.getHeight(),4,25,i_input_raster_type);\r
+                       sqdetect_inst=new RleDetector(this,i_ref_param.getScreenSize());\r
+                       transmat_inst=new NyARTransMat(i_ref_param);\r
+                       break;\r
+               default:\r
+                       throw new NyARException();\r
+               }\r
+               super.initInstance(patt_inst,sqdetect_inst,transmat_inst,th,i_ref_param,i_ref_code,i_marker_width);\r
+               \r
+       }\r
+\r
+       /**\r
+        * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+        * \r
+        * @param i_raster\r
+        * マーカーを検出するイメージを指定します。イメージサイズは、コンストラクタで指定i_paramの\r
+        * スクリーンサイズと一致し、かつi_input_raster_typeに指定した形式でなければいけません。\r
+        * @return マーカーが検出できたかを真偽値で返します。\r
+        * @throws NyARException\r
+        */\r
+       public boolean detectMarkerLite(INyARRgbRaster i_raster,int i_threshold) throws NyARException\r
+       {\r
+               ((NyARRasterFilter_ARToolkitThreshold)this._tobin_filter).setThreshold(i_threshold);\r
+               return super.detectMarkerLite(i_raster);\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/nyidmarker/NyIdMarkerParam.java b/lib/src/jp/nyatla/nyartoolkit/nyidmarker/NyIdMarkerParam.java
new file mode 100644 (file)
index 0000000..8fd48d8
--- /dev/null
@@ -0,0 +1,43 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker;\r
+\r
+/**\r
+ * [[Strage class]]\r
+ * マーカを抽出した時のパラメータを格納するクラスです。\r
+ *\r
+ */\r
+public class NyIdMarkerParam\r
+{\r
+       /**\r
+        * マーカの方位値です。\r
+        */\r
+       public int direction;\r
+       /**\r
+        * マーカ周辺のパターン閾値です。\r
+        */\r
+       public int threshold; \r
+       \r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/nyidmarker/NyIdMarkerPattern.java b/lib/src/jp/nyatla/nyartoolkit/nyidmarker/NyIdMarkerPattern.java
new file mode 100644 (file)
index 0000000..3316a8f
--- /dev/null
@@ -0,0 +1,54 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker;\r
+/**\r
+ * [[Strage class]]\r
+ * IDマーカパターン値を格納するクラスです。\r
+ * クラスは、未整形のマーカデータを格納しています。\r
+ *\r
+ */\r
+public class NyIdMarkerPattern\r
+{\r
+       /**\r
+        * マーカのModel番号\r
+        */\r
+       public int model;\r
+       /**\r
+        * コントロールビットのDoamin番号\r
+        */\r
+       public int ctrl_domain;\r
+       /**\r
+        * コントロールビットのマスク番号\r
+        */\r
+       public int ctrl_mask;\r
+       /**\r
+        * コントロールビットのチェック値\r
+        */\r
+       public int check;\r
+       /**\r
+        * データパケットの値\r
+        */\r
+       public final int[] data=new int[32];\r
+}
\ No newline at end of file
diff --git a/lib/src/jp/nyatla/nyartoolkit/nyidmarker/NyIdMarkerPickup.java b/lib/src/jp/nyatla/nyartoolkit/nyidmarker/NyIdMarkerPickup.java
new file mode 100644 (file)
index 0000000..aec8562
--- /dev/null
@@ -0,0 +1,1115 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * NyARColorPatt_NyIdMarkerがラスタからPerspective変換して読みだすためのクラス\r
+ *\r
+ */\r
+final class PerspectivePixelReader\r
+{\r
+       private static int READ_RESOLUTION=100;\r
+       private NyARPerspectiveParamGenerator _param_gen=new NyARPerspectiveParamGenerator_O1(1,1);\r
+       private double[] _cparam=new double[8];\r
+\r
+\r
+       public PerspectivePixelReader()\r
+       {\r
+               return;\r
+       }\r
+\r
+       public boolean setSourceSquare(NyARIntPoint2d[] i_vertex)throws NyARException\r
+       {\r
+               return this._param_gen.getParam(READ_RESOLUTION,READ_RESOLUTION,i_vertex, this._cparam);\r
+       }\r
+       public boolean setSourceSquare(NyARDoublePoint2d[] i_vertex)throws NyARException\r
+       {\r
+               return this._param_gen.getParam(READ_RESOLUTION,READ_RESOLUTION,i_vertex, this._cparam);\r
+       }\r
+       /**\r
+        * 矩形からピクセルを切り出します\r
+        * @param i_lt_x\r
+        * @param i_lt_y\r
+        * @param i_step_x\r
+        * @param i_step_y\r
+        * @param i_width\r
+        * @param i_height\r
+        * @param i_out_st\r
+        * o_pixelへの格納場所の先頭インデクス\r
+        * @param o_pixel\r
+        * @throws NyARException\r
+        */\r
+       private boolean rectPixels(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,int i_lt_x,int i_lt_y,int i_step_x,int i_step_y,int i_width,int i_height,int i_out_st,int[] o_pixel)throws NyARException\r
+       {\r
+               final double[] cpara=this._cparam;\r
+               final int[] ref_x=this._ref_x;\r
+               final int[] ref_y=this._ref_y;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               final int raster_width=i_raster_size.w;\r
+               final int raster_height=i_raster_size.h;\r
+\r
+               int out_index=i_out_st;\r
+               final double cpara_6=cpara[6];\r
+               final double cpara_0=cpara[0];\r
+               final double cpara_3=cpara[3];\r
+\r
+               for(int i=0;i<i_height;i++){\r
+                       //1列分のピクセルのインデックス値を計算する。\r
+                       int cy0=1+i*i_step_y+i_lt_y;\r
+                       double cpy0_12=cpara[1]*cy0+cpara[2];\r
+                       double cpy0_45=cpara[4]*cy0+cpara[5];\r
+                       double cpy0_7=cpara[7]*cy0+1.0;                 \r
+                       int pt=0;\r
+                       for(int i2=0;i2<i_width;i2++)\r
+                       {\r
+                               final int cx0=1+i2*i_step_x+i_lt_x;                             \r
+                               final double d=cpara_6*cx0+cpy0_7;\r
+                               final int x=(int)((cpara_0*cx0+cpy0_12)/d);\r
+                               final int y=(int)((cpara_3*cx0+cpy0_45)/d);\r
+                               if(x<0||y<0||x>=raster_width||y>=raster_height)\r
+                               {\r
+                                       return false;\r
+                               }\r
+                               ref_x[pt]=x;\r
+                               ref_y[pt]=y;\r
+                               pt++;\r
+                       }\r
+                       //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+                       i_reader.getPixelSet(ref_x,ref_y,i_width,pixcel_temp);\r
+                       //グレースケールにしながら、line→mapへの転写\r
+                       for(int i2=0;i2<i_width;i2++){\r
+                               int index=i2*3;\r
+                               o_pixel[out_index]=(pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2])/3;\r
+                               out_index++;\r
+                       }                       \r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * i_freqにあるゼロクロス点の周期が、等間隔か調べます。\r
+        * 次段半周期が、前段の80%より大きく、120%未満であるものを、等間隔周期であるとみなします。\r
+        * @param i_freq\r
+        * @param i_width\r
+        */\r
+       private static boolean checkFreqWidth(int[] i_freq,int i_width)\r
+       {\r
+               int c=i_freq[1]-i_freq[0];\r
+               final int count=i_width*2-1;\r
+               for(int i=1;i<count;i++){\r
+                       final int n=i_freq[i+1]-i_freq[i];\r
+                       final int v=n*100/c;\r
+                       if(v>150 || v<50){\r
+                               return false;\r
+                       }\r
+                       c=n;\r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * i_freq_count_tableとi_freq_tableの内容を調査し、最も大きな周波数成分を返します。\r
+        * @param i_freq_count_table\r
+        * @param i_freq_table\r
+        * @param o_freq_table\r
+        * @return\r
+        * 見つかれば0以上、密辛ければ0未満\r
+        */\r
+       private static int getMaxFreq(int[] i_freq_count_table,int[] i_freq_table,int[] o_freq_table)\r
+       {\r
+               //一番成分の大きいものを得る\r
+               int index=-1;\r
+               int max=0;\r
+               for(int i=0;i<MAX_FREQ;i++){\r
+                       if(max<i_freq_count_table[i]){\r
+                               index=i;\r
+                               max=i_freq_count_table[i];\r
+                       }\r
+               }               \r
+               if(index==-1){\r
+                       return -1;\r
+               }\r
+               /*周波数インデクスを計算*/\r
+               final int st=(index-1)*index;\r
+               for(int i=0;i<index*2;i++)\r
+               {\r
+                       o_freq_table[i]=i_freq_table[st+i]*FRQ_STEP/max;\r
+               }\r
+               return index;\r
+       }\r
+               \r
+       \r
+       //タイミングパターン用のパラメタ(FRQ_POINTS*FRQ_STEPが100を超えないようにすること)\r
+       private static final int FRQ_EDGE=5;\r
+       private static final int FRQ_STEP=2;\r
+       private static final int FRQ_POINTS=(100-(FRQ_EDGE*2))/FRQ_STEP;\r
+       \r
+\r
+       private static final int MIN_FREQ=3;\r
+       private static final int MAX_FREQ=10;\r
+       private static final int FREQ_SAMPLE_NUM=4;\r
+       private static final int MAX_DATA_BITS=MAX_FREQ+MAX_FREQ-1;\r
+\r
+       private final int[] _ref_x=new int[108];\r
+       private final int[] _ref_y=new int[108];\r
+       //(model+1)*4*3とTHRESHOLD_PIXEL*3のどちらか大きい方\r
+       private int[] _pixcel_temp=new int[108*3];\r
+       \r
+       private final int[] _freq_count_table=new int[MAX_FREQ];\r
+       private final int[] _freq_table=new int[(MAX_FREQ*2-1)*MAX_FREQ*2/2];\r
+\r
+       /**\r
+        * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。\r
+        * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを\r
+        * 検出した場合、関数は失敗します。\r
+        * \r
+        * @param i_y1\r
+        * @param i_y2\r
+        * @param i_th_h\r
+        * @param i_th_l\r
+        * @param o_edge_index\r
+        * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。\r
+        * [FRQ_POINTS]以上の配列を指定してください。\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public int getRowFrequency(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,int i_y1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+       {\r
+               //3,4,5,6,7,8,9,10\r
+               final int[] freq_count_table=this._freq_count_table;\r
+               //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列\r
+               final int[] freq_table=this._freq_table;\r
+               //初期化\r
+               final double[] cpara=this._cparam;\r
+               final int[] ref_x=this._ref_x;\r
+               final int[] ref_y=this._ref_y;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               for(int i=0;i<10;i++){\r
+                       freq_count_table[i]=0;\r
+               }\r
+               for(int i=0;i<110;i++){\r
+                       freq_table[i]=0;\r
+               }\r
+               final int raster_width=i_raster_size.w;\r
+               final int raster_height=i_raster_size.h;\r
+\r
+               final double cpara_0=cpara[0];\r
+               final double cpara_3=cpara[3];\r
+               final double cpara_6=cpara[6];          \r
+               \r
+               //10-20ピクセル目からタイミングパターンを検出\r
+               for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
+                       //2行分のピクセルインデックスを計算\r
+                       final double cy0=1+i_y1+i;\r
+                       final double cpy0_12=cpara[1]*cy0+cpara[2];\r
+                       final double cpy0_45=cpara[4]*cy0+cpara[5];\r
+                       final double cpy0_7=cpara[7]*cy0+1.0;\r
+\r
+                       int pt=0;\r
+                       for(int i2=0;i2<FRQ_POINTS;i2++)\r
+                       {\r
+                               final double cx0=1+i2*FRQ_STEP+FRQ_EDGE;                        \r
+                               final double d=(cpara_6*cx0)+cpy0_7;\r
+                               final int x=(int)((cpara_0*cx0+cpy0_12)/d);\r
+                               final int y=(int)((cpara_3*cx0+cpy0_45)/d);\r
+                               if(x<0||y<0||x>=raster_width||y>=raster_height)\r
+                               {\r
+                                       return -1;\r
+                               }\r
+                               ref_x[pt]=x;\r
+                               ref_y[pt]=y;\r
+                               pt++;\r
+                       }\r
+                       \r
+                       //ピクセルを取得(入力画像を多様化するならここから先を調整すること)\r
+                       i_reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+\r
+                       //o_edge_indexを一時的に破壊して調査する\r
+                       final int freq_t=getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);                   \r
+                       \r
+                       //周期は3-10であること\r
+                       if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+                               continue;\r
+                       }\r
+                       //周期は等間隔であること\r
+                       if(!checkFreqWidth(o_edge_index,freq_t)){\r
+                               continue;\r
+                       }\r
+                       //検出カウンタを追加\r
+                       freq_count_table[freq_t]++;\r
+                       final int table_st=(freq_t-1)*freq_t;\r
+                       for(int i2=0;i2<freq_t*2;i2++){\r
+                               freq_table[table_st+i2]+=o_edge_index[i2];\r
+                       }\r
+               }\r
+               return getMaxFreq(freq_count_table,freq_table,o_edge_index);\r
+       }\r
+       \r
+       public int getColFrequency(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,int i_x1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+       {\r
+               final double[] cpara=this._cparam;\r
+//             final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+               final int[] ref_x=this._ref_x;\r
+               final int[] ref_y=this._ref_y;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               //0,2,4,6,8,10,12,14,16,18,20=(11*20)/2=110\r
+               //初期化\r
+               final int[] freq_count_table=this._freq_count_table;\r
+               for(int i=0;i<10;i++){\r
+                       freq_count_table[i]=0;\r
+               }\r
+               final int[] freq_table=this._freq_table;\r
+               for(int i=0;i<110;i++){\r
+                       freq_table[i]=0;\r
+               }\r
+               final int raster_width=i_raster_size.w;\r
+               final int raster_height=i_raster_size.h;\r
+               \r
+               \r
+               final double cpara7=cpara[7];\r
+               final double cpara4=cpara[4];\r
+               final double cpara1=cpara[1];\r
+               //基準点から4ピクセルを参照パターンとして抽出\r
+               for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
+\r
+                       int cx0=1+i+i_x1;\r
+                       final double cp6_0=cpara[6]*cx0;\r
+                       final double cpx0_0=cpara[0]*cx0+cpara[2];\r
+                       final double cpx3_0=cpara[3]*cx0+cpara[5];\r
+                       \r
+                       int pt=0;\r
+                       for(int i2=0;i2<FRQ_POINTS;i2++)\r
+                       {\r
+                               int cy=1+i2*FRQ_STEP+FRQ_EDGE;\r
+                               \r
+                               final double d=cp6_0+cpara7*cy+1.0;\r
+                               final int x=(int)((cpx0_0+cpara1*cy)/d);\r
+                               final int y=(int)((cpx3_0+cpara4*cy)/d);\r
+                               if(x<0||y<0||x>=raster_width||y>=raster_height)\r
+                               {\r
+                                       return -1;\r
+                               }\r
+                               ref_x[pt]=x;\r
+                               ref_y[pt]=y;                            \r
+                               pt++;\r
+                       }               \r
+               \r
+                       //ピクセルを取得(入力画像を多様化するならここを調整すること)\r
+                       i_reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+                       \r
+                       final int freq_t=getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);\r
+                       //周期は3-10であること\r
+                       if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+                               continue;\r
+                       }\r
+                       //周期は等間隔であること\r
+                       if(!checkFreqWidth(o_edge_index,freq_t)){\r
+                               continue;\r
+                       }\r
+                       //検出カウンタを追加\r
+                       freq_count_table[freq_t]++;\r
+                       final int table_st=(freq_t-1)*freq_t;\r
+                       for(int i2=0;i2<freq_t*2;i2++){\r
+                               freq_table[table_st+i2]+=o_edge_index[i2];\r
+                       }\r
+               }\r
+               return getMaxFreq(freq_count_table,freq_table,o_edge_index);            \r
+       }\r
+\r
+       /**\r
+        * デバックすんだらstaticにしておk\r
+        * @param i_pixcels\r
+        * @param i_th_h\r
+        * @param i_th_l\r
+        * @param o_edge_index\r
+        * @return\r
+        */\r
+       private static int getFreqInfo(int[] i_pixcels,int i_th_h,int i_th_l,int[] o_edge_index)\r
+       {\r
+               //トークンを解析して、周波数を計算\r
+               int i=0;\r
+               int frq_l2h=0;\r
+               int frq_h2l=0;\r
+               while(i<FRQ_POINTS){\r
+                       //L->Hトークンを検出する\r
+                       while(i<FRQ_POINTS){\r
+                               final int index=i*3;\r
+                               final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+                               if(pix>i_th_h){\r
+                                       //トークン発見\r
+                                       o_edge_index[frq_l2h+frq_h2l]=i;\r
+                                       frq_l2h++;\r
+                                       break;\r
+                               }\r
+                               i++;\r
+                       }\r
+                       i++;\r
+                       //L->Hトークンを検出する\r
+                       while(i<FRQ_POINTS){\r
+                               final int index=i*3;\r
+                               final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+                               if(pix<=i_th_l){\r
+                                       //トークン発見\r
+                                       o_edge_index[frq_l2h+frq_h2l]=i;\r
+                                       frq_h2l++;\r
+                                       break;\r
+                               }\r
+                               i++;\r
+                       }\r
+                       i++;\r
+               }\r
+               return frq_l2h==frq_h2l?frq_l2h:-1;                     \r
+       }\r
+\r
+       private static final int THRESHOLD_EDGE=10;\r
+       private static final int THRESHOLD_STEP=2;\r
+       private static final int THRESHOLD_WIDTH=10;\r
+       private static final int THRESHOLD_PIXEL=THRESHOLD_WIDTH/THRESHOLD_STEP;\r
+       private static final int THRESHOLD_SAMPLE=THRESHOLD_PIXEL*THRESHOLD_PIXEL;\r
+       private static final int THRESHOLD_SAMPLE_LT=THRESHOLD_EDGE;\r
+       private static final int THRESHOLD_SAMPLE_RB=100-THRESHOLD_WIDTH-THRESHOLD_EDGE;\r
+       \r
+       public static class TThreshold{\r
+               public int th_h;\r
+               public int th_l;\r
+               public int th;\r
+               public int lt_x;\r
+               public int lt_y;\r
+               public int rb_x;\r
+               public int rb_y;\r
+       }       \r
+\r
+       class THighAndLow{\r
+               public int h;\r
+               public int l;\r
+       }\r
+       /**\r
+        * ピクセル配列の上位、下位の4ピクセルのピクセル値平均を求めます。\r
+        * この関数は、(4/i_pixcel.length)の領域を占有するPtail法で双方向の閾値を求めることになります。\r
+        * @param i_pixcel\r
+        * @param i_initial\r
+        * @param i_out\r
+        */\r
+       private void getPtailHighAndLow(int[] i_pixcel,THighAndLow i_out)\r
+       {\r
+               int h3,h2,h1,h0,l3,l2,l1,l0;\r
+               h3=h2=h1=h0=l3=l2=l1=l0=i_pixcel[0];\r
+               \r
+               for(int i=i_pixcel.length-1;i>=1;i--){\r
+                       final int pix=i_pixcel[i];\r
+                       if(h0<pix){\r
+                               if(h1<pix){\r
+                                       if(h2<pix){\r
+                                               if(h3<pix){\r
+                                                       h0=h1;\r
+                                                       h1=h2;\r
+                                                       h2=h3;\r
+                                                       h3=pix;\r
+                                               }else{\r
+                                                       h0=h1;\r
+                                                       h1=h2;\r
+                                                       h2=pix;\r
+                                               }\r
+                                       }else{\r
+                                               h0=h1;\r
+                                               h1=pix;\r
+                                       }\r
+                               }else{\r
+                                       h0=pix;\r
+                               }\r
+                       }\r
+                       if(l0>pix){\r
+                               if(l1>pix){\r
+                                       if(l2>pix){\r
+                                               if(l3>pix){\r
+                                                       l0=l1;\r
+                                                       l1=l2;\r
+                                                       l2=l3;\r
+                                                       l3=pix;\r
+                                               }else{\r
+                                                       l0=l1;\r
+                                                       l1=l2;\r
+                                                       l2=pix;\r
+                                               }\r
+                                       }else{\r
+                                               l0=l1;\r
+                                               l1=pix;\r
+                                       }\r
+                               }else{\r
+                                       l0=pix;\r
+                               }\r
+                       }\r
+               }\r
+               i_out.l=(l0+l1+l2+l3)/4;\r
+               i_out.h=(h0+h1+h2+h3)/4;\r
+               return;\r
+       }\r
+       private THighAndLow __detectThresholdValue_hl=new THighAndLow();\r
+       private NyARIntPoint2d __detectThresholdValue_tpt=new NyARIntPoint2d();\r
+       private int[] _th_pixels=new int[THRESHOLD_SAMPLE*4];\r
+       /**\r
+        * 指定した場所のピクセル値を調査して、閾値を計算して返します。\r
+        * @param i_reader\r
+        * @param i_x\r
+        * @param i_y\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public void detectThresholdValue(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,TThreshold o_threshold)throws NyARException\r
+       {\r
+               final int[] th_pixels=this._th_pixels;\r
+\r
+               //左上のピックアップ領域からピクセルを得る(00-24)\r
+               rectPixels(i_reader,i_raster_size,THRESHOLD_SAMPLE_LT,THRESHOLD_SAMPLE_LT,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,0,th_pixels);\r
+               \r
+               //左下のピックアップ領域からピクセルを得る(25-49)\r
+               rectPixels(i_reader,i_raster_size,THRESHOLD_SAMPLE_LT,THRESHOLD_SAMPLE_RB,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE,th_pixels);\r
+               \r
+               //右上のピックアップ領域からピクセルを得る(50-74)\r
+               rectPixels(i_reader,i_raster_size,THRESHOLD_SAMPLE_RB,THRESHOLD_SAMPLE_LT,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE*2,th_pixels);\r
+\r
+               //右下のピックアップ領域からピクセルを得る(75-99)\r
+               rectPixels(i_reader,i_raster_size,THRESHOLD_SAMPLE_RB,THRESHOLD_SAMPLE_RB,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE*3,th_pixels);\r
+\r
+               final THighAndLow hl=this.__detectThresholdValue_hl;\r
+               //Ptailで求めたピクセル平均\r
+               getPtailHighAndLow(th_pixels,hl);\r
+\r
+\r
+               \r
+               //閾値中心\r
+               int th=(hl.h+hl.l)/2;\r
+               //ヒステリシス(差分の20%)\r
+               int th_sub=(hl.h-hl.l)/5;\r
+               \r
+               o_threshold.th=th;\r
+               o_threshold.th_h=th+th_sub;//ヒステリシス付き閾値\r
+               o_threshold.th_l=th-th_sub;//ヒステリシス付き閾値\r
+\r
+               //エッジを計算(明点重心)\r
+               int lt_x,lt_y,lb_x,lb_y,rt_x,rt_y,rb_x,rb_y;\r
+               final NyARIntPoint2d tpt=this.__detectThresholdValue_tpt;\r
+               //LT\r
+               if(getHighPixelCenter(0,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+                       lt_x=tpt.x*THRESHOLD_STEP;\r
+                       lt_y=tpt.y*THRESHOLD_STEP;\r
+               }else{\r
+                       lt_x=11;\r
+                       lt_y=11;\r
+               }\r
+               //LB\r
+               if(getHighPixelCenter(THRESHOLD_SAMPLE*1,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+                       lb_x=tpt.x*THRESHOLD_STEP;\r
+                       lb_y=tpt.y*THRESHOLD_STEP;\r
+               }else{\r
+                       lb_x=11;\r
+                       lb_y=-1;\r
+               }\r
+               //RT\r
+               if(getHighPixelCenter(THRESHOLD_SAMPLE*2,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+                       rt_x=tpt.x*THRESHOLD_STEP;\r
+                       rt_y=tpt.y*THRESHOLD_STEP;\r
+               }else{\r
+                       rt_x=-1;\r
+                       rt_y=11;\r
+               }\r
+               //RB\r
+               if(getHighPixelCenter(THRESHOLD_SAMPLE*3,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+                       rb_x=tpt.x*THRESHOLD_STEP;\r
+                       rb_y=tpt.y*THRESHOLD_STEP;\r
+               }else{\r
+                       rb_x=-1;\r
+                       rb_y=-1;\r
+               }\r
+               //トラッキング開始位置の決定\r
+               o_threshold.lt_x=(lt_x+lb_x)/2+THRESHOLD_SAMPLE_LT-1;\r
+               o_threshold.rb_x=(rt_x+rb_x)/2+THRESHOLD_SAMPLE_RB+1;\r
+               o_threshold.lt_y=(lt_y+rt_y)/2+THRESHOLD_SAMPLE_LT-1;\r
+               o_threshold.rb_y=(lb_y+rb_y)/2+THRESHOLD_SAMPLE_RB+1;\r
+               return;\r
+       }\r
+\r
+       private boolean getHighPixelCenter(int i_st,int[] i_pixels,int i_width,int i_height,int i_th,NyARIntPoint2d o_point)\r
+       {\r
+               int rp=i_st;\r
+               int pos_x=0;\r
+               int pos_y=0;\r
+               int number_of_pos=0;\r
+               for(int i=0;i<i_height;i++){\r
+                       for(int i2=0;i2<i_width;i2++){\r
+                               if(i_pixels[rp++]>i_th){\r
+                                       pos_x+=i2;\r
+                                       pos_y+=i;\r
+                                       number_of_pos++;\r
+                               }\r
+                       }\r
+               }\r
+               if(number_of_pos>0){\r
+                       pos_x/=number_of_pos;\r
+                       pos_y/=number_of_pos;\r
+               }else{\r
+                       return false;\r
+               }\r
+               o_point.x=pos_x;\r
+               o_point.y=pos_y;\r
+               return true;\r
+       }\r
+       private int[] __detectDataBitsIndex_freq_index1=new int[FRQ_POINTS];\r
+       private int[] __detectDataBitsIndex_freq_index2=new int[FRQ_POINTS];\r
+       private int detectDataBitsIndex(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,PerspectivePixelReader.TThreshold i_th,double[] o_index_row,double[] o_index_col) throws NyARException\r
+       {\r
+               //周波数を測定\r
+               final int[] freq_index1=this.__detectDataBitsIndex_freq_index1;\r
+               final int[] freq_index2=this.__detectDataBitsIndex_freq_index2;\r
+               \r
+               int frq_t=getRowFrequency(i_reader,i_raster_size,i_th.lt_y,i_th.th_h,i_th.th_l,freq_index1);\r
+               int frq_b=getRowFrequency(i_reader,i_raster_size,i_th.rb_y,i_th.th_h,i_th.th_l,freq_index2);\r
+               //周波数はまとも?\r
+               if((frq_t<0 && frq_b<0) || frq_t==frq_b){\r
+                       return -1;\r
+               }\r
+               //タイミングパターンからインデクスを作成\r
+               int freq_h,freq_v;\r
+               int[] index;\r
+               if(frq_t>frq_b){\r
+                       freq_h=frq_t;\r
+                       index=freq_index1;\r
+               }else{\r
+                       freq_h=frq_b;\r
+                       index=freq_index2;\r
+               }\r
+               for(int i=0;i<freq_h+freq_h-1;i++){\r
+                       o_index_row[i*2]=((index[i+1]-index[i])*2/5+index[i])+FRQ_EDGE;\r
+                       o_index_row[i*2+1]=((index[i+1]-index[i])*3/5+index[i])+FRQ_EDGE;\r
+               }               \r
+               \r
+               \r
+               final int frq_l=getColFrequency(i_reader,i_raster_size,i_th.lt_x,i_th.th_h,i_th.th_l,freq_index1);\r
+               final int frq_r=getColFrequency(i_reader,i_raster_size,i_th.rb_x,i_th.th_h,i_th.th_l,freq_index2);\r
+               //周波数はまとも?\r
+               if((frq_l<0 && frq_r<0) || frq_l==frq_r){\r
+                       return -1;\r
+               }\r
+               //タイミングパターンからインデクスを作成\r
+               if(frq_l>frq_r){\r
+                       freq_v=frq_l;\r
+                       index=freq_index1;\r
+               }else{\r
+                       freq_v=frq_r;\r
+                       index=freq_index2;\r
+               }\r
+               //同じ周期?\r
+               if(freq_v!=freq_h){\r
+                       return -1;\r
+               }\r
+               \r
+               for(int i=0;i<freq_v+freq_v-1;i++){\r
+                       final int w=index[i];\r
+                       final int w2=index[i+1]-w;\r
+                       o_index_col[i*2]=((w2)*2/5+w)+FRQ_EDGE;\r
+                       o_index_col[i*2+1]=((w2)*3/5+w)+FRQ_EDGE;\r
+               }               \r
+               //Lv4以上は無理\r
+               if(freq_v>MAX_FREQ){\r
+                       return -1;\r
+               }\r
+               return freq_v;\r
+               \r
+       }\r
+       private double[] __readDataBits_index_bit_x=new double[MAX_DATA_BITS*2];\r
+       private double[] __readDataBits_index_bit_y=new double[MAX_DATA_BITS*2];\r
+       \r
+       public boolean readDataBits(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,PerspectivePixelReader.TThreshold i_th,MarkerPattEncoder o_bitbuffer)throws NyARException\r
+       {\r
+               final int raster_width=i_raster_size.w;\r
+               final int raster_height=i_raster_size.h;\r
+               \r
+               final double[] index_x=this.__readDataBits_index_bit_x;\r
+               final double[] index_y=this.__readDataBits_index_bit_y;\r
+               \r
+\r
+               //読み出し位置を取得\r
+               final int size=detectDataBitsIndex(i_reader,i_raster_size,i_th,index_x,index_y);\r
+               final int resolution=size+size-1;\r
+               if(size<0){\r
+                       return false;\r
+               }\r
+               if(!o_bitbuffer.initEncoder(size-1)){\r
+                       return false;\r
+               }               \r
+               \r
+               final double[] cpara=this._cparam;\r
+               final int[] ref_x=this._ref_x;\r
+               final int[] ref_y=this._ref_y;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               \r
+               final double cpara_0=cpara[0];\r
+               final double cpara_1=cpara[1];\r
+               final double cpara_3=cpara[3];\r
+               final double cpara_6=cpara[6];\r
+               \r
+               \r
+               final int th=i_th.th;\r
+               int p=0;\r
+               for(int i=0;i<resolution;i++){\r
+                       //1列分のピクセルのインデックス値を計算する。\r
+                       double cy0=1+index_y[i*2+0];\r
+                       double cy1=1+index_y[i*2+1];                    \r
+                       double cpy0_12=cpara_1*cy0+cpara[2];\r
+                       double cpy0_45=cpara[4]*cy0+cpara[5];\r
+                       double cpy0_7=cpara[7]*cy0+1.0;\r
+                       double cpy1_12=cpara_1*cy1+cpara[2];\r
+                       double cpy1_45=cpara[4]*cy1+cpara[5];\r
+                       double cpy1_7=cpara[7]*cy1+1.0;\r
+                       \r
+                       int pt=0;\r
+                       for(int i2=0;i2<resolution;i2++)\r
+                       {\r
+                               int xx,yy;\r
+                               double d;\r
+                               double cx0=1+index_x[i2*2+0];\r
+                               double cx1=1+index_x[i2*2+1];\r
+\r
+                               double cp6_0=cpara_6*cx0;\r
+                               double cpx0_0=cpara_0*cx0;\r
+                               double cpx3_0=cpara_3*cx0;\r
+\r
+                               double cp6_1=cpara_6*cx1;\r
+                               double cpx0_1=cpara_0*cx1;\r
+                               double cpx3_1=cpara_3*cx1;\r
+                               \r
+                               d=cp6_0+cpy0_7;\r
+                               ref_x[pt]=xx=(int)((cpx0_0+cpy0_12)/d);\r
+                               ref_y[pt]=yy=(int)((cpx3_0+cpy0_45)/d);\r
+                               if(xx<0 || xx>=raster_width || yy<0 || yy>=raster_height)\r
+                               {\r
+                                       ref_x[pt]=xx<0?0:(xx>=raster_width?raster_width-1:raster_width);\r
+                                       ref_y[pt]=yy<0?0:(yy>=raster_height?raster_height-1:raster_height);\r
+                               }\r
+                               pt++;\r
+\r
+                               d=cp6_0+cpy1_7;\r
+                               ref_x[pt]=xx=(int)((cpx0_0+cpy1_12)/d);\r
+                               ref_y[pt]=yy=(int)((cpx3_0+cpy1_45)/d);\r
+                               if(xx<0 || xx>=raster_width || yy<0 || yy>=raster_height)\r
+                               {\r
+                                       ref_x[pt]=xx<0?0:(xx>=raster_width?raster_width-1:raster_width);\r
+                                       ref_y[pt]=yy<0?0:(yy>=raster_height?raster_height-1:raster_height);\r
+                               }\r
+                               pt++;\r
+\r
+                               d=cp6_1+cpy0_7;\r
+                               ref_x[pt]=xx=(int)((cpx0_1+cpy0_12)/d);\r
+                               ref_y[pt]=yy=(int)((cpx3_1+cpy0_45)/d);\r
+                               if(xx<0 || xx>=raster_width || yy<0 || yy>=raster_height)\r
+                               {\r
+                                       ref_x[pt]=xx<0?0:(xx>=raster_width?raster_width-1:raster_width);\r
+                                       ref_y[pt]=yy<0?0:(yy>=raster_height?raster_height-1:raster_height);\r
+                               }\r
+                               pt++;\r
+\r
+                               d=cp6_1+cpy1_7;\r
+                               ref_x[pt]=xx=(int)((cpx0_1+cpy1_12)/d);\r
+                               ref_y[pt]=yy=(int)((cpx3_1+cpy1_45)/d);\r
+                               if(xx<0 || xx>=raster_width || yy<0 || yy>=raster_height)\r
+                               {\r
+                                       ref_x[pt]=xx<0?0:(xx>=raster_width?raster_width-1:raster_width);\r
+                                       ref_y[pt]=yy<0?0:(yy>=raster_height?raster_height-1:raster_height);\r
+                               }\r
+                               pt++;\r
+                       }\r
+                       //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+                       i_reader.getPixelSet(ref_x,ref_y,resolution*4,pixcel_temp);\r
+                       //グレースケールにしながら、line→mapへの転写\r
+                       for(int i2=0;i2<resolution;i2++){\r
+                               int index=i2*3*4;\r
+                               int pixel=(     pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2]+\r
+                                                       pixcel_temp[index+3]+pixcel_temp[index+4]+pixcel_temp[index+5]+\r
+                                                       pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+\r
+                                                       pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3);\r
+                               //暗点を1、明点を0で表現します。\r
+                               o_bitbuffer.setBitByBitIndex(p,pixel>th?0:1);\r
+                               p++;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+       public boolean setSquare(NyARIntPoint2d[] i_vertex) throws NyARException\r
+       {\r
+               if (!this._param_gen.getParam(READ_RESOLUTION,READ_RESOLUTION,i_vertex,this._cparam)) {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+\r
+}\r
+class MarkerPattDecoder\r
+{\r
+       public void decode(int model,int domain,int mask)\r
+       {\r
+               \r
+       }\r
+}\r
+/**\r
+ * マーカパターンのエンコーダです。\r
+ *\r
+ */\r
+class MarkerPattEncoder\r
+{\r
+       private static final int[] _bit_table_3={\r
+               25,     26,     27,     28,     29,     30,     31,\r
+               48,     9,      10,     11,     12,     13,     32,\r
+               47,     24,     1,      2,      3,      14,     33,\r
+               46,     23,     8,      0,      4,      15,     34,\r
+               45,     22,     7,      6,      5,      16,     35,\r
+               44,     21,     20,     19,     18,     17,     36,\r
+               43,     42,     41,     40,     39,     38,     37\r
+               };      \r
+       private static final int[] _bit_table_2={\r
+               9,      10,     11,     12,     13,\r
+               24,     1,      2,      3,      14,\r
+               23,     8,      0,      4,      15,\r
+               22,     7,      6,      5,      16,\r
+               21,     20,     19,     18,     17};\r
+       private static final int[][] _bit_tables={\r
+               _bit_table_2,_bit_table_3,null,null,null,null,null,\r
+       };\r
+       /**\r
+        * RECT(0):[0]=(0)\r
+        * RECT(1):[1]=(1-8)\r
+        * RECT(2):[2]=(9-16),[3]=(17-24)\r
+        * RECT(3):[4]=(25-32),[5]=(33-40),[6]=(41-48)\r
+        */\r
+       private int[] _bit_table;\r
+       private int[] _bits=new int[16];\r
+       private int[] _work=new int[16];\r
+       private int _model;\r
+       public void setBitByBitIndex(int i_index_no,int i_value)\r
+       {\r
+               assert i_value==0 || i_value==1;\r
+               final int bit_no=this._bit_table[i_index_no];\r
+               if(bit_no==0){\r
+                       this._bits[0]=i_value;\r
+               }else{\r
+                       int bidx=(bit_no-1)/8+1;\r
+                       int sidx=(bit_no-1)%8;\r
+                       this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+               }\r
+               return;\r
+       }\r
+       \r
+       public void setBit(int i_bit_no,int i_value)\r
+       {\r
+               assert i_value==0 || i_value==1;\r
+               if(i_bit_no==0){\r
+                       this._bits[0]=i_value;\r
+               }else{\r
+                       int bidx=(i_bit_no-1)/8+1;\r
+                       int sidx=(i_bit_no-1)%8;\r
+                       this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+               }\r
+               return;\r
+       }\r
+       public int getBit(int i_bit_no)\r
+       {\r
+               if(i_bit_no==0){\r
+                       return this._bits[0];\r
+               }else{\r
+                       int bidx=(i_bit_no-1)/8+1;\r
+                       int sidx=(i_bit_no-1)%8;\r
+                       return (this._bits[bidx]>>(sidx))&(0x01);\r
+               }\r
+       }\r
+       public int getModel()\r
+       {\r
+               return this._model;\r
+       }\r
+       private static int getControlValue(int i_model,int[] i_data)\r
+       {\r
+               int v;\r
+               switch(i_model){\r
+               case 2:\r
+                       v=(i_data[2] & 0x0e)>>1;\r
+                       return v>=5?v-1:v;\r
+               case 3:\r
+                       v=(i_data[4] & 0x3e)>>1;\r
+                       return v>=21?v-1:v;\r
+               case 4:\r
+               case 5:\r
+               case 6:\r
+        case 7:\r
+        default:\r
+            break;\r
+               }\r
+               return -1;\r
+       }\r
+       public static int getCheckValue(int i_model,int[] i_data)\r
+       {\r
+               int v;\r
+               switch(i_model){\r
+               case 2:\r
+                       v=(i_data[2] & 0xe0)>>5;\r
+                       return v>5?v-1:v;\r
+               case 3:\r
+                       v=((i_data[4] & 0x80)>>7) |((i_data[5] & 0x0f)<<1);\r
+                       return v>21?v-1:v;\r
+               case 4:\r
+               case 5:\r
+               case 6:\r
+        case 7:\r
+        default:\r
+            break;\r
+               }\r
+               return -1;\r
+       }\r
+       public boolean initEncoder(int i_model)\r
+       {\r
+               if(i_model>3 || i_model<2){\r
+                       //Lv4以降に対応する時は、この制限を変える。\r
+                       return false;\r
+               }\r
+               this._bit_table=_bit_tables[i_model-2];\r
+               this._model=i_model;\r
+               return true;\r
+       }\r
+       private int getDirection()\r
+       {\r
+               int l,t,r,b;\r
+               int timing_pat;\r
+               switch(this._model){\r
+               case 2:\r
+                       //トラッキングセルを得る\r
+                       t=this._bits[2] & 0x1f;\r
+                       r=((this._bits[2] & 0xf0)>>4)|((this._bits[3]&0x01)<<4);\r
+                       b=this._bits[3] & 0x1f;\r
+                       l=((this._bits[3] & 0xf0)>>4)|((this._bits[2]&0x01)<<4);\r
+                       timing_pat=0x0a;\r
+                       break;\r
+               case 3:\r
+                       t=this._bits[4] & 0x7f;\r
+                       r=((this._bits[4] & 0xc0)>>6)|((this._bits[5] & 0x1f)<<2);\r
+                       b=((this._bits[5] & 0xf0)>>4)|((this._bits[6] & 0x07)<<4);\r
+                       l=((this._bits[6] & 0xfc)>>2)|((this._bits[4] & 0x01)<<6);\r
+                       timing_pat=0x2a;\r
+                       break;\r
+               default:\r
+                       return -3;\r
+               }\r
+               //タイミングパターンの比較\r
+               if(t==timing_pat){\r
+                       if(r==timing_pat){\r
+                               return (b!=timing_pat && l!=timing_pat)?2:-2;\r
+                       }else if(l==timing_pat){\r
+                               return (b!=timing_pat && r!=timing_pat)?3:-2;\r
+                       }\r
+               }else if(b==timing_pat){\r
+                       if(r==timing_pat){\r
+                               return (t!=timing_pat && l!=timing_pat)?1:-2;\r
+                       }else if(l==timing_pat){\r
+                               return (t!=timing_pat && r!=timing_pat)?0:-2;\r
+                       }\r
+               }\r
+               return -1;\r
+       }\r
+       /**\r
+        * 格納しているマーカパターンをエンコードして、マーカデータを返します。\r
+        * @param o_out\r
+        * @return\r
+        * 成功すればマーカの方位を返却します。失敗すると-1を返します。\r
+        */\r
+\r
+       public int encode(NyIdMarkerPattern o_out)\r
+       {\r
+               final int d=getDirection();\r
+               if(d<0){\r
+                       return -1;\r
+               }\r
+               //回転ビットの取得\r
+               getRotatedBits(d,o_out.data);\r
+               final int model=this._model;\r
+               //周辺ビットの取得\r
+               o_out.model=model;\r
+               int control_bits=getControlValue(model,o_out.data);\r
+               o_out.check=getCheckValue(model,o_out.data);\r
+               o_out.ctrl_mask=control_bits%5;\r
+               o_out.ctrl_domain=control_bits/5;\r
+               if(o_out.ctrl_domain!=0 || o_out.ctrl_mask!=0){\r
+                       return -1;\r
+               }\r
+               //マスク解除処理を実装すること\r
+               return d;\r
+       }\r
+       private void getRotatedBits(int i_direction,int[] o_out)\r
+       {\r
+               int sl=i_direction*2;\r
+               int sr=8-sl;\r
+\r
+               int w1;\r
+               o_out[0]=this._bits[0];\r
+               //RECT1\r
+               w1=this._bits[1];\r
+               o_out[1]=((w1<<sl)|(w1>>sr))& 0xff;\r
+               \r
+               //RECT2\r
+               sl=i_direction*4;\r
+               sr=16-sl;\r
+               w1=this._bits[2]|(this._bits[3]<<8);\r
+               w1=(w1<<sl)|(w1>>sr);\r
+               o_out[2]=w1 & 0xff;\r
+               o_out[3]=(w1>>8) & 0xff;\r
+\r
+               if(this._model<2){\r
+                       return;\r
+               }\r
+\r
+               //RECT3\r
+               sl=i_direction*6;\r
+               sr=24-sl;                       \r
+               w1=this._bits[4]|(this._bits[5]<<8)|(this._bits[6]<<16);\r
+               w1=(w1<<sl)|(w1>>sr);\r
+               o_out[4]=w1 & 0xff;\r
+               o_out[5]=(w1>>8) & 0xff;\r
+               o_out[6]=(w1>>16) & 0xff;\r
+               \r
+               if(this._model<3){\r
+                       return;\r
+               }\r
+               //RECT4(Lv4以降はここの制限を変える)\r
+//             shiftLeft(this._bits,7,3,i_direction*8);\r
+//             if(this._model<4){\r
+//                     return;\r
+//             }\r
+               return;\r
+       }\r
+       public void shiftLeft(int[] i_pack,int i_start,int i_length,int i_ls)\r
+       {\r
+               int[] work=this._work;\r
+               //端数シフト\r
+               final int mod_shift=i_ls%8;\r
+               for(int i=i_length-1;i>=1;i--){\r
+                       work[i]=(i_pack[i+i_start]<<mod_shift)|(0xff&(i_pack[i+i_start-1]>>(8-mod_shift)));\r
+               }\r
+               work[0]=(i_pack[i_start]<<mod_shift)|(0xff&(i_pack[i_start+i_length-1]>>(8-mod_shift)));\r
+               //バイトシフト\r
+               final int byte_shift=(i_ls/8)%i_length;\r
+               for(int i=i_length-1;i>=0;i--){\r
+                       i_pack[(byte_shift+i)%i_length+i_start]=0xff & work[i];\r
+               }\r
+               return;\r
+       }       \r
+}\r
+/**\r
+ * ラスタ画像の任意矩形から、NyARIdMarkerDataを抽出します。\r
+ *\r
+ */\r
+public class NyIdMarkerPickup\r
+{\r
+       private PerspectivePixelReader _perspective_reader;\r
+       private final PerspectivePixelReader.TThreshold __pickFromRaster_th=new PerspectivePixelReader.TThreshold();\r
+       private final MarkerPattEncoder __pickFromRaster_encoder=new MarkerPattEncoder();\r
+\r
+\r
+       public NyIdMarkerPickup()\r
+       {\r
+               this._perspective_reader=new PerspectivePixelReader();\r
+               return;\r
+       }\r
+       /**\r
+        * imageの4頂点で囲まれた矩形からidマーカを読みだします。\r
+        * @param image\r
+        * @param i_vertex\r
+        * @param o_data\r
+        * @param o_param\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public final boolean pickFromRaster(INyARRgbRaster image, NyARDoublePoint2d[] i_vertex,NyIdMarkerPattern o_data,NyIdMarkerParam o_param)throws NyARException\r
+       {\r
+               //遠近法のパラメータを計算\r
+               if(!this._perspective_reader.setSourceSquare(i_vertex)){\r
+                       return false;\r
+               }\r
+               return this._pickFromRaster(image,o_data,o_param);\r
+       }\r
+       /**\r
+        * imageの4頂点で囲まれた矩形からidマーカを読みだします。\r
+        * @param image\r
+        * @param i_vertex\r
+        * @param o_data\r
+        * @param o_param\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public final boolean pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertex,NyIdMarkerPattern o_data,NyIdMarkerParam o_param)throws NyARException\r
+       {\r
+               if(!this._perspective_reader.setSourceSquare(i_vertex)){\r
+                       return false;\r
+               }\r
+               return this._pickFromRaster(image,o_data,o_param);\r
+       }\r
+       \r
+       /**\r
+        * i_imageから、idマーカを読みだします。\r
+        * o_dataにはマーカデータ、o_paramにはマーカのパラメータを返却します。\r
+        * @param image\r
+        * @param i_vertex\r
+        * @param o_data\r
+        * @param o_param\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       private final boolean _pickFromRaster(INyARRgbRaster image, NyIdMarkerPattern o_data,NyIdMarkerParam o_param)throws NyARException\r
+       {\r
+               INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+               NyARIntSize raster_size=image.getSize();\r
+\r
+               final PerspectivePixelReader.TThreshold th=this.__pickFromRaster_th;\r
+               final MarkerPattEncoder encoder=this.__pickFromRaster_encoder;\r
+               //マーカパラメータを取得\r
+               this._perspective_reader.detectThresholdValue(reader,raster_size,th);\r
+\r
+               if(!this._perspective_reader.readDataBits(reader,raster_size,th, encoder)){\r
+                       return false;\r
+               }\r
+               final int d=encoder.encode(o_data);\r
+               if(d<0){\r
+                       return false;\r
+               }\r
+               o_param.direction=d;\r
+               o_param.threshold=th.th;\r
+               \r
+               return true;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerData.java b/lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerData.java
new file mode 100644 (file)
index 0000000..1e6edd2
--- /dev/null
@@ -0,0 +1,47 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+/**\r
+ * \r
+ * [[Strage class]]\r
+ *\r
+ */\r
+public interface INyIdMarkerData\r
+{\r
+       /**\r
+        * i_targetのマーカデータと自身のデータが等しいかを返します。\r
+        * @param i_target\r
+        * 比較するマーカオブジェクト\r
+        * @return\r
+        * 等しいかの真偽値\r
+        */\r
+       public boolean isEqual(INyIdMarkerData i_target);\r
+       /**\r
+        * i_sourceからマーカデータをコピーします。\r
+        * @param i_source\r
+        */\r
+       public void copyFrom(INyIdMarkerData i_source);\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerDataEncoder.java b/lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerDataEncoder.java
new file mode 100644 (file)
index 0000000..329ea1b
--- /dev/null
@@ -0,0 +1,34 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+import jp.nyatla.nyartoolkit.nyidmarker.NyIdMarkerPattern;\r
+\r
+\r
+public interface INyIdMarkerDataEncoder\r
+{\r
+       public boolean encode(NyIdMarkerPattern i_data,INyIdMarkerData o_dest);\r
+       public INyIdMarkerData createDataInstance();\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerDataEncoder_RawBit.java b/lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerDataEncoder_RawBit.java
new file mode 100644 (file)
index 0000000..5f851b9
--- /dev/null
@@ -0,0 +1,61 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+\r
+\r
+public class NyIdMarkerDataEncoder_RawBit implements INyIdMarkerDataEncoder\r
+{      \r
+       private final static int _DOMAIN_ID=0;\r
+       private final static int[] _mod_data={7,31,127,511,2047,4095};\r
+       public boolean encode(NyIdMarkerPattern i_data,INyIdMarkerData o_dest)\r
+       {\r
+               final NyIdMarkerData_RawBit dest=(NyIdMarkerData_RawBit)o_dest;\r
+               if(i_data.ctrl_domain!=_DOMAIN_ID){\r
+                       return false;\r
+               }\r
+               //パケット数計算\r
+               final int resolution_len=(i_data.model+i_data.model-1);      //データドットの数\r
+               final int packet_length=(resolution_len*resolution_len)/8+1;\r
+               int sum=0;\r
+               for(int i=0;i<packet_length;i++){\r
+                       dest.packet[i]=i_data.data[i];\r
+                       sum+=i_data.data[i];\r
+               }\r
+               //チェックドット値計算\r
+               sum=sum%_mod_data[i_data.model-2];\r
+               //チェックドット比較\r
+               if(i_data.check!=sum){\r
+                       return false;\r
+               }\r
+               dest.length=packet_length;\r
+               return true;\r
+       }\r
+       public INyIdMarkerData createDataInstance()\r
+       {\r
+               return new NyIdMarkerData_RawBit();\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerData_RawBit.java b/lib/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerData_RawBit.java
new file mode 100644 (file)
index 0000000..832b432
--- /dev/null
@@ -0,0 +1,55 @@
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+/**\r
+ * [[Strage class]]\r
+ *\r
+ */\r
+public class NyIdMarkerData_RawBit implements INyIdMarkerData\r
+{\r
+       public final int[] packet=new int[22];\r
+       public int length;\r
+       public boolean isEqual(INyIdMarkerData i_target)\r
+       {\r
+               NyIdMarkerData_RawBit s=(NyIdMarkerData_RawBit)i_target;\r
+               if(s.length!=this.length){\r
+                       return false;\r
+               }\r
+               for(int i=s.length-1;i>=0;i--){\r
+                       if(s.packet[i]!=this.packet[i]){\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+       public void copyFrom(INyIdMarkerData i_source)\r
+       {\r
+               final NyIdMarkerData_RawBit s=(NyIdMarkerData_RawBit)i_source;\r
+               System.arraycopy(s.packet,0,this.packet,0,s.length);\r
+               this.length=s.length;\r
+               return;\r
+       }\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/processor/SingleARMarkerProcesser.java b/lib/src/jp/nyatla/nyartoolkit/processor/SingleARMarkerProcesser.java
new file mode 100644 (file)
index 0000000..f5c1b94
--- /dev/null
@@ -0,0 +1,363 @@
+/* \r
+ * Capture Test NyARToolkitCSサンプルプログラム\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.processor;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.analyzer.raster.threshold.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+/**\r
+ * このクラスは、同時に1個のマーカを処理することのできる、アプリケーションプロセッサです。\r
+ * マーカの出現・移動・消滅を、イベントで通知することができます。\r
+ * クラスには複数のマーカを登録できます。一つのマーカが見つかると、プロセッサは継続して同じマーカを\r
+ * 1つだけ認識し続け、見失うまでの間は他のマーカを認識しません。\r
+ * \r
+ * イベントは、 OnEnter→OnUpdate[n]→OnLeaveの順で発生します。\r
+ * マーカが見つかるとまずOnEnterが1度発生して、何番のマーカが発見されたかがわかります。\r
+ * 次にOnUpdateにより、現在の変換行列が連続して渡されます。最後にマーカを見失うと、OnLeave\r
+ * イベントが発生します。\r
+ * \r
+ */\r
+public abstract class SingleARMarkerProcesser\r
+{\r
+       /**\r
+        * detectMarkerのコールバック関数\r
+        */\r
+       private class DetectSquare extends NyARSquareContourDetector_Rle\r
+       {\r
+               //公開プロパティ\r
+               public final NyARSquare square=new NyARSquare();\r
+               public double confidence=0.0;\r
+               public int code_index=-1;               \r
+               public double cf_threshold_new = 0.50;\r
+               public double cf_threshold_exist = 0.30;\r
+               \r
+               //参照\r
+               private INyARRgbRaster _ref_raster;\r
+               //所有インスタンス\r
+               private INyARColorPatt _inst_patt;\r
+               private NyARMatchPattDeviationColorData _deviation_data;\r
+               private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt;\r
+               private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+               private NyARCoord2Linear _coordline;\r
+               private int _raster_type;\r
+               \r
+               public DetectSquare(NyARParam i_param,int i_raster_type) throws NyARException\r
+               {\r
+                       super(i_param.getScreenSize());\r
+                       this._match_patt=null;\r
+                       this._coordline=new NyARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+                       this._raster_type=i_raster_type;\r
+                       return;\r
+               }\r
+               public void setNyARCodeTable(NyARCode[] i_ref_code,int i_code_resolution)\r
+               {\r
+                       /*unmanagedで実装するときは、ここでリソース解放をすること。*/\r
+                       this._deviation_data=new NyARMatchPattDeviationColorData(i_code_resolution,i_code_resolution);\r
+                       this._inst_patt=new NyARColorPatt_Perspective_O2(i_code_resolution,i_code_resolution,4,25,this._raster_type);\r
+                       this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA[i_ref_code.length];\r
+                       for(int i=0;i<i_ref_code.length;i++){\r
+                               this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);\r
+                       }\r
+               }\r
+               private NyARIntPoint2d[] __ref_vertex=new NyARIntPoint2d[4];\r
+               private int _target_id;\r
+               /**\r
+                * Initialize call back handler.\r
+                */\r
+               public void init(INyARRgbRaster i_raster,int i_target_id)\r
+               {\r
+                       this._ref_raster=i_raster;\r
+                       this._target_id=i_target_id;\r
+                       this.code_index=-1;\r
+                       this.confidence=Double.MIN_VALUE;\r
+               }\r
+\r
+               /**\r
+                * 矩形が見付かるたびに呼び出されます。\r
+                * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+                */\r
+               protected void onSquareDetect(NyARIntCoordinates i_coord,int[] i_vertex_index)  throws NyARException\r
+               {\r
+                       if (this._match_patt==null) {\r
+                               return;\r
+                       }\r
+                       //輪郭座標から頂点リストに変換\r
+                       NyARIntPoint2d[] vertex=this.__ref_vertex;\r
+                       vertex[0]=i_coord.items[i_vertex_index[0]];\r
+                       vertex[1]=i_coord.items[i_vertex_index[1]];\r
+                       vertex[2]=i_coord.items[i_vertex_index[2]];\r
+                       vertex[3]=i_coord.items[i_vertex_index[3]];\r
+               \r
+                       //画像を取得\r
+                       if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){\r
+                               return;//取得失敗\r
+                       }\r
+                       //取得パターンをカラー差分データに変換して評価する。\r
+                       this._deviation_data.setRaster(this._inst_patt);\r
+\r
+                       \r
+                       //code_index,dir,c1にデータを得る。\r
+                       final NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+                       int lcode_index = 0;\r
+                       int dir = 0;\r
+                       double c1 = 0;\r
+                       for (int i = 0; i < this._match_patt.length; i++) {\r
+                               this._match_patt[i].evaluate(this._deviation_data,mr);\r
+                               double c2 = mr.confidence;\r
+                               if (c1 < c2) {\r
+                                       lcode_index = i;\r
+                                       c1 = c2;\r
+                                       dir = mr.direction;\r
+                               }\r
+                       }\r
+                       \r
+                       //認識処理\r
+                       if (this._target_id == -1) { // マーカ未認識\r
+                               //現在は未認識\r
+                               if (c1 < this.cf_threshold_new) {\r
+                                       return;\r
+                               }\r
+                               if (this.confidence > c1) {\r
+                                       // 一致度が低い。\r
+                                       return;\r
+                               }\r
+                               //認識しているマーカIDを保存\r
+                               this.code_index=lcode_index;\r
+                       }else{\r
+                               //現在はマーカ認識中                           \r
+                               // 現在のマーカを認識したか?\r
+                               if (lcode_index != this._target_id) {\r
+                                       // 認識中のマーカではないので無視\r
+                                       return;\r
+                               }\r
+                               //認識中の閾値より大きいか?\r
+                               if (c1 < this.cf_threshold_exist) {\r
+                                       return;\r
+                               }\r
+                               //現在の候補よりも一致度は大きいか?\r
+                               if (this.confidence>c1) {\r
+                                       return;\r
+                               }\r
+                               this.code_index=this._target_id;\r
+                       }\r
+                       //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。\r
+                       //ココから先はこの条件でしか実行されない。\r
+                       \r
+                       //一致率の高い矩形があれば、方位を考慮して頂点情報を作成\r
+                       this.confidence=c1;\r
+                       NyARSquare sq=this.square;\r
+                       //directionを考慮して、squareを更新する。\r
+                       for(int i=0;i<4;i++){\r
+                               int idx=(i+4 - dir) % 4;\r
+                               this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coord,sq.line[i]);\r
+                       }\r
+                       for (int i = 0; i < 4; i++) {\r
+                               //直線同士の交点計算\r
+                               if(!sq.line[i].crossPos(sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+                                       throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+                               }\r
+                       }\r
+               }\r
+       }       \r
+       /**オーナーが自由に使えるタグ変数です。\r
+        */\r
+       public Object tag;\r
+\r
+       private int _lost_delay_count = 0;\r
+\r
+       private int _lost_delay = 5;\r
+\r
+       protected INyARTransMat _transmat;\r
+\r
+       private NyARRectOffset _offset; \r
+       private int _threshold = 110;\r
+       // [AR]検出結果の保存用\r
+       private NyARBinRaster _bin_raster;\r
+\r
+       private NyARRasterFilter_ARToolkitThreshold _tobin_filter;\r
+\r
+       protected int _current_arcode_index = -1;\r
+\r
+       private NyARRasterThresholdAnalyzer_SlidePTile _threshold_detect;\r
+       \r
+       protected SingleARMarkerProcesser()\r
+       {\r
+               return;\r
+       }\r
+\r
+       private boolean _initialized=false;\r
+\r
+       protected void initInstance(NyARParam i_param,int i_raster_type) throws NyARException\r
+       {\r
+               //初期化済?\r
+               assert(this._initialized==false);\r
+               \r
+               NyARIntSize scr_size = i_param.getScreenSize();\r
+               // 解析オブジェクトを作る\r
+               this._transmat = new NyARTransMat(i_param);\r
+               this._tobin_filter=new NyARRasterFilter_ARToolkitThreshold(110,i_raster_type);\r
+\r
+               // 2値画像バッファを作る\r
+               this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h);\r
+               this._threshold_detect=new NyARRasterThresholdAnalyzer_SlidePTile(15,i_raster_type,4);\r
+               this._initialized=true;\r
+               //コールバックハンドラ\r
+               this._detectmarker=new DetectSquare(i_param,i_raster_type);\r
+               this._offset=new NyARRectOffset();\r
+               return;\r
+       }\r
+\r
+       /*自動・手動の設定が出来ないので、コメントアウト\r
+       public void setThreshold(int i_threshold)\r
+       {\r
+               this._threshold = i_threshold;\r
+               return;\r
+       }*/\r
+\r
+       /**検出するマーカコードの配列を指定します。 検出状態でこの関数を実行すると、\r
+        * オブジェクト状態に強制リセットがかかります。\r
+        */\r
+       public void setARCodeTable(NyARCode[] i_ref_code_table, int i_code_resolution, double i_marker_width)\r
+       {\r
+               if (this._current_arcode_index != -1) {\r
+                       // 強制リセット\r
+                       reset(true);\r
+               }\r
+               //検出するマーカセット、情報、検出器を作り直す。(1ピクセル4ポイントサンプリング,マーカのパターン領域は50%)\r
+               this._detectmarker.setNyARCodeTable(i_ref_code_table,i_code_resolution);\r
+               this._offset.setSquare(i_marker_width);\r
+               return;\r
+       }\r
+\r
+       public void reset(boolean i_is_force)\r
+       {\r
+               if (this._current_arcode_index != -1 && i_is_force == false) {\r
+                       // 強制書き換えでなければイベントコール\r
+                       this.onLeaveHandler();\r
+               }\r
+               // カレントマーカをリセット\r
+               this._current_arcode_index = -1;\r
+               return;\r
+       }\r
+       private DetectSquare _detectmarker;\r
+       public void detectMarker(INyARRgbRaster i_raster) throws NyARException\r
+       {\r
+               // サイズチェック\r
+               assert(this._bin_raster.getSize().isEqualSize(i_raster.getSize().w, i_raster.getSize().h));\r
+\r
+               //BINイメージへの変換\r
+               this._tobin_filter.setThreshold(this._threshold);\r
+               this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
+\r
+               // スクエアコードを探す\r
+               this._detectmarker.init(i_raster,this._current_arcode_index);\r
+               this._detectmarker.detectMarker(this._bin_raster);\r
+               \r
+               // 認識状態を更新\r
+               final boolean is_id_found=this.updateStatus(this._detectmarker.square,this._detectmarker.code_index);\r
+               //閾値フィードバック(detectExistMarkerにもあるよ)\r
+               if(!is_id_found){\r
+                       //マーカがなければ、探索+DualPTailで基準輝度検索\r
+                       int th=this._threshold_detect.analyzeRaster(i_raster);\r
+                       this._threshold=(this._threshold+th)/2;\r
+               }\r
+               \r
+               \r
+               return;\r
+       }\r
+       /**\r
+        * \r
+        * @param i_new_detect_cf\r
+        * @param i_exist_detect_cf\r
+        */\r
+       public void setConfidenceThreshold(double i_new_cf,double i_exist_cf)\r
+       {\r
+               this._detectmarker.cf_threshold_exist=i_exist_cf;\r
+               this._detectmarker.cf_threshold_new=i_new_cf;\r
+       }\r
+\r
+       private NyARTransMatResult __NyARSquare_result = new NyARTransMatResult();\r
+\r
+       /**     オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。\r
+        *      戻り値は、「実際にマーカを発見する事ができたか」です。クラスの状態とは異なります。\r
+        */\r
+       private boolean updateStatus(NyARSquare i_square, int i_code_index)  throws NyARException\r
+       {\r
+               NyARTransMatResult result = this.__NyARSquare_result;\r
+               if (this._current_arcode_index < 0) {// 未認識中\r
+                       if (i_code_index < 0) {// 未認識から未認識の遷移\r
+                               // なにもしないよーん。\r
+                               return false;\r
+                       } else {// 未認識から認識の遷移\r
+                               this._current_arcode_index = i_code_index;\r
+                               // イベント生成\r
+                               // OnEnter\r
+                               this.onEnterHandler(i_code_index);\r
+                               // 変換行列を作成\r
+                               this._transmat.transMat(i_square, this._offset, result);\r
+                               // OnUpdate\r
+                               this.onUpdateHandler(i_square, result);\r
+                               this._lost_delay_count = 0;\r
+                               return true;\r
+                       }\r
+               } else {// 認識中\r
+                       if (i_code_index < 0) {// 認識から未認識の遷移\r
+                               this._lost_delay_count++;\r
+                               if (this._lost_delay < this._lost_delay_count) {\r
+                                       // OnLeave\r
+                                       this._current_arcode_index = -1;\r
+                                       this.onLeaveHandler();\r
+                               }\r
+                               return false;\r
+                       } else if (i_code_index == this._current_arcode_index) {// 同じARCodeの再認識\r
+                               // イベント生成\r
+                               // 変換行列を作成\r
+                               this._transmat.transMatContinue(i_square, this._offset, result,result);\r
+                               // OnUpdate\r
+                               this.onUpdateHandler(i_square, result);\r
+                               this._lost_delay_count = 0;\r
+                               return true;\r
+                       } else {// 異なるコードの認識→今はサポートしない。\r
+                               throw new  NyARException();\r
+                       }\r
+               }\r
+       }\r
+\r
+       protected abstract void onEnterHandler(int i_code);\r
+\r
+       protected abstract void onLeaveHandler();\r
+\r
+       protected abstract void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result);\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/processor/SingleNyIdMarkerProcesser.java b/lib/src/jp/nyatla/nyartoolkit/processor/SingleNyIdMarkerProcesser.java
new file mode 100644 (file)
index 0000000..75597d1
--- /dev/null
@@ -0,0 +1,295 @@
+/* \r
+ * Capture Test NyARToolkitサンプルプログラム\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.processor;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.analyzer.raster.threshold.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.data.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+public abstract class SingleNyIdMarkerProcesser\r
+{\r
+       /**\r
+        * Rleラ矩形Detectorのブリッジ\r
+        *\r
+        */\r
+       private class RleDetector extends NyARSquareContourDetector_Rle\r
+       {\r
+               //公開プロパティ\r
+               public final NyARSquare square=new NyARSquare();\r
+               public INyIdMarkerData marker_data;\r
+               public int threshold;\r
+\r
+               \r
+               //参照\r
+               private INyARRgbRaster _ref_raster;\r
+               //所有インスタンス\r
+               private INyIdMarkerData _current_data;\r
+               private final NyIdMarkerPickup _id_pickup = new NyIdMarkerPickup();\r
+               private NyARCoord2Linear _coordline;\r
+               private INyIdMarkerDataEncoder _encoder;\r
+\r
+               \r
+               private INyIdMarkerData _data_temp;\r
+               private INyIdMarkerData _prev_data;\r
+               \r
+               public RleDetector(NyARParam i_param,INyIdMarkerDataEncoder i_encoder) throws NyARException\r
+               {\r
+                       super(i_param.getScreenSize());\r
+                       this._coordline=new NyARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+                       this._data_temp=i_encoder.createDataInstance();\r
+                       this._current_data=i_encoder.createDataInstance();\r
+                       this._encoder=i_encoder;\r
+                       return;\r
+               }\r
+               private NyARIntPoint2d[] __ref_vertex=new NyARIntPoint2d[4];\r
+               /**\r
+                * Initialize call back handler.\r
+                */\r
+               public void init(INyARRgbRaster i_raster,INyIdMarkerData i_prev_data)\r
+               {\r
+                       this.marker_data=null;\r
+                       this._prev_data=i_prev_data;\r
+                       this._ref_raster=i_raster;\r
+               }\r
+               private final NyIdMarkerParam _marker_param=new NyIdMarkerParam();\r
+               private final NyIdMarkerPattern _marker_data=new NyIdMarkerPattern();\r
+\r
+               /**\r
+                * 矩形が見付かるたびに呼び出されます。\r
+                * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+                */\r
+               protected void onSquareDetect(NyARIntCoordinates i_coord,int[] i_vertex_index)  throws NyARException\r
+               {\r
+                       //既に発見済なら終了\r
+                       if(this.marker_data!=null){\r
+                               return;\r
+                       }\r
+                       //輪郭座標から頂点リストに変換\r
+                       NyARIntPoint2d[] vertex=this.__ref_vertex;\r
+                       vertex[0]=i_coord.items[i_vertex_index[0]];\r
+                       vertex[1]=i_coord.items[i_vertex_index[1]];\r
+                       vertex[2]=i_coord.items[i_vertex_index[2]];\r
+                       vertex[3]=i_coord.items[i_vertex_index[3]];\r
+               \r
+                       NyIdMarkerParam param=this._marker_param;\r
+                       NyIdMarkerPattern patt_data  =this._marker_data;                        \r
+                       // 評価基準になるパターンをイメージから切り出す\r
+                       if (!this._id_pickup.pickFromRaster(this._ref_raster,vertex, patt_data, param)){\r
+                               return;\r
+                       }\r
+                       //エンコード\r
+                       if(!this._encoder.encode(patt_data,this._data_temp)){\r
+                               return;\r
+                       }\r
+\r
+                       //継続認識要求されている?\r
+                       if (this._prev_data==null){\r
+                               //継続認識要求なし\r
+                               this._current_data.copyFrom(this._data_temp);\r
+                       }else{\r
+                               //継続認識要求あり\r
+                               if(!this._prev_data.isEqual((this._data_temp))){\r
+                                       return;//認識請求のあったIDと違う。\r
+                               }\r
+                       }\r
+                       //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。\r
+                       //ココから先はこの条件でしか実行されない。\r
+                       NyARSquare sq=this.square;\r
+                       //directionを考慮して、squareを更新する。\r
+                       for(int i=0;i<4;i++){\r
+                               int idx=(i+4 - param.direction) % 4;\r
+                               this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coord,sq.line[i]);\r
+                       }\r
+                       for (int i = 0; i < 4; i++) {\r
+                               //直線同士の交点計算\r
+                               if(!sq.line[i].crossPos(sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+                                       throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+                               }\r
+                       }\r
+                       this.threshold=param.threshold;\r
+                       this.marker_data=this._current_data;//みつかった。\r
+               }       \r
+       }       \r
+\r
+       \r
+       /**\r
+        * オーナーが自由に使えるタグ変数です。\r
+        */\r
+       public Object tag;\r
+\r
+       /**\r
+        * ロスト遅延の管理\r
+        */\r
+       private int _lost_delay_count = 0;\r
+       private int _lost_delay = 5;\r
+\r
+       private RleDetector _square_detect;\r
+       protected INyARTransMat _transmat;\r
+       private NyARRectOffset _offset; \r
+       private boolean _is_active;\r
+       private int _current_threshold=110;\r
+       // [AR]検出結果の保存用\r
+       private NyARBinRaster _bin_raster;\r
+       private NyARRasterFilter_ARToolkitThreshold _tobin_filter;\r
+       private INyIdMarkerData _data_current;\r
+\r
+\r
+       protected SingleNyIdMarkerProcesser()\r
+       {\r
+               return;\r
+       }\r
+       private boolean _initialized=false;\r
+       protected void initInstance(NyARParam i_param,INyIdMarkerDataEncoder i_encoder,double i_marker_width,int i_raster_format) throws NyARException\r
+       {\r
+               //初期化済?\r
+               assert(this._initialized==false);\r
+               \r
+               NyARIntSize scr_size = i_param.getScreenSize();\r
+               // 解析オブジェクトを作る\r
+               this._square_detect = new RleDetector(i_param,i_encoder);\r
+               this._transmat = new NyARTransMat(i_param);\r
+\r
+               // 2値画像バッファを作る\r
+               this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h);\r
+               //ワーク用のデータオブジェクトを2個作る\r
+               this._data_current=i_encoder.createDataInstance();\r
+               this._tobin_filter =new NyARRasterFilter_ARToolkitThreshold(110,i_raster_format);\r
+               this._threshold_detect=new NyARRasterThresholdAnalyzer_SlidePTile(15,i_raster_format,4);\r
+               this._initialized=true;\r
+               this._is_active=false;\r
+               this._offset=new NyARRectOffset();\r
+               this._offset.setSquare(i_marker_width);\r
+               return;\r
+               \r
+       }\r
+\r
+       public void setMarkerWidth(int i_width)\r
+       {\r
+               this._offset.setSquare(i_width);\r
+               return;\r
+       }\r
+\r
+       public void reset(boolean i_is_force)\r
+       {\r
+               if (i_is_force == false && this._is_active){\r
+                       // 強制書き換えでなければイベントコール\r
+                       this.onLeaveHandler();\r
+               }\r
+               //マーカ無効\r
+               this._is_active=false;\r
+               return;\r
+       }\r
+\r
+       public void detectMarker(INyARRgbRaster i_raster) throws NyARException\r
+       {\r
+               // サイズチェック\r
+               if (!this._bin_raster.getSize().isEqualSize(i_raster.getSize().w, i_raster.getSize().h)) {\r
+                       throw new NyARException();\r
+               }\r
+               // ラスタを2値イメージに変換する.\r
+               this._tobin_filter.setThreshold(this._current_threshold);\r
+               this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
+\r
+               // スクエアコードを探す(第二引数に指定したマーカ、もしくは新しいマーカを探す。)\r
+               this._square_detect.init(i_raster,this._is_active?this._data_current:null);\r
+               this._square_detect.detectMarker(this._bin_raster);\r
+\r
+               // 認識状態を更新(マーカを発見したなら、current_dataを渡すかんじ)\r
+               final boolean is_id_found=updateStatus(this._square_detect.square,this._square_detect.marker_data);\r
+\r
+               //閾値フィードバック(detectExistMarkerにもあるよ)\r
+               if(is_id_found){\r
+                       //マーカがあれば、マーカの周辺閾値を反映\r
+                       this._current_threshold=(this._current_threshold+this._square_detect.threshold)/2;\r
+               }else{\r
+                       //マーカがなければ、探索+DualPTailで基準輝度検索\r
+                       int th=this._threshold_detect.analyzeRaster(i_raster);\r
+                       this._current_threshold=(this._current_threshold+th)/2;\r
+               }               \r
+               return;\r
+       }\r
+\r
+       \r
+       private NyARRasterThresholdAnalyzer_SlidePTile _threshold_detect;\r
+       private NyARTransMatResult __NyARSquare_result = new NyARTransMatResult();\r
+\r
+       /**オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。\r
+        */\r
+       private boolean updateStatus(NyARSquare i_square, INyIdMarkerData i_marker_data)  throws NyARException\r
+       {\r
+               boolean is_id_found=false;\r
+               NyARTransMatResult result = this.__NyARSquare_result;\r
+               if (!this._is_active) {// 未認識中\r
+                       if (i_marker_data==null) {// 未認識から未認識の遷移\r
+                               // なにもしないよーん。\r
+                               this._is_active=false;\r
+                       } else {// 未認識から認識の遷移\r
+                               this._data_current.copyFrom(i_marker_data);\r
+                               // イベント生成\r
+                               // OnEnter\r
+                               this.onEnterHandler(this._data_current);\r
+                               // 変換行列を作成\r
+                               this._transmat.transMat(i_square, this._offset, result);\r
+                               // OnUpdate\r
+                               this.onUpdateHandler(i_square, result);\r
+                               this._lost_delay_count = 0;\r
+                               this._is_active=true;\r
+                               is_id_found=true;\r
+                       }\r
+               } else {// 認識中\r
+                       if (i_marker_data==null) {\r
+                               // 認識から未認識の遷移\r
+                               this._lost_delay_count++;\r
+                               if (this._lost_delay < this._lost_delay_count) {\r
+                                       // OnLeave\r
+                                       this.onLeaveHandler();\r
+                                       this._is_active=false;\r
+                               }\r
+                       } else if(this._data_current.isEqual(i_marker_data)) {\r
+                               //同じidの再認識\r
+                               this._transmat.transMatContinue(i_square, this._offset, result,result);\r
+                               // OnUpdate\r
+                               this.onUpdateHandler(i_square, result);\r
+                               this._lost_delay_count = 0;\r
+                               is_id_found=true;\r
+                       } else {// 異なるコードの認識→今はサポートしない。\r
+                               throw new  NyARException();\r
+                       }\r
+               }\r
+               return is_id_found;\r
+       }       \r
+       //通知ハンドラ\r
+       protected abstract void onEnterHandler(INyIdMarkerData i_code);\r
+       protected abstract void onLeaveHandler();\r
+       protected abstract void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result);\r
+}\r
diff --git a/lib/src/jp/nyatla/nyartoolkit/utils/TransformedBitmapPickup.java b/lib/src/jp/nyatla/nyartoolkit/utils/TransformedBitmapPickup.java
new file mode 100644 (file)
index 0000000..feb8478
--- /dev/null
@@ -0,0 +1,116 @@
+package jp.nyatla.nyartoolkit.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARPerspectiveProjectionMatrix;\r
+import jp.nyatla.nyartoolkit.core.pickup.NyARColorPatt_Perspective_O2;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * マーカの周辺領域からビットマップを取得する方法を提供します。\r
+ * 比較的負荷が大きいので、連続してパターンを取得し続ける用途には向いていません。\r
+ *\r
+ */\r
+class TransformedBitmapPickup extends NyARColorPatt_Perspective_O2\r
+{\r
+       private NyARIntPoint2d[] _work_points = NyARIntPoint2d.createArray(4);\r
+\r
+       private NyARPerspectiveProjectionMatrix _ref_perspective;\r
+\r
+       /**\r
+        * \r
+        * @param i_width\r
+        * 取得するビットマップの幅\r
+        * @param i_height\r
+        * 取得するビットマップの解像度\r
+        * @param i_resolution\r
+        * resolution of reading pixel per point. ---- 取得時の解像度。高解像度のときは1を指定してください。低解像度のときは2以上を指定します。\r
+        */\r
+       public TransformedBitmapPickup(NyARPerspectiveProjectionMatrix i_ref_cparam, int i_width, int i_height, int i_resolution)\r
+       {\r
+               //ANYラスタで構築\r
+               super(i_width, i_height, i_resolution, 0,NyARBufferType.NULL_ALLZERO);\r
+               this._ref_perspective = i_ref_cparam;\r
+       }\r
+\r
+       /**\r
+        * This function retrieves bitmap from the area defined by RECT(i_l,i_t,i_r,i_b) above transform matrix i_base_mat. \r
+        * ----\r
+        * この関数は、basementで示される平面のAで定義される領域から、ビットマップを読み出します。\r
+        * 例えば、8cmマーカでRECT(i_l,i_t,i_r,i_b)に-40,0,0,-40.0を指定すると、マーカの左下部分の画像を抽出します。\r
+        * \r
+        * マーカから離れた場所になるほど、また、マーカの鉛直方向から外れるほど誤差が大きくなります。\r
+        * @param i_src_imege\r
+        * 詠み出し元の画像を指定します。\r
+        * @param i_l\r
+        * 基準点からの左上の相対座標(x)を指定します。\r
+        * @param i_t\r
+        * 基準点からの左上の相対座標(y)を指定します。\r
+        * @param i_r\r
+        * 基準点からの右下の相対座標(x)を指定します。\r
+        * @param i_b\r
+        * 基準点からの右下の相対座標(y)を指定します。\r
+        * @param i_base_mat\r
+        * @return 画像の取得の成否を返す。\r
+        */\r
+       public boolean pickupImage2d(INyARRgbRaster i_src_imege, double i_l, double i_t, double i_r, double i_b, NyARTransMatResult i_base_mat) throws NyARException\r
+       {\r
+               double cp00, cp01, cp02, cp11, cp12;\r
+               cp00 = this._ref_perspective.m00;\r
+               cp01 = this._ref_perspective.m01;\r
+               cp02 = this._ref_perspective.m02;\r
+               cp11 = this._ref_perspective.m11;\r
+               cp12 = this._ref_perspective.m12;\r
+               //マーカと同一平面上にある矩形の4個の頂点を座標変換して、射影変換して画面上の\r
+               //頂点を計算する。\r
+               //[hX,hY,h]=[P][RT][x,y,z]\r
+\r
+               //出力先\r
+               NyARIntPoint2d[] poinsts = this._work_points;           \r
+               \r
+               double yt0,yt1,yt2;\r
+               double x3, y3, z3;\r
+               \r
+               double m00=i_base_mat.m00;\r
+               double m10=i_base_mat.m10;\r
+               double m20=i_base_mat.m20;\r
+               \r
+               //yとtの要素を先に計算\r
+               yt0=i_base_mat.m01 * i_t+i_base_mat.m03;\r
+               yt1=i_base_mat.m11 * i_t+i_base_mat.m13;\r
+               yt2=i_base_mat.m21 * i_t+i_base_mat.m23;\r
+               // l,t\r
+               x3 = m00 * i_l + yt0;\r
+               y3 = m10 * i_l + yt1;\r
+               z3 = m20 * i_l + yt2;\r
+               poinsts[0].x = (int) ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);\r
+               poinsts[0].y = (int) ((y3 * cp11 + z3 * cp12) / z3);\r
+               // r,t\r
+               x3 = m00 * i_r + yt0;\r
+               y3 = m10 * i_r + yt1;\r
+               z3 = m20 * i_r + yt2;\r
+               poinsts[1].x = (int) ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);\r
+               poinsts[1].y = (int) ((y3 * cp11 + z3 * cp12) / z3);\r
+\r
+               //yとtの要素を先に計算\r
+               yt0=i_base_mat.m01 * i_b+i_base_mat.m03;\r
+               yt1=i_base_mat.m11 * i_b+i_base_mat.m13;\r
+               yt2=i_base_mat.m21 * i_b+i_base_mat.m23;\r
+\r
+               // r,b\r
+               x3 = m00 * i_r + yt0;\r
+               y3 = m10 * i_r + yt1;\r
+               z3 = m20 * i_r + yt2;\r
+               poinsts[2].x = (int) ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);\r
+               poinsts[2].y = (int) ((y3 * cp11 + z3 * cp12) / z3);\r
+               // l,b\r
+               x3 = m00 * i_l + yt0;\r
+               y3 = m10 * i_l + yt1;\r
+               z3 = m20 * i_l + yt2;\r
+               poinsts[3].x = (int) ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);\r
+               poinsts[3].y = (int) ((y3 * cp11 + z3 * cp12) / z3);\r
+               return this.pickFromRaster(i_src_imege, poinsts);\r
+       }\r
+}
\ No newline at end of file