写像変換4

 投稿者:しばっち  投稿日:2011年 5月21日(土)20時04分11秒
  !'写像変換
!'マウスで入力用と出力用の四角形を指定
!'四角形にならない時は点順を並べ替える
!'入力用の四角形を出力用の四角形に写像変換する(四角形から四角形へ変換)

OPTION BASE 0
PUBLIC NUMERIC XSIZE,YSIZE
FILE GETNAME F$, "BMP,JPG,GIFファイル|*.BMP;*.JPG;*.GIF"
IF F$="" THEN STOP
CALL PICTURELOAD(F$,XSIZE,YSIZE)
DIM M(XSIZE,YSIZE),X(4),Y(4),U(4),V(4),A(1 TO 8,1 TO 8), D(1 TO 8)
ASK PIXEL ARRAY (0,0) M
PRINT "入力用四角形"
PRINT "マウスで座標を指定してください(4点)" !'四角形を指定する
CALL GETXY(X(1),Y(1),X(2),Y(2),X(3),Y(3),X(4),Y(4)) !'4回左クリックする(クリック順に結ぶ)
IF ISSQUARE(X(1),Y(1),X(2),Y(2),X(3),Y(3),X(4),Y(4))=0 THEN !'四角形でないなら並び替え
   PRINT "四角形ではありません"
   PRINT "並び替えます"
   WAIT DELAY 2
   CALL SORT(X(1),Y(1),X(2),Y(2),X(3),Y(3),X(4),Y(4)) !'時計回りに並び替え
   MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:M !'以下ソート結果の表示
   PLOT LINES:X(1),Y(1);
   SET COLOR COLORINDEX(0,0,1)
   DRAW DISK WITH SCALE(3)*SHIFT(X(1),Y(1))
   PLOT LINES:X(2),Y(2);
   SET COLOR COLORINDEX(1,0,0)
   DRAW DISK WITH SCALE(3)*SHIFT(X(2),Y(2))
   PLOT LINES:X(3),Y(3);
   SET COLOR COLORINDEX(1,0,1)
   DRAW DISK WITH SCALE(3)*SHIFT(X(3),Y(3))
   PLOT LINES:X(4),Y(4);
   SET COLOR COLORINDEX(0,1,0)
   DRAW DISK WITH SCALE(3)*SHIFT(X(4),Y(4))
   PLOT LINES:X(1),Y(1)
END IF
WAIT DELAY 1.5
CLEAR
PRINT "出力用四角形"
PRINT "マウスで座標を指定してください(4点)" !'四角形を指定する
CALL GETXY(U(1),V(1),U(2),V(2),U(3),V(3),U(4),V(4)) !'4回左クリックする
IF ISSQUARE(U(1),V(1),U(2),V(2),U(3),V(3),U(4),V(4))=0 THEN !'四角形でないなら並び替え
   PRINT "四角形ではありません"
   PRINT "並び替えます"
   WAIT DELAY 2
   CALL SORT(U(1),V(1),U(2),V(2),U(3),V(3),U(4),V(4))
   CLEAR
   PLOT LINES:U(1),V(1);
   SET COLOR COLORINDEX(0,0,1)
   DRAW DISK WITH SCALE(3)*SHIFT(U(1),V(1))
   PLOT LINES:U(2),V(2);
   SET COLOR COLORINDEX(1,0,0)
   DRAW DISK WITH SCALE(3)*SHIFT(U(2),V(2))
   PLOT LINES:U(3),V(3);
   SET COLOR COLORINDEX(1,0,1)
   DRAW DISK WITH SCALE(3)*SHIFT(U(3),V(3))
   PLOT LINES:U(4),V(4);
   SET COLOR COLORINDEX(0,1,0)
   DRAW DISK WITH SCALE(3)*SHIFT(U(4),V(4))
   PLOT LINES:U(1),V(1)
END IF
!'  変換式  (※ ここではIを1とおく)
!'  U=(A*X+B*Y+C)/(G*X+H*Y+I)
!'  V=(D*X+E*F+C)/(G*X+H*Y+I)

!' A*X+B*Y+C-U*(G*X+H*Y)=U
!' D*X+E*Y+F-V*(G*X+H*Y)=V

!'8元連立方程式
!'(A)(X1, Y1, 1, 0, 0, 0,-U1*X1,-U1*Y1) (U1)
!'(B)(X2, Y2, 1, 0, 0, 0,-U2*X2,-U2*Y2) (U2)
!'(C)(X3, Y3, 1, 0, 0, 0,-U3*X3,-U3*Y3) (U3)
!'(D)(X4, Y4, 1, 0, 0, 0,-U4*X4,-U4*Y4) (U4)
!'(E)( 0,  0, 0,X1,Y1, 1,-V1*X1,-V1*Y1)=(V1)
!'(F)( 0,  0, 0,X2,Y2, 1,-V2*X2,-V2*Y2) (V2)
!'(G)( 0,  0, 0,X3,Y3, 1,-V3*X3,-V3*Y3) (V3)
!'(H)( 0,  0, 0,X4,Y4, 1,-V4*X4,-V4*Y4) (V4)

LET  A(1, 1) = X(1)
LET  A(1, 2) = Y(1)
LET  A(1, 3) = 1
LET  A(1, 7) = -U(1) * X(1)
LET  A(1, 8) = -U(1) * Y(1)
LET  D(1)=U(1)
LET  A(2, 1) = X(2)
LET  A(2, 2) = Y(2)
LET  A(2, 3) = 1
LET  A(2, 7) = -U(2) * X(2)
LET  A(2, 8) = -U(2) * Y(2)
LET  D(2)=U(2)
LET  A(3, 1) = X(3)
LET  A(3, 2) = Y(3)
LET  A(3, 3) = 1
LET  A(3, 7) = -U(3) * X(3)
LET  A(3, 8) = -U(3) * Y(3)
LET  D(3)=U(3)
LET  A(4, 1) = X(4)
LET  A(4, 2) = Y(4)
LET  A(4, 3) = 1
LET  A(4, 7) = -U(4) * X(4)
LET  A(4, 8) = -U(4) * Y(4)
LET  D(4)=U(4)
LET  A(5, 4) = X(1)
LET  A(5, 5) = Y(1)
LET  A(5, 6) = 1
LET  A(5, 7) = -V(1) * X(1)
LET  A(5, 8) = -V(1) * Y(1)
LET  D(5)=V(1)
LET  A(6, 4) = X(2)
LET  A(6, 5) = Y(2)
LET  A(6, 6) = 1
LET  A(6, 7) = -V(2) * X(2)
LET  A(6, 8) = -V(2) * Y(2)
LET  D(6)=V(2)
LET  A(7, 4) = X(3)
LET  A(7, 5) = Y(3)
LET  A(7, 6) = 1
LET  A(7, 7) = -V(3) * X(3)
LET  A(7, 8) = -V(3) * Y(3)
LET  D(7)=V(3)
LET  A(8, 4) = X(4)
LET  A(8, 5) = Y(4)
LET  A(8, 6) = 1
LET  A(8, 7) = -V(4) * X(4)
LET  A(8, 8) = -V(4) * Y(4)
LET  D(8)=V(4)
MAT A=INV(A)
MAT D=A*D
LET  A1 = D(1)
LET  B1 = D(2)
LET  C1 = D(3)
LET  D1 = D(4)
LET  E1 = D(5)
LET  F1 = D(6)
LET  G1 = D(7)
LET  H1 = D(8)
LET MODE=2
FOR VV = 0 TO YSIZE-1
   FOR UU = 0 TO XSIZE-1
      IF AREA4(U(1), V(1), U(2), V(2), U(3), V(3), U(4), V(4), UU,VV)<>0 THEN !'四角形内なら
         CALL SOLVE(A1 - G1* UU, B1 - UU * H1, UU - C1, D1- G1 * VV, E1 - VV * H1, VV - F1, XA, YA) !'逆変換
         !'  XA,YAを求める
         !'  (A1*XA+B1*YA+C1)/(G1*XA+H1*YA+1)-UU=0
         !'  (D1*XA+E1*YA+F1)/(G1*XA+H1*YA+1)-VV=0

         !'  A1*XA+B1*YA+C1-UU*(G1*XA+H1*YA+1)=0
         !'  D1*XA+E1*YA+F1-VV*(G1*XA+H1*YA+1)=0

         !'  XA*(A1-G1*UU)+YA*(B1-UU*H1)=UU-C1
         !'  XA*(D1-G1*VV)+YA*(E1-VV*H1)=VV-F1

         IF XA >= 0 AND YA >= 0 AND XA <= XSIZE - 1 AND YA <= YSIZE - 1 THEN
            SELECT CASE MODE
            CASE 0
               CALL NEAR(XA,YA,M,RR,GG,BB)
            CASE 1
               CALL BILIEAR(XA,YA,M,RR,GG,BB)
            CASE 2
               CALL BICUBIC(XA,YA,M,RR,GG,BB)
            END SELECT
            CALL PSET(UU,VV,RR,GG,BB)
         END IF
      END IF
   NEXT  UU
NEXT  VV
END

EXTERNAL  SUB GETXY(XA,YA,XB,YB,XC,YC,XD,YD)
!'正順(左上-->右上-->右下-->左下)時計回りとする
!'クリック順 青--> 赤--> 紫 --> 緑 の順にラインを結ぶ
!'ラインの色は青線(上側)、赤線(右側)、紫線(下側)、緑線(左側)を表す
FOR I=1 TO 4
   DO
      MOUSE POLL X,Y,LEFT,RIGHT
   LOOP UNTIL LEFT=1 OR RIGHT=1
   PRINT "(";X;",";Y;")"
   IF RIGHT=1 THEN
      LET XA=0
      LET YA=0
      LET XB=XSIZE-1
      LET YB=0
      LET XC=XSIZE-1
      LET YC=YSIZE-1
      LET XD=0
      LET YD=YSIZE-1
      EXIT FOR
   END IF
   SELECT CASE I
   CASE 1
      LET XA=X
      LET YA=Y
      SET COLOR COLORINDEX(0,0,1)
      DRAW DISK WITH SCALE(3)*SHIFT(X,Y) !'青点
   CASE 2
      LET XB=X
      LET YB=Y
      PLOT LINES:XA,YA;XB,YB
      SET COLOR COLORINDEX(1,0,0)
      DRAW DISK WITH SCALE(3)*SHIFT(X,Y) !'赤点
   CASE 3
      LET XC=X
      LET YC=Y
      PLOT LINES:XB,YB;XC,YC
      SET COLOR COLORINDEX(1,0,1)
      DRAW DISK WITH SCALE(3)*SHIFT(X,Y) !'紫点
   CASE 4
      LET XD=X
      LET YD=Y
      PLOT LINES:XC,YC;XD,YD
      SET COLOR COLORINDEX(0,1,0)
      DRAW DISK WITH SCALE(3)*SHIFT(X,Y) !'緑点
      PLOT LINES:XD,YD;XA,YA
   END SELECT
   DO
      MOUSE POLL DMX,DMY,LEFT,RIGHT
   LOOP WHILE LEFT=1
NEXT I
END SUB

EXTERNAL  FUNCTION TRIANGLE (X1, Y1, X2, Y2, X3, Y3) !'三角形の面積
LET  TRIANGLE = ABS(X1 * Y2 + X2 * Y3 + X3 * Y1 - X2 * Y1 - X3 * Y2 - Y3 * X1) / 2
END FUNCTION

EXTERNAL  FUNCTION AREA3 (X1, Y1, X2, Y2, X3, Y3, PX, PY) !'三角形内なら真
LET  T = TRIANGLE(X1, Y1, X2, Y2, X3, Y3)
LET  A = TRIANGLE(X1, Y1, X2, Y2, PX, PY)
LET  B = TRIANGLE(X2, Y2, X3, Y3, PX, PY)
LET  C = TRIANGLE(X1, Y1, X3, Y3, PX, PY)
IF ABS(A + B + C - T) < 1 THEN LET  AREA3 = -1 ELSE LET  AREA3 = 0
END FUNCTION

EXTERNAL  FUNCTION AREA4 (X1, Y1, X2, Y2, X3, Y3, X4, Y4, PX, PY) !'四角形内なら真
LET  A = AREA3(X1, Y1, X2, Y2, X3, Y3, PX, PY)
LET  B = AREA3(X1, Y1, X4, Y4, X3, Y3, PX, PY)
IF A<>0 OR B<>0 THEN LET  AREA4 = -1 ELSE LET  AREA4 = 0
END FUNCTION
 

Re: 写像変換4

 投稿者:しばっち  投稿日:2011年 5月21日(土)20時05分12秒
  > No.1552[元記事へ]

続き

EXTERNAL  SUB SOLVE (A1, B1, C1, A2, B2, C2, XA, YA) !'逆変換
LET  DD = A1 * B2 - A2 * B1
IF DD=0 THEN
   LET XA=-1
   LET YA=-1
ELSE
   LET  XA = INT((C1 * B2 - C2 * B1) / DD)
   LET  YA = INT((A1 * C2 - A2 * C1) / DD)
END IF
END SUB

EXTERNAL  SUB SORT(XA,YA,XB,YB,XC,YC,XD,YD) !'点順の並べ替え
DO
   LET FL=0
   CALL CROSS(XA,YA,XB,YB,XC,YC,XD,YD,XX,YY)
   IF XX>0 AND YY>0 THEN
      SWAP XB,XC
      SWAP YB,YC
      LET FL=1
   END IF
   CALL CROSS(XB,YB,XC,YC,XA,YA,XD,YD,XX,YY)
   IF XX>0 AND YY>0 THEN
      SWAP XD,XC
      SWAP YD,YC
      LET FL=1
   END IF
   IF SQUARE(XA,YA,XB,YB,XC,YC,XD,YD)<0 AND ISSQUARE(XA,YA,XD,YD,XC,YC,XB,YB)<>0 THEN
      SWAP XB,XD
      SWAP YB,YD
      LET FL=1
   END IF
LOOP UNTIL FL=0 OR ISSQUARE(XA,YA,XB,YB,XC,YC,XD,YD)<>0
END SUB

EXTERNAL FUNCTION SQUARE(X1,Y1,X2,Y2,X3,Y3,X4,Y4)
LET SQUARE=(X1*Y2+X2*Y3+X3*Y4+X4*Y1-Y1*X2-Y2*X3-Y3*X4-Y4*X1)/2 !'四角形の面積 右回りなら正
END FUNCTION

EXTERNAL  FUNCTION COSINE (OX, OY, PX, PY, MX, MY)
LET  COSINE=((PX-OX)*(MX-OX)+(PY-OY)*(MY-OY))/SQR((PX-OX)*(PX-OX)+(PY-OY)*(PY-OY))/SQR((MX-OX)*(MX-OX)+(MY-OY)*(MY-OY))
END FUNCTION

EXTERNAL  FUNCTION ISSQUARE(X1,Y1,X2,Y2,X3,Y3,X4,Y4) !'四角形なら真
LET T1=ACOS(COSINE(X1,Y1,X4,Y4,X2,Y2))
LET T2=ACOS(COSINE(X2,Y2,X1,Y1,X3,Y3))
LET T3=ACOS(COSINE(X3,Y3,X2,Y2,X4,Y4))
LET T4=ACOS(COSINE(X4,Y4,X3,Y3,X1,Y1))
LET ISSQUARE=0
IF TRIANGLE(X1,Y1,X2,Y2,X3,Y3)=0 THEN EXIT FUNCTION
IF TRIANGLE(X1,Y1,X2,Y2,X4,Y4)=0 THEN EXIT FUNCTION
IF TRIANGLE(X2,Y2,X3,Y3,X4,Y4)=0 THEN EXIT FUNCTION
IF TRIANGLE(X3,Y3,X4,Y4,X1,Y1)=0 THEN EXIT FUNCTION
IF ABS(T1+T2+T3+T4-2*PI)<.0001 THEN LET ISSQUARE=-1
IF ABS(2*PI-T1+T2+T3+T4-2*PI)<.0001 THEN LET ISSQUARE=-1
IF ABS(2*PI+T1-T2+T3+T4-2*PI)<.0001 THEN LET ISSQUARE=-1
IF ABS(2*PI+T1+T2-T3+T4-2*PI)<.0001 THEN LET ISSQUARE=-1
IF ABS(2*PI+T1+T2+T3-T4-2*PI)<.0001 THEN LET ISSQUARE=-1
END FUNCTION

EXTERNAL  SUB CROSS(XA,YA,XB,YB,X1,Y1,X2,Y2,X,Y)
!'線分(XA,YA)-(XB,YB)
!'線分(X1,Y1)-(X2,Y2)との交点
!'なければ負数を返す

!'Y=(YB-YA)/(XB-XA)*(X-XA)+YA
!'Y=(Y2-Y1)/(X2-X1)*(X-X1)+Y1
!'B/A*(X-XA)+YA=D/C*(X-X1)+Y1
!'(B/A-D/C)*X=B/A*XA-D/C*X1+Y1-YA
LET B=YB-YA
LET A=XB-XA
LET D=Y2-Y1
LET C=X2-X1
IF A<>0 AND B<>0 AND C<>0 AND D<>0 THEN
   LET X=INT((B/A*XA-D/C*X1+Y1-YA)/(B/A-D/C))
   LET Y=INT((YB-YA)/(XB-XA)*(X-XA)+YA)
   IF MIN(XA,XB)<=X AND MAX(XA,XB)>=X AND MIN(YA,YB)<=Y AND Y<=MAX(YA,YB) AND MIN(X1,X2)<=X AND MAX(X1,X2)>=X AND MIN(Y1,Y2)<=Y AND Y<=MAX(Y1,Y2) THEN  EXIT SUB
END IF
LET X=-1
LET Y=-1
END SUB
 

戻る