「ガッツでC.G.!サポートツール」で LINE&PAINT CG を描くと、1データあたり 100KB~200KBぐらいになります。8ビットPCの頃に比べると、超贅沢なデータ量ですね。
M5Atom でCG描画アプリを実行するときは、このデータをフラッシュメモリ(SPIFFS)に格納するわけですが、フラッシュメモリのデータ格納容量が2MB程度しか確保できなくて、そうすると 100KB だと 20枚程度が限界になってしまうのですよね。
MI68 で展示していた PIC 画像表示とLINE&PAINT CG です。
PIC 画像は電脳倶楽部に収録されていたものです。LINE&PAINT データは自分で画像をトレースして作成しました。 pic.twitter.com/7e9lq85A1R— Nochi(ドウスル?▮) (@shikarunochi) October 13, 2022
外付けでSDカードを接続するのもアリですが、ミニチュアモニタで使っている 240×240 1.3インチディスプレイはCSピンを持ってないため、SDカードとLCDでSPI接続共有するのが難しく、M5Atom だとピンが足りないわけです。
そんなわけで、少しでもファイルサイズを小さくしたい。
「ガッツでC.G.!サポートツール」は線を引くときにかなり贅沢にポイント座標を取得してます。
こういう風になってるところも多いです。
このとき、(X1,Y1)-(X2,Y2)の角度と(X1,Y1)-(X3,Y3)の角度が同じであれば(X2,Y2)は省略することが可能ですね。
生成済みの描画データに対して、この処理を行うツールを Python で書いてみました。
import sys import os if len(sys.argv) > 1: fileName = sys.argv[1] else: fileName = "MagicalMirai2018.dat" #print("ファイル名を指定してください") #sys.exit() cgData = open(fileName, encoding="utf-8") file, ext = os.path.splitext(fileName) dietData = open(file + "_diet.dat", mode='w', encoding="utf-8") line = cgData.readline() #1行目はタイトル dietData.write(line) #直線になっている場合、途中の点を省略する。 lineMode = False while line: line = cgData.readline() print("line:" + line) lineData = line.rstrip().split(',') #-10から始まっていたら、LINEモード。LINEは1行1LINE if len(lineData) == 0: continue if line.startswith('-10'): lineMode = True dietData.write(lineData.pop(0)) dietData.write(',') elif line.startswith('-1'): lineMode = False dietData.write(line) elif lineMode == False: dietData.write(line) if lineMode == True: dietData.write(lineData.pop(0)) #color dietData.write(',') index = 0 while(1): if index + 5 >= len(lineData): dietData.write(",".join(lineData)) dietData.write("\n") break #(x1,y1)-(x2,y2)の傾きと、(x1,y1)-(x3,y3)の傾きが同じであれば(x2,y2)を削除できる。 x1 = int(lineData[index + 0]) y1 = int(lineData[index + 1]) x2 = int(lineData[index + 2]) y2 = int(lineData[index + 3]) x3 = int(lineData[index + 4]) y3 = int(lineData[index + 5]) if(y1 - y2 == 0) and (y1 - y3 == 0): #両方傾きゼロだけ特別扱い del lineData[index+2] del lineData[index+2] #詰まっているので同じINDEX elif(y1 - y2 == 0) or (y1 - y3 == 0): #分母ゼロなので割れない index = index + 2 elif (x1-x2) / (y1 - y2) == (x1-x3) / (y1 -y3): del lineData[index+2] del lineData[index+2] #詰まっているので同じINDEX else: index = index + 2 dietData.close() cgData.close()
元ファイル:MagicalMirai2018.dat : 194,551 byte
実行後ファイル:MagicalMirai2018.diet.dat :126,695 byte
小さくなった!(その分、描画の時も少々クイックになります)
最初からこの処理を「ガッツでC.G.!サポートツール」の線引き処理に組み込んどけばよいのですよね…。
var point = [Math.round(mouse.x),Math.round(mouse.y)]; //前回と傾きが同じだった場合、前回のポイントは削除する。 if(curDrawData.length >=2){ point1 = curDrawData[curDrawData.length-2]; point2 = curDrawData[curDrawData.length-1]; x1 = point1[0]; y1 = point1[1]; x2 = point2[0]; y2 = point1[1]; x3 = point[0]; y3 = point[1]; if((y1 - y2 == 0) && (y1 - y3 == 0)){ //両方傾きゼロだけ特別扱い curDrawData.pop(); }else if((y1 - y2 == 0) || (y1 - y3 == 0)){ //分母ゼロなので割れない }else if((x1-x2) / (y1 - y2) == (x1 - x3) / (y1 - y3)){ curDrawData.pop(); } } curDrawData.push(point);
…ということで、こちらも先ほど組み込み終わりました!