• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:最速コードに挑戦!?)

最速コードに挑戦!?BASICを使ってPSETを書いてみました。

このQ&Aのポイント
  • BASICを思い出してPSETを使って最速のアルゴリズムを作りたいです。
  • LINE文を作りたいのですが、最速のアルゴリズムをご存知の方はいますか?
  • HTMLのボタンをクリックすると、最速のアルゴリズムでカラフルなポイントを表示します。

質問者が選んだベストアンサー

  • ベストアンサー
  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.2

こんばんは。 (悲しい)続報です。 >overflow='hidden'で1pxになりました! おぉっ!! そーだったのかぁ! 「overflow」は本来の意味で一瞬だけ考えたけど、もとのdivでサイズ指定していないからと、即座に「いらない」と決め付けちゃってました。 前回のは、オブジェクトの定義が相当にいい加減だったので、少し修正してみました。(まだよくわかってないけど、幾分かはましになったと思う。) あと、簡単なチェックだけ付け加えてます。(color、width、座標) ポイントの座標がx、yとも負でないというのを追加したら、めっきり遅くなってしまいました。(かけるポイント数なので当り前だけど) 各ポイントでチェックするのでなく、事前にまとめてチェックしないと早くならないと思うけど、はみ出た場合に座標を修正してとかやるのが面倒なので、とりあえずそのままです。 Lineで、前回は水平、垂直線を別処理してましたが、全部同じ処理にしてしまいました。(ここでも少し遅くなった) Line(x,y)なら最後の点からの線を、2組以上の点を与えると連続線という仕様にしてみました。  Draw.Line(100,100, 300,100, 300,300, 100,300, 100,100) で四角形になるという具合です。 やっている途中で発見したのですが、var a=arguments で取った配列は、通常の配列変数とは違うんですね。知らなかった。(配列を大きくしたりできない)←いろいろと、お勉強になりますね。 あと、せっかく widthを作ったものの、■をベースにして描いているので、幅がある場合は最大1.4倍くらいの誤差が出てしまうのが悲しいですね。 pipiさんの見本のように文字の●などを利用した方がいいのだけれど、こちらはこちらで位置の制御が難しそうなのと、フォントによっても違ってしまいそうなので、今のところどうするのが一番良いのかわかりませーん。 そういえば、もとの課題の「i*3.14519/90」ってよく見たら、なんか抜けてませんか~?? んで、本来のテーマの『最速』はというと?    ますます、遅くなっちゃいましたぁ~~  とほほほ・・・ <html> <body> <input type="button" value="Test Pset" onClick="test1();"> <input type="button" value="Test Line" onClick="test2();"> <input type="button" value="Test Circle" onClick=""> <script> //----------------------------- function test1(){ Draw.color="red"; for (i=0; i<3800; i+=.5){ Draw.Pset(300-Math.cos(i*Math.PI/90)*250,300-Math.sin(i*Math.PI/85)*250); } } function test2(){ Draw.color="blue"; Draw.Line(50,850,50,850); for (i=0; i<3800; i+=.5){ Draw.Line(300-Math.cos(i*Math.PI/90)*250,850-Math.sin(i*Math.PI/85)*250); } } //----------------------------- var Draw = { width:1, _c:'red', _x:0, _y:0, Circle:function(){ this._check_attr(); }, Line:function(){ var a=[]; for (var i=0; i<this.Line.arguments.length; i++){a[i]=this.Line.arguments[i];} if (a.length<4){ for (i=a.length; i>0; i--){a[i+1]=a[i-1];} a[0]=this._x; a[1]=this._y; } var d=Math.floor(a.length/2-1)*2; this._x=a[d]; this._y=a[d+1]; if (a.length>3 && !(a[0]==a[2] && a[1]==a[3])){ this._check_attr(); var obj=document.createElement('div'); for (i=0; i<a.length-3; i+=2){ var dx=a[i+2]-a[i]; var dy=a[i+3]-a[i+1]; d=Math.round(Math.max(Math.abs(dx),Math.abs(dy))); var xx=a[i]-this._w/2; dx=dx/d; var yy=a[i+1]-this._w/2; dy=dy/d; for (var j=0; j<=d; j++){ if (xx>=0 && yy>=0) obj.appendChild(this._draw_point(xx,yy)); xx+=dx; yy+=dy; } document.body.appendChild(obj); } } }, Pset:function(x,y){ this._check_attr(); this._x=x; this._y=y; var xx=x-this._w/2; var yy=y-this._w/2; if (xx>=0 && yy>=0) document.body.appendChild(this._draw_point(xx,yy)); }, _draw_point:function(x,y){ var p=document.createElement('div'); with(p.style){ position='absolute'; backgroundColor=this._c; overflow='hidden'; fontSize='0'; top=y+'px'; left=x+'px'; width=this._w+'px'; height=this._w+'px'; } return p; }, _check_attr:function(){ var v=(Math.abs(this.width))?Math.abs(this.width):1; this._w=Math.max(Math.round(v),1); v=this.color; var t=document.createElement("div"); try{t.style.color=v;}catch(e){v=this._c;} this._c=v; t=null; } } //----------------------------- </script> </body> </html>

noname#84373
質問者

お礼

3.14159でしたね^^; 全然きづきませんでした! 最速のアルゴリズムといっておきながら、あまりの遅さに こうなってしまいました;_; IE限定です <html xmlns:v="urn:schemas-microsoft-com:vml"> <head> <style> v\:* { behavior: url(#default#VML); } </style> </head> <body> <div id="a"> </div> </body> <script> n=3; for(i=5;i<500;i+=5){ var mx,my; for(j=i;j<i+361;j+=360/n){ x=(500-Math.sin(j*3.14159/180)*i)|0; y=(500-Math.cos(j*3.14159/180)*i)|0; if(i!=j) { insCode='<v:line from="'+mx+','+my+'" to="'+x+','+y+'" strokecolor="red"/>'; document.body.insertAdjacentHTML( "BeforeEnd",insCode); } mx=x;my=y; } } </script> </html>

noname#84373
質問者

補足

<html xmlns:v="urn:schemas-microsoft-com:vml"> <head> <style> v\:* { behavior: url(#default#VML); } </style> </head> <body> </body> <script> n=4; for(i=5;i<500;i+=5){ p=i/3; for(j=p;j<p+361;j+=360/n){ x=(500-Math.sin(j*3.14159/180)*i)|0; y=(500-Math.cos(j*3.14159/180)*i)|0; if(p!=j) line(mx,my,x,y,'#f08'); mx=x;my=y; } } function line(x,y,x2,y2,c){document.body.insertAdjacentHTML( "BeforeEnd",'<v:line from="'+x+','+y+'" to="'+x2+','+y2+'" strokecolor="'+c+'"/>');} </script> </html>

その他の回答 (1)

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.1

こんばんは。 回答がないみたいなので、またしゃしゃり出てみました。 実は「psetって何?」状態からのスタートなので・・・ こんなものかなと勝手に解釈してみました。 http://msdn.microsoft.com/ja-jp/library/cc380592.aspx お勉強の意味で参加していますので、回答の対象外ということにしてください。 んでもって、テーマの「最速」にはまったく気を使っていませんので、まずは基準(にもならんか?)となる「最遅」のものの提示です。(笑 方法としては、1px×1pxのdivを塗りつぶして点にしてみました。ついでに、オブジェクトも作成してみましたが、このあたりは初めてのことなのでかなりいい加減です。(って、描画なんて全部初めてだけど・・・) Lineは引数2個で、直前のポイントからのラインとなるようなイメージで作成し始めましたが、実際にはまだそこまでになっていません。 (引数のチェックとかも一切なしなので、負の幅とか、無い色を指定するとエラーになっちゃいます。) IEの場合ドットサイズが1pxにならないので、fontsizeも0にしてみましたが、まだ何か引っかかっているらしく、どうすればいいのか解明できていない状態です。 (width=1を指定しても2px?の幅になってしまう) とりあえずボタンを2個にして。PsetとLineのテストにしてみました。(少しサイズを小さくしました。) <html> <body> <input type="button" value="Test Pset" onClick="test1();"> <input type="button" value="Test Line" onClick="test2();"> <script> function test1(){ Draw.width=1; Draw.color="red"; for (i=0; i<3800; i+=.5){ Draw.Pset(300-Math.cos(i*3.14519/90)*250,300-Math.sin(i*3.14519/85)*250); } } function test2(){ Draw.width=1; Draw.color="blue"; x1=50; y1=850; for (i=0; i<3800; i+=.5){ x2=300-Math.cos(i*3.14519/90)*250; y2=850-Math.sin(i*3.14519/85)*250; Draw.Line(x1,y1,x2,y2); x1=x2; y1=y2; } } Draw=new DrawObject(); function DrawObject(c,w,last_x,last_y){ this.color=c; this.width=w; this.x=last_x; this.y=last_y; this.Line=Line; this.Pset=Pset; } function Line(x1,y1,x2,y2){ Draw.x=x2; Draw.y=y2; if (!(x1==x2 && y1==y2)){ var obj = document.createElement("div"); var w=Draw.width; if (x1==x2||y1==y2){ var h=(y1==y2)?w:y2-y1; w=(x1==x2)?w:x2-x1; obj.appendChild(Point(x1,y1,w,h)); } else { var a=(y2-y1)/(x2-x1); var b=y1-a*x1; var d=Math.abs(x2-x1)/Math.max(Math.abs(x2-x1),Math.abs(y2-y1)); var xx=(x2>x1)?x1:x2; var xy=(x2>x1)?x2:x1; for (var i=xx; i<=xy; i+=d){obj.appendChild(Point(i,a*i+b,w,w));} } document.body.appendChild(obj); } } function Pset(x,y){ Draw.x=x; Draw.y=y; var w=Draw.width; document.body.appendChild(Point(x,y,w,w)); } function Point(x,y,w,h){ var p=document.createElement("div") var xx=Math.round(x-Draw.width/2); var yy=Math.round(y-Draw.width/2); with(p.style){ position='absolute'; backgroundColor=Draw.color; fontSize='0px'; // lineHeight='0px'; top=yy+'px'; left=xx+'px'; width=w+'px' height=h+'px' } return p; } </script> </body> </html>

noname#84373
質問者

お礼

やっぱり凄いですね~! 尊敬しちゃいますよ! できる人は何をやってもできるんですね^^; ちなみにheightの2pxですが、最初から悩んでいました。 そしたらなんと、overflow='hidden'で1pxになりました! PSETを知らない?! というか年がばれるな~!

関連するQ&A