• 締切済み

VBで円を書いたとき、同じにならないのですが。どうしてでしょう?

VBで、円を描いたとき Circle (CX, CY), 450 で、描いた円と Pi = 3.14159265 For i = 1 To 120 dd = i * 3 x = Cos((90 - dd) * Pi / 180) y = -Sin((90 - dd) * Pi / 180) HX = CX + x * 450 HY = CY + y * 450 PSet (HX, HY) Next i で、描いた円が、重ならないのですが、何故でしょうか? Circle で、描いた円の方が縦が、少し短いような感じになります。

みんなの回答

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんにちは。 私には、お話の流れも、VBの種類もわかりませんが、今、VB6で試してみました。 お書きになったコードを移動させて、Circle の円と比較してみましたが、ぴったりと重なりますね。Form のScaleMode を[ユーザー]にしているのではありませんか?[Twip]にしている限りは、同じだと思うのですが。

yodakii
質問者

補足

回答ありがとうございます。 ScaleModeを 1-Twipにしてみましたが、変わりません。コード上ではなく、プロパティーで変えたためでしょうか? 試しているのは、私もVB6です。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

>circleだけに、補正がかかっていると言うことでしょうか? >sin cos で計算した値には補正がかからないためと言うことで良いのでしょうか? 補正の話は推測の話なのでそれをさらに説明するのはちょっと腰が引けますが・ 質問文でのsin, cos による座標計算は、 X軸とY軸が等間隔であるという前提の元に座標計算していると思います。 つまり、補正されたいないわけです。 いってみれば、PSet(X,Y)で小さな点を打つ場合、 小さな正方形が敷き詰められていてそれが原点から数えてX軸方向に何個Y軸方法に何個の位置にある正方形を塗りつぶすというようなことをやっているわけです。 ところが、 #1でも言ったようにこのドットは正方形ではなくて、 例えば縦に長い長方形のようになっているのです。 すると、それを正方形だとして同じ座標を用いると Y軸方向に(X軸の幅に比して)伸びることになります。 なので、ドットの長方形の比があらかじめ判っているのであれば、 画面上真円になるように、描画を補正してやることができます。

yodakii
質問者

お礼

ありがとうございました。 ドットの補正に関して調べてみようと思います。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

一般にコンピュータのピクセル(ドット)は、正方形ではなくて、 扁平ですから、(ディスプレイで真円に近くなるよう)そういう補正がされているのかもしれません

yodakii
質問者

補足

ご回答ありがとうございます。 ディスプレイが扁平であるため、補正がかかることは分かりますが、この場合 circle だけに、補正がかかっていると言うことでしょうか? sin cos で計算した値には補正がかからないためと言うことで良いのでしょうか?

関連するQ&A

  • 続、VB 座標軸の回転?

    昨日 http://okwave.jp/qa/q7871613.html で質問したものです。 プログラムを作っていて上手に動かないので再度質問です。 xx = x0 - cx yy = y0 - cy x= xx * cosA - yy * sinA + cx y= xx * sinA + yy * cosA + cy x0 = x y0 = y xx:Xの中心からの相対座標 yy:Yの中心からの相対座標 x0:Xの現在地 y0:Yの現在地 cx:三角形の中心X cy:三角形の中心Y x:座標変換後のX y:座標変換後のY A:角度 このようにプログラムしたのですが、回転をさせると渦巻き状に広がってしまいます。 以下のようにプログラミングしたつもりなのですが、うまくいきません。 悪そうな部分を教えてくれるとありがたいです。 >> リーダーの座標を実座標を差し引いて原点(0,0)とし、メンバーの座標をリーダーからの相対座標(x1,y1)(x2,y2)・・・・とします 例えばメンバー(x1,y1)をリーダー中心に半時計周りへ10度回転させた場合の、移動先の座標を(xx1,yy1)とすると・・・ θ=10度(VBではラジアン単位へ変換してください) xx1=x1 * cosθ - y1 * sinθ yy1=x1 * sinθ + y1 * cosθ これで回転して移動した先xx1、yy1が求まります。 最初に差し引いた実座標を足して戻して完成です。

  • VBによる回帰直線のプログラム

    VB6を本を見ながら勉強していますが、どの本にもフォーム上にグラフを表示するものばかりでピクチャボックスに回帰直線y=ax+bの直線を描けるようにはどうしたらいいのかプログラムに困っています。どなたか分かる方いましたらよろしくお願いします。ちなみにプログラムはこのようになっています; Private Sub Command1_Click() Dim c(10) As Double Dim d(10) As Double Dim cx As Integer, cy As Integer, lx As Integer, ly As Integer '----------------------------------------------------------------- 'ピクチャボックスの初期化 Picture1.Cls 'グラフの位置 cx = 60 cy = 320 lx = 300 ly = 300 'グラフ枠を描画 Picture1.FillColor = QBColor(15) Picture1.Line (cx, cy)-(cx + lx, cy - ly), , B '縦軸の目盛り Picture1.DrawStyle = 2 '線の種類 点線 For i = 0 To 5 Picture1.Line (cx, cy - 60 * i)-(cx + lx, cy - 60 * i) Picture1.CurrentX = cx - 25 'ラベルを表示する場所の指定 Picture1.CurrentY = cy - 60 * i '横軸を描画 Picture1.Print Format(i) 'ラベル出力位置を設定 '(i*縦軸の目盛りの倍数 現在は10倍 Next i '横軸の目盛り For i = 0 To 5 Picture1.Line (cx + 60 * i, cy)-(cx + 60 * i, cy - ly) Picture1.CurrentX = cx + 60 * i Picture1.CurrentY = cy + 5 Picture1.Print Format(i) Next i '------------------------------------------------------------------------ Dim n As Integer 'n:データ数 n = Val(Text3.Text) For i = 0 To n - 1 c(i) = Val(Text1(i).Text) d(i) = Val(Text2(i).Text) Next i 'データを○印でプロット For i = 0 To n - 1 Picture1.Circle (cx + 60 * c(i), cy - 60 * d(i)), 3, QBColor(0) Next i 'ここまで成功---------------------------------------------------------------------- 'xに関する平均値と標準偏差の計算プログラム Dim sx As Double, sxx As Double, avx As Double, sdx As Double Dim x(10) As Integer For i = 0 To n - 1 x(i + 1) = c(i) Next i sx = 0 sxx = 0 For i = 1 To n sx = sx + x(i) sxx = sxx + x(i) * x(i) Next i avx = sx / n sdx = Sqr((sxx - n * avx * avx) / n) 'yに関する平均値と標準偏差の計算プログラム Dim sy As Double, syy As Double, svy As Double, sdy As Double Dim y(10) As Double 'インデックスが範囲を超えているのエラーの解決 10を代入 For i = 0 To n - 1 y(i + 1) = d(i) Next i sy = 0 syy = 0 For i = 1 To n sy = sy + y(i) syy = syy + y(i) * y(i) Next i avy = sy / n sdy = Sqr((syy - n * avy * avy) / n) '-------------------------------------------------------------------------------------- '回帰直線y=ax+bを描く End Sub

  • このプログラムを実行すると座標列になるのですが、どうして実行結果のよう

    このプログラムを実行すると座標列になるのですが、どうして実行結果のような座標列になるのかがよくわかりません。 僕はdraw_polygon()中のif(r>xxx)の部分に何かあるような気がします。単なる推測ですが・・・。 理由を教えていただけませんか? #define _CRT_SECURE_NO_DEPRECATE 1 #include <stdio.h> #include <math.h> #defi ne PI 3.14159265358979323846 FILE *fp;//グローバル変数.あまり使うな! double get_x(double r, double angle); double get_y(double r, double angle); void draw_polygon(int n, double r, double cx, double cy); void main(void) { fp=fopen("polygon.csv","w");//チェック省略 draw_polygon(4,1,0,0); fclose(fp); } double get_x(double r, double angle) { return(r*cos(angle)); } double get_y(double r, double angle) { return(r*sin(angle)); } void draw_polygon(int n, double r, double cx, double cy) { int i; double delta,angle,x,y; delta=2.0*PI/n; for(i=0; i<=n; i++)//i<=n { angle=delta*i; x=get_x(r,angle)+cx; y=get_y(r,angle)+cy; fprintf(fp,"%8.3f,%8.3f\n",x,y); } fprintf(fp,"\n"); if(r>0.05) { for(i=0; i<=n; i++)//i<=n { angle=delta*i; x=get_x(r,angle)+cx; y=get_y(r,angle)+cy; draw_polygon(n,r*0.5,x,y); } } } プログラムを見やすく作ったのですが、この質問を掲示した途端に上下そろってしまいました(汗) 見にくくなってしまいすみません。

  • エクセルVBA、フリーフォームで円を描画したい

    円の方程式 X = r * Sin(θ)、Y = r * Cos(θ)を使い、フリーフォームで円を描こうと思い、下記のマクロを書きました。 まず、最初からつまずきました。 マクロ名をSub Circleにしたらそれだけでエラー。 VBAにCircleという関数か何かあるのですか? 次に下記に名前を変えて実行したら、実行時エラー1004「アプリケーションまたはオブジェクトの定義エラー」だそうです。ためしにX0、Y0を100にしたらエラーは出ませんがスタートの座標100、100から円までの軌跡と円に接するところが変になります。 フリーフォームで真円を描くにはどこをどう直せばいいでしょうか? Sub EN() r = 50 π = Application.WorksheetFunction.Pi() ' X0 = 100 ' Y0 = 100 X0 = r * Sin(0) + 100 Y0 = r * Cos(0) + 100 With ActiveSheet.Shapes.BuildFreeform(msoEditingAuto, X0, Y0) For θ = 0 To π * 2 Step π * 2 / 360 X = r * Sin(θ) + 100 Y = r * Cos(θ) + 100 .AddNodes msoSegmentCurve, msoEditingAuto, X, Y DoEvents Next .ConvertToShape.Select'ここがエラー End With End Sub

  • 連立1次方程式が解を持つ条件を求めよ

    下記のx、y、z、に関する連立1次方程式が解を持つ条件を求めよ hx + 2y + z + k = 0 2x + hy + kz +1 = 0 hx + y + 2z +k = 0 x + hy + kz +2 =0

  • 99BASICで五目並べを作りたいのですが…

    サブルーチン*CHECK_TABLEは、味方の色(COL:0が黒、1が白)の数を 上から、右上、右、右下、下、左下、左、左上の8つの方向を順番に 数えるプログラムなのですが、上手く動作しません。 出来かけのソースを載せますので、誰か、助けてください。 100 '最初のプログラム(2009/03/18-05:44:23) 110 DIM MASU(640/32,480/32):CLC_X=23*32:CLC_Y=20*32:JUNBN=1 120 DIM CHKTBL_X(7):DIM CHKTBL_Y(7):DIM C(7) 130 CHKTBL_X(0)=0:CHKTBL_Y(0)=-1 140 CHKTBL_X(1)=1:CHKTBL_Y(1)=-1 150 CHKTBL_X(2)=1:CHKTBL_Y(2)=0 160 CHKTBL_X(3)=1:CHKTBL_Y(3)=1 170 CHKTBL_X(4)=0:CHKTBL_Y(4)=1 180 CHKTBL_X(5)=-1:CHKTBL_Y(5)=1 190 CHKTBL_X(6)=-1:CHKTBL_Y(6)=0 200 CHKTBL_X(7)=-1:CHKTBL_Y(7)=-1 210 PALETTE 8,(150,0,0) 220 *MAIN_LOOP'メインループ-------------------------------------------------- 230 CLS 3:SCREEN 3,5,0 240 GOSUB *DRAW_TABLE 250 GOSUB *GET_CLICK 260 SCREEN 3,1,0 270 GOTO *MAIN_LOOP '-------------------------------------------------------- 280 *DRAW_TABLE 290 LINE(0,0)-(640,480),8,BF '背景色を塗る 300 FOR I=0 TO 640/32 310 FOR J=0 TO 480/32 320 LINE(I*32,J*32)-(I*32+32,J*32+32),7,B '升目を描く 330 CX=I:CY=J 340 IF MASU(CX,CY)=1 THEN CIRCLE(I*32+16,J*32+16),16,0:PAINT(I*32+16,J*32+16),0 350 IF MASU(CX,CY)=2 THEN CIRCLE(I*32+16,J*32+16),16,7:PAINT(I*32+16,J*32+16),7 360 NEXT J'マスの値に応じて円の色を変える 370 NEXT I 380 RETURN 390 *GET_CLICK '------------------------------------------------------------- 400 'GET MOUSE 0,SW,MOUSE_X,MOUSE_Y 410 GET MOUSE 2,SW,CLC_X,CLC_Y 'クリックした座標を取得 420 IF CLC_X<>0 AND CLC_Y<>0 THEN CX=CLC_X\32:CY=CLC_Y\32 '32で割る 430 IF MASU(CX,CY)=0 AND FLAG=1 THEN MASU(CX,CY)=JUNBN+1 '順番通りにマスを反映させる 440 NUM1=CX:NUM2=CY:COL=JUNBN+1 450 GOSUB *CHECK_TABLE 460 FOR I=0 TO 7 480 IF C(I)>4 THEN WINCOLOR=JUNBN+1:GOSUB *WIN 485 PRINT "C(";I;")=";C(I) 490 NEXT I 500 MOUSE ON,2:ON MOUSE GOSUB *CHANGE_JUNBN 510 RETURN 520 *CHANGE_JUNBN 530 JUNBN=JUNBN XOR 1:FLAG=1 '順番を反転させる 540 RETURN 550 *CHECK_TABLE '----------------------------------------------------------- 560 FCOL=COL '味方の色 570 FOR I=0 TO 7 580 CHECK_X=NUM1:CHECK_Y=NUM2:COUNT=0 '指定の座標からチェックする 590 FOR J=0 TO 100 600 IF CHECK_X<0 OR CHECK_X>640/32 THEN GOTO *BK 610 IF CHECK_Y<0 OR CHECK_Y>480/32 THEN GOTO *BK 620 IF COUNT>0 AND MASU(CHECK_X,CHECK_Y)<>FCOL THEN GOTO *BK 630 IF COUNT>0 AND MASU(CHECK_X,CHECK_Y)=FCOL THEN C(I)=C(I)+1 640 CHECK_X=CHECK_X+CHKTBL_X(I):CHECK_Y=CHECK_Y+CHKTBL_Y(I) 650 COUNT=COUNT+1 660 NEXT J 670 *BK 680 NEXT I 690 RETURN 700 *WIN '------------------------------------------------------------------- 710 IF WINCOLOR=1 THEN PRINT"黒が勝ちました。!" ELSE PRINT"白が勝ちました。!" 720 RETURN

  • 3点を通る放物線の求め方を教えてください。

    3点を通る放物線の求め方を教えてください。 (x1,y1), (x2,y2), (x3,y3)をこの順番で通り、頂点を(x2,y2)とする放物線を考えます。 3点が直線上になければ、ただ一つの放物線が定まると思います。 x=x2 を対称軸と仮定すれば、 a(x-x2)^2+y-y2=0 が放物線の式になります。 回転を考慮し、c^2+s^2=1 の変数を加えて書きなおせば、 a(cx-sy-cx2+sy2)^2+sx+cy-sx2-cy2=0 となりますが、X=x-x2, Y=y-y2 と置けば、 a(cX-sY)^2+sX+cY=0 となります。 この先、x1, y1 などを代入し、連立方程式にして解けば…と思いましたが上手くいきませんでした。

  • MATLABで円の投影データの作成

    単位円をx軸に投影するプログラムを作るのですが。 ラジアンをt=(0:100)*2*pi/100で設定し、x=cos(t),y=sin(t)をplot(x,y)で円をプロットするところまではできたのですが。 この後、radonというコマンドを使って投影をするそうなのですが、そっから先に進みません。いろいろなサイトを調べたのですが、radonの使い方が分からないのです。すいません、よろしくいお願いします。

  • flashで円の描画。

    長文失礼します。 FLASH,CS3でActionScript2.0で作業しています。 FLASHで複数の円を重ねて円グラフの様な描画をしたくて、ネット上にあったソースを自分で少しいじりました。 しかし複数の円を描画しようとすると他の円が消えてしまいます。 外部に円を描画するスクリプト(DrawArc.as)がおいてあります。 //DrawArc.as class DrawArc { var mc:MovieClip; function DrawArc(target:MovieClip) { mc = target; } function drawLine(x:Number, y:Number, radius:Number, arc:Number, startAngle:Number, thickness:Number, color:Number, alpha:Number, yRadius:Number) { mc.clear(); mc.lineStyle(thickness,color,alpha,false,"none","none"); mc.moveTo(x,y); if (arguments.length<8) { return; } if (yRadius == undefined) { yRadius = radius; } if (Math.abs(arc)>360) { arc = 360; } var segs = Math.ceil(Math.abs(arc)/45); var segAngle = arc/segs; var theta = -(segAngle/180)*Math.PI; var angle = -(startAngle/180)*Math.PI; var ax = x-Math.cos(angle)*radius; var ay = y-Math.sin(angle)*yRadius; if (segs>0) { for (var i = 0; i<segs; i++) { angle += theta; var angleMid = angle-(theta/2); var bx = ax+Math.cos(angle)*radius; var by = ay+Math.sin(angle)*yRadius; var cx = ax+Math.cos(angleMid)*(radius/Math.cos(theta/2)); var cy = ay+Math.sin(angleMid)*(yRadius/Math.cos(theta/2)); mc.curveTo(cx,cy,bx,by); } } } } そしてFLASHのフレーム内に import DrawArc; mc = new DrawArc(this); targetNum = 0; onEnterFrame = function () { if (targetNum<=220) { targetNum += 2; change(); } else { delete this.onEnterFrame; } }; function change() { mc.drawLine(Stage.width/2,65,40,-targetNum,90,30,0x69f203,100); } とかいてあります。 これで円を描画してくれるんですが、 さらにもう一つの円を重ねて表示させたいので FLASHのフレーム内に import DrawArc; mc = new DrawArc(this); mc2 = new DrawArc(this);//新しい用 targetNum = 0; targetNum2 = 0;//新しい用 onEnterFrame = function () { if (targetNum<=220) { targetNum += 2; change(); } if (targetNum2<=210) { targetNum2 += 2; change2(); } }; function change() { mc.drawLine(Stage.width/2,65,40,-targetNum,90,30,0x002503,100); mc.mc.swapDepths(10); trace(mc.mc.getDepth()); } function change2() { mc2.drawLine(Stage.width/2,65,40,-targetNum2,90,30,0x69f203,100); mc2.mc.swapDepths(11); trace(mc2.mc.getDepth()); } と書いたのですがDepthが両方とも10になってしまいます。このDepthが別々になれば両方ちゃんと表示されると思うのですが、手詰まりになってしまいました。 どなたか解決策が分かる方教えてください。

    • ベストアンサー
    • Flash
  • 連立1次方程式が解を持つ条件を求める

    下記のx、y、z、に関する連立1次方程式が解を持つ条件を求める (線形代数を元に、解が存在するための条件は、係数行列の階数=拡大係数行列の階数) hx + 2y + z + k = 0 2x + hy + kz +1 = 0 hx + y + 2z +k = 0 x + hy + kz +2 =0

専門家に質問してみよう