using System;
using System.Collections .Generic ;
using System.ComponentModel ;
using System.Data ;
using System.Drawing ;
using System.Linq ;
using System.Text ;
using System.Windows .Forms ;
namespace アフィン変換サンプル___
{
public partial class Form1 : Form
{
static PointF[ ] Arrow = new PointF[ ] { new PointF( 0 , 2 ) , new PointF( 1.5f , 1 ) , new PointF( 1 , 1 ) , new PointF( 1 , - 1 ) , new PointF( - 1 , - 1 ) , new PointF( - 1 , 1 ) , new PointF( - 1.5f , 1 ) } ;
PointF[ ] ArrowD = new PointF[ Arrow.Count ( ) ] ;
double Direction = 0 ;
float Sc = 32 ; //Scale. コントロールに同名の何かが会ったから短くした。
uint Mode = 3 ;
public Form1( )
{
InitializeComponent( ) ;
Application.Idle += new EventHandler( OnIdle) ;
}
void OnIdle( object sender, EventArgs e)
{
PointF Move= new PointF( this.ClientSize .Width / 2.0f , this.ClientSize .Height / 2.0f ) ;
for ( int i = 0 ; i < Arrow.Count ( ) ; i++ )
{
ArrowD[ i] = TransForm( Arrow[ i] , Direction, new SizeF( Sc, Sc) , Move) ; //大変換!!
}
this.Invalidate ( false ) ;
System.Threading .Thread .Sleep ( 15 ) ;
}
private void Form1_Paint( object sender, PaintEventArgs e) //event
{
Graphics g = e.Graphics ;
g.FillPolygon ( Brushes.Green , ArrowD) ; //多角形塗りつぶし。
float X = this.ClientSize .Width / 2 ;
float Y = this.ClientSize .Height / 2 ;
float L = 8 ;
g.DrawLine ( Pens.Black , X - L, Y, X + L, Y) ;
g.DrawLine ( Pens.Black , X, Y - L, X, Y + L) ;
}
private void Form1_MouseMove( object sender, MouseEventArgs e) //event
{
float X = this.ClientSize .Width / 2.0f - e.X ;
float Y = this.ClientSize .Height / 2.0f - e.Y ;
if ( ( Mode& 1 ) != 0 ) Direction = Math.Atan2 ( Y, X) + ToRadian( 90 ) ;
if ( ( Mode& 2 ) != 0 ) Sc = ( float ) Math.Sqrt ( X * X + Y * Y) ;
}
private void Form1_MouseDown( object sender, MouseEventArgs e) //event
{
Mode %= 3 ;
Mode++;
}
double SingleRadian = Math.PI / 180.0 ;
public double ToRadian( double Degree)
{
return SingleRadian * ( Degree % 360.0 ) ;
}
public double ToDegree( double Radian)
{
return ( Radian / SingleRadian) % 360.0 ;
}
public PointF TransForm( PointF Pos, double RotRadian, SizeF Scale, PointF Move)
{
PointF Ret = new PointF( ) ;
double Sin = Math.Sin ( RotRadian) ;
double Cos = Math.Cos ( RotRadian) ;
Ret.X = ( float ) ( ( ( Pos.X * Scale.Width ) * Cos) - ( ( Pos.Y * Scale.Height ) * Sin) + Move.X ) ;
Ret.Y = ( float ) ( ( ( Pos.X * Scale.Width ) * Sin) + ( ( Pos.Y * Scale.Height ) * Cos) + Move.Y ) ;
return Ret;
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLkNvbXBvbmVudE1vZGVsOwp1c2luZyBTeXN0ZW0uRGF0YTsKdXNpbmcgU3lzdGVtLkRyYXdpbmc7CnVzaW5nIFN5c3RlbS5MaW5xOwp1c2luZyBTeXN0ZW0uVGV4dDsKdXNpbmcgU3lzdGVtLldpbmRvd3MuRm9ybXM7CgpuYW1lc3BhY2Ug44Ki44OV44Kj44Oz5aSJ5o+b44K144Oz44OX44OrX19fCnsKICAgIHB1YmxpYyBwYXJ0aWFsIGNsYXNzIEZvcm0xIDogRm9ybQogICAgewogICAgICAgIHN0YXRpYyBQb2ludEZbXSBBcnJvdyA9IG5ldyBQb2ludEZbXSB7IG5ldyBQb2ludEYoMCwgMiksIG5ldyBQb2ludEYoMS41ZiwgMSksIG5ldyBQb2ludEYoMSwgMSksIG5ldyBQb2ludEYoMSwgLTEpLCBuZXcgUG9pbnRGKC0xLCAtMSksIG5ldyBQb2ludEYoLTEsIDEpLCBuZXcgUG9pbnRGKC0xLjVmLCAxKSB9OwogICAgICAgIFBvaW50RltdIEFycm93RCA9IG5ldyBQb2ludEZbQXJyb3cuQ291bnQoKV07CgogICAgICAgIGRvdWJsZSBEaXJlY3Rpb24gPSAwOwogICAgICAgIGZsb2F0IFNjID0gMzI7Ly9TY2FsZS4g44Kz44Oz44OI44Ot44O844Or44Gr5ZCM5ZCN44Gu5L2V44GL44GM5Lya44Gj44Gf44GL44KJ55+t44GP44GX44Gf44CCCgogICAgICAgIHVpbnQgTW9kZSA9IDM7CgogICAgICAgIHB1YmxpYyBGb3JtMSgpCiAgICAgICAgewogICAgICAgICAgICBJbml0aWFsaXplQ29tcG9uZW50KCk7CiAgICAgICAgICAgIEFwcGxpY2F0aW9uLklkbGUgKz0gbmV3IEV2ZW50SGFuZGxlcihPbklkbGUpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBPbklkbGUob2JqZWN0IHNlbmRlciwgRXZlbnRBcmdzIGUpCiAgICAgICAgeyAgCiAgICAgICAgICAgIFBvaW50RiBNb3ZlPSBuZXcgUG9pbnRGKHRoaXMuQ2xpZW50U2l6ZS5XaWR0aC8yLjBmLHRoaXMuQ2xpZW50U2l6ZS5IZWlnaHQvMi4wZik7CiAgICAgICAgICAgIAogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEFycm93LkNvdW50KCk7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQXJyb3dEW2ldID0gVHJhbnNGb3JtKEFycm93W2ldLCBEaXJlY3Rpb24sIG5ldyBTaXplRihTYywgU2MpLCBNb3ZlKTsvL+Wkp+WkieaPm++8ge+8gQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuSW52YWxpZGF0ZShmYWxzZSk7CiAgICAgICAgICAgIFN5c3RlbS5UaHJlYWRpbmcuVGhyZWFkLlNsZWVwKDE1KTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBGb3JtMV9QYWludChvYmplY3Qgc2VuZGVyLCBQYWludEV2ZW50QXJncyBlKS8vZXZlbnQKICAgICAgICB7CiAgICAgICAgICAgIEdyYXBoaWNzIGcgPSBlLkdyYXBoaWNzOwogICAgICAgICAgICBnLkZpbGxQb2x5Z29uKEJydXNoZXMuR3JlZW4sIEFycm93RCk7Ly/lpJrop5LlvaLloZfjgorjgaTjgbbjgZfjgIIKCiAgICAgICAgICAgIGZsb2F0IFggPSB0aGlzLkNsaWVudFNpemUuV2lkdGggLyAyOwogICAgICAgICAgICBmbG9hdCBZID0gdGhpcy5DbGllbnRTaXplLkhlaWdodCAvIDI7CiAgICAgICAgICAgIGZsb2F0IEwgPSA4OwoKICAgICAgICAgICAgZy5EcmF3TGluZShQZW5zLkJsYWNrLCBYIC0gTCwgWSwgWCArIEwsIFkpOwogICAgICAgICAgICBnLkRyYXdMaW5lKFBlbnMuQmxhY2ssIFgsIFkgLSBMLCBYLCBZICsgTCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHByaXZhdGUgdm9pZCBGb3JtMV9Nb3VzZU1vdmUob2JqZWN0IHNlbmRlciwgTW91c2VFdmVudEFyZ3MgZSkvL2V2ZW50CiAgICAgICAgeyAgICAgICAgICAgICAgICAKICAgICAgICAgICAgZmxvYXQgWCA9IHRoaXMuQ2xpZW50U2l6ZS5XaWR0aC8yLjBmLWUuWDsKICAgICAgICAgICAgZmxvYXQgWSA9IHRoaXMuQ2xpZW50U2l6ZS5IZWlnaHQvMi4wZi1lLlk7CgogICAgICAgICAgICBpZiAoKE1vZGUmMSkgIT0wKSBEaXJlY3Rpb24gPSBNYXRoLkF0YW4yKFksIFgpICsgVG9SYWRpYW4oOTApOwogICAgICAgICAgICBpZiAoKE1vZGUmMikgIT0wKSBTYyA9IChmbG9hdClNYXRoLlNxcnQoWCAqIFggKyBZICogWSk7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIEZvcm0xX01vdXNlRG93bihvYmplY3Qgc2VuZGVyLCBNb3VzZUV2ZW50QXJncyBlKS8vZXZlbnQKICAgICAgICB7ICAgICAgICAgICAgCiAgICAgICAgICAgIE1vZGUgJT0gMzsKICAgICAgICAgICAgTW9kZSsrOwogICAgICAgIH0KICAgICAgIAogICAgICAgIGRvdWJsZSBTaW5nbGVSYWRpYW4gPSBNYXRoLlBJIC8gMTgwLjA7IAoKICAgICAgICBwdWJsaWMgZG91YmxlIFRvUmFkaWFuKGRvdWJsZSBEZWdyZWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gU2luZ2xlUmFkaWFuICogKERlZ3JlZSAlIDM2MC4wKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIGRvdWJsZSBUb0RlZ3JlZShkb3VibGUgUmFkaWFuKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIChSYWRpYW4gLyBTaW5nbGVSYWRpYW4pICUgMzYwLjA7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBQb2ludEYgVHJhbnNGb3JtKFBvaW50RiBQb3MsIGRvdWJsZSBSb3RSYWRpYW4sIFNpemVGIFNjYWxlLCBQb2ludEYgTW92ZSkKICAgICAgICB7CiAgICAgICAgICAgIFBvaW50RiBSZXQgPSBuZXcgUG9pbnRGKCk7CiAgICAgICAgICAgIGRvdWJsZSBTaW4gPSBNYXRoLlNpbihSb3RSYWRpYW4pOwogICAgICAgICAgICBkb3VibGUgQ29zID0gTWF0aC5Db3MoUm90UmFkaWFuKTsKCiAgICAgICAgICAgIFJldC5YID0gKGZsb2F0KSgoKFBvcy5YICogU2NhbGUuV2lkdGgpICogQ29zKSAtICgoUG9zLlkgKiBTY2FsZS5IZWlnaHQpICogU2luKSArIE1vdmUuWCk7CiAgICAgICAgICAgIFJldC5ZID0gKGZsb2F0KSgoKFBvcy5YICogU2NhbGUuV2lkdGgpICogU2luKSArICgoUG9zLlkgKiBTY2FsZS5IZWlnaHQpICogQ29zKSArIE1vdmUuWSk7CgogICAgICAgICAgICByZXR1cm4gUmV0OwogICAgICAgIH0KCiAgICB9Cn0K