package cit.PureATN;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.Vector;
import org.piccolo2d.PNode;
import org.piccolo2d.activities.PActivity;
import org.piccolo2d.nodes.PPath;
import org.piccolo2d.util.PBounds;
import cit.PureATN.MultiNote.MultiNote;
/**
* 生徒の筆記(1ストローク)モデル Zoom可能な画面に表示するためのクラス
* @author miuramo
*
*/
public class ShortStroke extends PPPath implements Serializable, Runnable {
private static final long serialVersionUID = 5928762332664417016L;
//TODO: 筆記解析をするならtrue
// public transient static boolean doAssess = false;
public float[] sx;
public float[] sy;
// public short[] penpress;
public float width;
public int color;
public int penid;//ペンのID
// public int paperid;//シートのID
public long time;
public boolean isRealPen = false; //マウス描画ならfalse
// public int sbackid;
public transient long id;
public transient ArrayList<Point2D> tempPts;
// public transient PNode ink;
// public transient Point2D startp;
public transient Shape full;
// transient Event_onSS event_onss = null;
public String toCsv(){
SimpleDateFormat sdf = new SimpleDateFormat("\"yyyy/MM/dd HH:mm:ss\"");
StringBuffer sb = new StringBuffer();
sb.append(penid);
sb.append(",");
// sb.append(paperid);
// sb.append(",");
sb.append(String.valueOf(time));
sb.append(",");
sb.append(sdf.format(time));
sb.append(",");
sb.append(sx.length);
sb.append(",");
for(int i=0;i<sx.length;i++){
sb.append(sx[i]);
sb.append(",");
sb.append(sy[i]);
sb.append(",");
}
String s = sb.toString();
return s.substring(0,s.length()-1);
}
// public transient int interval;
// public transient Thread playthread;
// public transient boolean playing;
//for playing
public transient ArrayList<Shape> shapel;
public transient PBounds bounds;
static Hashtable<String, BasicStroke> penStrokeHash;
static Hashtable<Integer, Color> colorHash;
static {
penStrokeHash = new Hashtable<String, BasicStroke>();
colorHash = new Hashtable<Integer, Color>();
}
public static BasicStroke getCachedBasicStroke(float f){ //f=太さ
if (penStrokeHash.containsKey(java.lang.Float.valueOf(f).toString())){
return penStrokeHash.get(java.lang.Float.valueOf(f).toString());
} else {
BasicStroke bs = new BasicStroke( f/2, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND, 90.0f);
penStrokeHash.put( java.lang.Float.valueOf(f).toString(), bs);
return bs;
}
}
public static Color getColor(int f){
if (colorHash.containsKey(f)){
return colorHash.get(f);
} else {
Color opaqueC = new Color(f);
Color cl = new Color(opaqueC.getRed(),
opaqueC.getGreen(), opaqueC.getBlue(), 245); //TODO:ここで筆記の透明度を設定.以前は95
colorHash.put(f, cl);
return cl;
}
}
// 新規作成
public ShortStroke() {
this(0, new Color(0,0,90), 3, new Date().getTime());
}
public ShortStroke(int _penid, Color _color, int _width, long _time){
penid = _penid;
color = _color.getRGB();
this.setStrokePaint(_color);
width = _width;
setStroke(getCachedBasicStroke(width));
time = _time;
setTransparency(0.7f);
// playing = false;
}
// startDragのまえに、layer.addChildしておく
public void startDrag_on_draw(double px, double py){
tempPts = new ArrayList<Point2D>();
this.moveTo(px,py);
}
public void drag_on_draw(double px, double py){
if (tempPts == null) return;
tempPts.add(new Point2D.Double(px,py));
this.lineTo(px,py);
}
public void endDrag_on_draw(){
// 下敷きが用意されていれば、Layerから下敷きに移動する
if (tempPts == null) return;
applyTempPtsToAry();
if (Note.theapp instanceof MultiNote){
//下敷きを特定
MultiNote mn = (MultiNote)Note.theapp;
PPath theShitajiki = mn.shitajikiNodes[penid];
if (theShitajiki != null){
Point2D offset = theShitajiki.getOffset();
if (!this.isRealPen) { //マウス描画のときは、下敷きのオフセットにあわせる
move((float)-offset.getX(), (float)-offset.getY());
}
theShitajiki.addChild(this);
}
}
}
public void restore_on_load(){
if (Note.theapp instanceof MultiNote){
//下敷きを特定
MultiNote mn = (MultiNote)Note.theapp;
PPath theShitajiki = mn.shitajikiNodes[penid];
if (theShitajiki != null){
theShitajiki.addChild(this);
}
} else {
PNode layer = Note.theapp.getCanvas().getLayer();
layer.addChild(this);
}
}
public void applyTempPtsToAry(){
sx = new float[tempPts.size()];
sy = new float[tempPts.size()];
// penpress = new short[tempPts.size()];
for(int i=0;i<tempPts.size();i++){
sx[i] = (float)tempPts.get(i).getX();
sy[i] = (float)tempPts.get(i).getY();
// penpress[i] = 127;
}
}
public Color getColor(){
return ShortStroke.getColor(color);
}
public void setColor(Color c){
setStrokePaint(c);
//元のデータも書き換える
color = c.getRGB();
}
public void animateToFlushColor(Color flushcolor, long duration, long startwait){
PActivity a1 = this.animateToColor(flushcolor, duration);
PActivity a2 = this.animateToColor(getColor(), duration);
a1.setStartTime(System.currentTimeMillis()+startwait);
a2.startAfter(a1);
}
public Point2D getPenPoint(int pos) {
return new Point2D.Float(sx[pos], sy[pos]);
}
public Point2D getFirstPoint() {
return new Point2D.Float(sx[0], sy[0]);
}
public Point2D getLastPoint() {
return new Point2D.Float(sx[sx.length - 1], sy[sy.length - 1]);
}
public synchronized void run() {
// playing = true;
// reset();
// ink.addChild(this);
// moveTo(sx[0], sy[0]);
// for (int i = 1; i < sx.length; i++) {
// lineTo(sx[i], sy[i]);
// ink.repaintFrom(getBoundsReference(), this);
// try {
// Thread.sleep(interval);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// if (!playing)
// return;
// }
// removeFromParent();
// ink.addChild(this);
// ink.repaintFrom(getBoundsReference(), this);
// if (SnailServer.server.recognizeCB.isSelected())
// note.recognize(this);
// note.student.afterAddDBStroke(note, this);
// stop();
}
// public void suspend() {
// synchronized (playthread) {
// try {
// playthread.wait(); // プロセスを休止する
// } catch (InterruptedException e) {
// }
// }
// }
// public synchronized void resume() {
// playthread.notify();
// }
// public void stop() {
// if (playing)
// playing = false;
// if (playthread != null)
// playthread = null;
// // ink.repaint();
// }
public synchronized PPath genStroke(String protocol, float inkscale) {
return genStroke_old(protocol, inkscale);
// return genStroke_besier(protocol);
}
// public PPath getStroke(){
// if (stroke!=null) return stroke;
// else return rebuildStroke();
// }
public synchronized PPath genStroke_besier(String protocol, float inkscale) {
StringTokenizer st = new StringTokenizer(protocol);
Vector<double[]> v = new Vector<double[]>();
int c = st.countTokens();
int p = 0;
sx = new float[c / 2];
sy = new float[c / 2];
float tsx = (float) (Integer.parseInt(st.nextToken(), 36) * inkscale);
float tsy = (float) (Integer.parseInt(st.nextToken(), 36) * inkscale);
float ttx, tty; // previous values;
sx[p] = tsx;
sy[p] = tsy;
// System.out.println("tsx: "+ tsx + " tsy: "+tsy);
double[] t = new double[2];
t[0] = tsx;
t[1] = tsy;
v.add(t);
ttx = tsx;
tty = tsy;
while (st.hasMoreElements()) {
p++;
float x = (float) (Integer.parseInt(st.nextToken(), 36) * inkscale);
float y = (float) (Integer.parseInt(st.nextToken(), 36) * inkscale);
sx[p] = x;
sy[p] = y;
if (x != ttx && y != tty) {
double[] tt = new double[2];
tt[0] = x;
tt[1] = y;
v.add(tt);
}
}
// FitCurves fc = new FitCurves();
// try {
// fc.getBezier(v, 4.0);
// } catch (ArrayIndexOutOfBoundsException aioobe) {
// genStroke_old(protocol, inkscale);
// }
return this;
}
public synchronized PPath genStroke_old(String protocol, float inkscale) {
try {
StringTokenizer st = new StringTokenizer(protocol);
time = new Date().getTime();
// System.out.println(time);
int c = st.countTokens();
int p = 0;
sx = new float[c / 2];
sy = new float[c / 2];
// stroke = new MyPPath(this);
reset();
float tsx = (float) (Integer.parseInt(st.nextToken(), 36) * inkscale);
float tsy = (float) (Integer.parseInt(st.nextToken(), 36) * inkscale);
moveTo((float) tsx, (float) tsy);
sx[p] = tsx;
sy[p] = tsy;
while (st.hasMoreElements()) {
p++;
float x = (float) (Integer.parseInt(st.nextToken(), 36) * inkscale);
float y = (float) (Integer.parseInt(st.nextToken(), 36) * inkscale);
lineTo((float) x, (float) y);
sx[p] = x;
sy[p] = y;
}
return this;
} catch (NoSuchElementException ex) {
System.out.println(ex.toString());
return null;
}
}
public synchronized PPath rebuildStroke_old() {
// stroke = new MyPPath(this);
reset();
if (sx.length == 0 || sy.length == 0) {
System.out.println("長さ0のストロークデータ " + time);
return this;
}
moveTo((float) sx[0], (float) sy[0]);
for (int i = 0; i < sx.length; i++) {
lineTo((float) sx[i], (float) sy[i]);
}
full = new GeneralPath(this.getPathReference()); // 最後までの筆記を記録
// removeAllChildren();
// for(int i=0;i<sx.length;i++){
// PPath a = PPath.createEllipse(sx[i]-0.3f, sy[i]-0.3f, 0.3f, 0.3f);
// a.setPaint(getColor(3000000));
// a.setStrokePaint(getColor(3000000));
// addChild(a);
// }
return this;
// return this;
}
// public void calcMetrics(){
// // if (dist < 0){ //初期値は-1なので。はじめてかどうかのチェック
// // // lengthInPixel();
// // // maxspeedInPixel();
// // // varspeedInPixel();
// // // angle();
// // // ramer();
// // // log();
// // }
// }
// public void exportBySieve(){ //TODO:
// calcMetrics();
// FileReadWriter.buffer.add(var_ramer+","+num_choten+","+num_choten2+","+ramer+","+penid+","+time+","+ppd+","+pts+","+dist);
// /*
// * FileReadWriter.buffer.add(id+","+time+","+sbackid+","+penid+","+paperid+","+
// sx.length+","+length+","+avgspeed+","+varspeed+","+varspeed2+","+maxspeed+","+timediff+","+timed+","+
// num_choten+","+num_choten2+","+numrammer);//研究用
// */
// // FileReadWriter.buffer.add(timed+","+num_choten+","+num_choten2+","+numrammer+","+
// // varspeed+","+varspeed2+","+avgspeed+","+avgspeed2);//分析1用
// // FileReadWriter.buffer.add(num_choten+","+varspeed+","+avgspeed);//分析2-1用
// // FileReadWriter.buffer.add(num_choten2+","+varspeed2+","+avgspeed2);//分析2-2用
// // FileReadWriter.buffer.add(numrammer+","+varspeed+","+avgspeed);//分析2-3用
// // FileReadWriter.buffer.add(numrammer+","+varspeed2+","+avgspeed2);//分析2-4用
// //
// //System.out.println(penid+" "+paperid+" count "+sx.length+" len "+length+" avg "+avgspeed+" var "+varspeed+" max "+maxspeed+" td "+timediff);
// //太さと色を設定
// }
// public void exportBySieveAverage(){ //TODO:
// calcMetrics();
/*
* FileReadWriter.buffer.add(id+","+time+","+sbackid+","+penid+","+paperid+","+
sx.length+","+length+","+avgspeed+","+varspeed+","+varspeed2+","+maxspeed+","+timediff+","+timed+","+
num_choten+","+num_choten2+","+numrammer);//研究用
*/
// FileReadWriter.buffer.add(timed+","+num_choten+","+num_choten2+","+numrammer+","+
// varspeed+","+varspeed2+","+avgspeed+","+avgspeed2);//分析1用
// FileReadWriter.buffer.add(num_choten+","+varspeed+","+avgspeed);//分析2-1用
// FileReadWriter.buffer.add(num_choten2+","+varspeed2+","+avgspeed2);//分析2-2用
// FileReadWriter.buffer.add(numrammer+","+varspeed+","+avgspeed);//分析2-3用
// FileReadWriter.buffer.add(numrammer+","+varspeed2+","+avgspeed2);//分析2-4用
//
//System.out.println(penid+" "+paperid+" count "+sx.length+" len "+length+" avg "+avgspeed+" var "+varspeed+" max "+maxspeed+" td "+timediff);
//太さと色を設定
// }
public synchronized PPath rebuildStroke() {
setStroke(getCachedBasicStroke(width));
setStrokePaint(getColor(color));
// float h = (float)(avgspeed/3);
// if (h>1.0) h=1.0f;
// float b = (float)(Math.log(varspeed+0.01)+0.2);
// if (b>1.0) b=1.0f;
// int hh = (int)(h*205)+50;
// if (hh>255) hh=255;
// setStrokePaint(new Color(Color.HSBtoRGB(h, 0.7f, 0.7f)));
// if (hh>60) setStrokePaint(new Color(hh,hh,hh));
// else setStrokePaint(new Color(255-hh*2,0,0));
return rebuildStroke_old();
// return rebuildStroke_besier();
}
public synchronized PPath rebuildStroke_besier() { // bezier version
// float ttx2 = -1, tty2 = 0;
float ttx1 = 0, tty1 = 0;
Vector<double[]> v = new Vector<double[]>();
for (int i = 0; i < sx.length; i++) {
float x = sx[i];
float y = sy[i];
if (x != ttx1 && y != tty1) {
double[] tt = new double[2];
double[] tmid = new double[2];
if (ttx1 != 0 && tty1 != 0) {
tmid[0] = (x + ttx1) / 2.0;
tmid[1] = (y + tty1) / 2.0;
v.add(tmid);
}
tt[0] = x;
tt[1] = y;
v.add(tt);
}
ttx1 = x;
tty1 = y;
}
// FitCurves fc = new FitCurves();
// fc.getBezier(v, 4.0);
// ((MyPPath)stroke).setSS(this);
return this;
}
//自分の最後と、otherの最初の距離をみる
public float distance(ShortStroke other){
if (sx.length==0) return 99999f;
float tx = sx[sx.length-1];
float ty = sy[sy.length-1];
if (other.sx.length==0) return 99999f;
float ox = other.sx[0];
float oy = other.sy[0];
return (float) Math.sqrt((ox-tx)*(ox-tx)+(oy-ty)*(oy-ty));
}
public void move(float dx, float dy){//移動
for(int i=0;i<sx.length;i++){
sx[i] = sx[i]+dx;
}
for(int i=0;i<sy.length;i++){
sy[i] = sy[i]+dy;
}
rebuildStroke();
}
public void addPoint(Point2D p) {
tempPts.add(p);
}
/**
* 生徒PDAからの生筆記データからDB用データを生成
*
* @param sx X座標配列
* @param sy Y座標配列
* @return DB格納用バイトデータ
*/
// public byte[] getXYBytes() {
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// BufferedOutputStream bos;
// DataOutputStream dos;
// try {
// bos = new BufferedOutputStream(baos);
// dos = new DataOutputStream(bos);
// dos.writeInt(sx.length);
// for (int i = 0; i < sx.length; i++) {
// dos.writeFloat(sx[i]);
// }
// for (int i = 0; i < sy.length; i++) {
// dos.writeFloat(sy[i]);
// }
// dos.close();
// bos.close();
// baos.close();
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }
// return baos.toByteArray();
// }
// public byte[] getPseudoPPBytes() {
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// BufferedOutputStream bos;
// DataOutputStream dos;
// try {
// bos = new BufferedOutputStream(baos);
// dos = new DataOutputStream(bos);
// dos.writeInt(sx.length);
// for (int i = 0; i < sx.length; i++) {
// dos.writeShort(128);
// }
// dos.close();
// bos.close();
// baos.close();
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }
// return baos.toByteArray();
// }
// public void debugPrint() {
// // System.out.println("SSDebug "+penid+" "+paperid+" "+new Date(time));
// }
public ShortStroke clone(){
ShortStroke newss = new ShortStroke();
newss.sx = new float[this.sx.length];
newss.sy = new float[this.sy.length];
for(int i=0;i<this.sx.length;i++){
newss.sx[i] = this.sx[i];
}
for(int i=0;i<this.sy.length;i++){
newss.sy[i] = this.sy[i];
}
// if (this.penpress != null){
// newss.penpress = new short[this.penpress.length];
// for(int i=0;i<this.penpress.length;i++){
// newss.penpress[i] = this.penpress[i];
// }
// }
newss.time = this.time;
newss.penid = this.penid;
newss.color = this.color;
newss.width = this.width;
// newss.paperid = this.paperid;
newss.id = this.id;
return newss;
}
public void play(int _interval /* PNode _ink, PNode _redink, Note n*/) {
// if (playing) return;
// this.prepareStrokeList(_ink);
// for(TimePlayPath tpp: strokelist){
// // tpp.snip.setTransparency(0.0f);
// tpp.snip.setVisible(false);
// }
// ink = _ink;
// redink = _redink;
// note = n;
// interval = _interval;
// playthread = new Thread(this);
// playthread.start();
// try {
// playthread.join();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
// 現在の形状をリストに追加
public void restoreShape() {
if (shapel == null) {
shapel = new ArrayList<Shape>();
}
Shape shape = this.getPathReference();
shapel.add(new GeneralPath(shape));
}
// リセット
public void resetShapes() {
if (full == null) {
rebuildStroke();
}
if (shapel == null) {
shapel = new ArrayList<Shape>();
}
setPathTo(full);
shapel.clear();
}
// 形状を保存
public void prepareShapes() {
if (shapel == null) {
shapel = new ArrayList<Shape>();
}
shapel.clear();
GeneralPath gp = new GeneralPath();
gp.moveTo(sx[0], sy[0]);
shapel.add(new GeneralPath(gp));
for (int i = 1; i < sx.length; i++) {
gp.lineTo(sx[i], sy[i]);
shapel.add(new GeneralPath(gp));
}
}
public int getSteps() {
return sx.length;
}
//TODO:
// public transient double[] speedary;
// public transient double[] speedary2;
// public transient double dist = -1;
// public transient double length2;
// public transient double avgspeed;
// public transient double avgspeed2;
// public transient double varspeed;
// public transient double varspeed2;
// public transient double maxspeed;
// public transient ShortStroke previous;
// public transient long timediff;
// public transient long timed;
// public transient double[] angleary ;
// public transient double[] angleary2 ;
// public transient double[] angleary3 ;
// public transient int num_choten = 0;//90度以上の点の数
// public transient int num_choten2 = 0;//90度以上の点の数 ノイズ除去ver
// public transient double sumangle, avgangle;
// public transient double varangle;
// public transient int ramer;
// public transient double choten1_var;
// public transient double choten1_avg;
// public transient double choten2_var;
// public transient double choten2_avg;
// public transient int kukan2;
// public transient double var_oreten;
// public transient double var_ramer;
// public transient double ramerthre;
// public transient double ppd, pps,ppr;
// public transient double pts, dbltime;
// public int pos; //水井筆記のpos
// public String tag;
// public void print_metrics2(){
// String a[] = new String[]{"var_ramer","ppd","pts","length", "current_begin"};
// for(String fn: a){
// Field f = null;
// try {
// f = ShortStroke.class.getField(fn);
// } catch (NoSuchFieldException e) {
// e.printStackTrace();
// } catch (SecurityException e) {
// e.printStackTrace();
// }
// try {
// System.out.println(fn+" : "+f.get(this));
// } catch (IllegalArgumentException e) {
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// }
// }
// System.out.println("");
// }
// public void print_metrics(){
// ShortStroke clone = this.clone();
// clone.calcMetrics();
// String a[] = new String[]{"ramerthre","varspeed2","numrammer","var_ramer", "length"};
// for(String fn: a){
// Field f = null;
// try {
// f = ShortStroke.class.getField(fn);
// } catch (NoSuchFieldException e) {
// e.printStackTrace();
// } catch (SecurityException e) {
// e.printStackTrace();
// }
// try {
// System.out.println(fn+" : "+f.get(clone));
// } catch (IllegalArgumentException e) {
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// }
// }
// System.out.println("size : "+clone.sx.length);
// for(double d: clone.speedary) System.out.print(d+" ");
// System.out.println("");
// }
// private void log() {
// var_oreten = varspeed /( Math.log10(num_choten2+2));
// var_ramer = varspeed / (Math.log10(ramer+2));
// ppd = sx.length/dist;
// pps = sx.length/(ramerthre*5);
// ppr = sx.length/(ramer+1);
// pts = sx.length;
// dbltime = (double)(time - 1360901083972L)/1000;
// // System.out.println("Math.log10 = "+Math.log10(numrammer+2));
// }
// private void ramer() {
// float minx=java.lang.Float.MAX_VALUE,maxx=java.lang.Float.MIN_VALUE,miny=java.lang.Float.MAX_VALUE,maxy=java.lang.Float.MIN_VALUE;
// for(int i=0;i<sx.length;i++){
// if (sx[i] < minx) minx = sx[i];
// if (sx[i] > maxx) maxx = sx[i];
// if (sy[i] < miny) miny = sy[i];
// if (sy[i] > maxy) maxy = sy[i];
// }
// double w = maxx-minx;
// double h = maxy-miny;
// ramerthre = (w > h) ? w/5 : h/5;
// //TODO: ramer = Rammer.getRammerPoints(sx, sy, (float)ramerthre).size()-2;
// }
// private void angle() {
// if (sx.length > 2) {
// angleary = new double[sx.length-2];
// num_choten = 0;
// //1または2か所の合計で80以上曲がっている折れ点の数を数える。
// double prev_angle = -1.0;
// boolean isprev_choten = false;
// for(int i=0;i<sx.length-2;i++){
// double cos = getAngle(new Point2D.Float(sx[i],sy[i]), new Point2D.Float(sx[i+1],sy[i+1]), new Point2D.Float(sx[i+2],sy[i+2]));
// angleary[i] = cos;
// if (cos > -0.17) {
// num_choten++;
// isprev_choten = true;
// }
// else if ((cos + prev_angle > -1.53) && isprev_choten==false) {//(cos > -0.8) && (prev_angle > -0.8)
// num_choten++;
// isprev_choten = true;
// } else {
// isprev_choten = false;
// }
// sumangle += cos;
// prev_angle = cos;
// }
// }
// // 初めの二つの角度について除外
// if(sx.length > 4){
// angleary2 = new double[sx.length-4];
// double prev_angle2 = -1.0;
// boolean isprev_choten2 = false;
// num_choten2 = 0;
// for(int i=0;i<sx.length-4;i++){
// double cos2 = getAngle(new Point2D.Float(sx[i+2],sy[i+2]), new Point2D.Float(sx[i+3],sy[i+3]), new Point2D.Float(sx[i+4],sy[i+4]));
// angleary2[i] = cos2;
// if (cos2 > -0.17) {
// num_choten2++;
// isprev_choten2 = true;
// }
// else if ((cos2 + prev_angle2 > -1.53) && isprev_choten2==false) {//(cos > -0.8) && (prev_angle > -0.8)
// num_choten2++;
// isprev_choten2 = true;
// } else {
// isprev_choten2 = false;
// }
// prev_angle2 = cos2;
// }
// //折れ点の数をノイズ分ひく
// if(angleary2.length > 0){
// if(angleary2[angleary2.length-1] > -0.17 && speedary[speedary.length-1] < 1.0){
// num_choten2--;
// }
// }
// if(angleary2.length > 1){
// if(angleary2[angleary2.length-2] > -0.17 && (speedary[speedary.length-1]+speedary[speedary.length-2]) < 2.0){
// num_choten2--;
// }
// }
// }
// }
// public void setPreviousSS(ShortStroke pre){
// if (pre == null) return;
// if (pre.penid != this.penid) return;
// // if (pre.paperid != this.paperid) return;
// if (pre.id == this.id-1) {
// previous = pre;
// timediff = this.time - previous.time;
// long pretime = ((previous.sx.length-1)*1000)/75;
// timed = timediff - pretime;
// }
// }
// //筆記のパスの長さ(これをgetSteps()で割ったら平均速度になる)
// public double lengthInPixel(){
// double len = 0;
// double len2 = 0;
// if (sx.length>1){
// speedary = new double[sx.length-1];
// for(int i=1;i<sx.length;i++){
// speedary[i-1] = Math.sqrt((sx[i]-sx[i-1])*(sx[i]-sx[i-1])+(sy[i]-sy[i-1])*(sy[i]-sy[i-1]));
// len = len + speedary[i-1];
// // System.out.println(i+"len1 :"+speedary[i-1]);
// }
// }
// // System.out.println("");
// if (sx.length > 3) {
// speedary2 = new double[sx.length-3];
// for(int i=3;i<sx.length;i++){
// speedary2[i-3] = Math.sqrt((sx[i]-sx[i-1])*(sx[i]-sx[i-1])+(sy[i]-sy[i-1])*(sy[i]-sy[i-1]));
// //System.out.println("speedary : "+speedary[i-1]);
// len2 = len2 + speedary2[i-3];
// //System.out.println(i+"len2 :"+speedary2[i-3]);
// }
// kukan2 = speedary2.length;
// }
// // System.out.println("");
// if (sx.length > 4 ) {
// for(int i=0;i<sx.length;i++){
// }
// // System.out.println("");
// angleary3 = new double[sx.length-4];
// // num_choten = 0;
// //1または2か所の合計で90以上曲がっている折れ点の数を数える。 但し初めの二つの角度については除外
// for(int i=0;i<sx.length-4;i++){
// double cos = getAngle(new Point2D.Float(sx[i+2],sy[i+2]), new Point2D.Float(sx[i+3],sy[i+3]), new Point2D.Float(sx[i+4],sy[i+4]));
// angleary3[i] = cos;
// }
// // System.out.println("同じ"+angleary3.length+speedary.length+sx.length);
// if(angleary3.length > 1){
// if(angleary3[angleary3.length-1] > -0.17 && speedary[speedary.length-1] < 1.0){
// // System.out.println("ts");
// len2 = len2 - speedary2[speedary2.length-1];
// kukan2 = kukan2 - 1;
// }
// }
// if(angleary3.length > 2){
// if(angleary3[angleary3.length-2] > -0.17 && (speedary[speedary.length-1]+speedary[speedary.length-2]) < 2.0){
// len2 = len2 - speedary2[speedary2.length-1] - speedary2[speedary2.length-2];
// kukan2 = kukan2 - 2;
// }
// }
// }
// dist = len;
// length2 = len2;
// return len;
// }
// public double maxspeedInPixel(){ //最大瞬間速度
// double len = 0;
// double tmp = 0;
// if (sx.length >1){
// if (speedary == null) lengthInPixel();
// for(int i=0;i<speedary.length;i++){
// tmp = speedary[i];
// if (len < tmp) len = tmp;
// }
// }
// maxspeed = len;
// return len;
// }
// public double varspeedInPixel(){//速度の分散
// double var = 0;
// double var2 = 0;
// if (sx.length >1){
// if (speedary == null) lengthInPixel();
// avgspeed = dist/speedary.length; //平均速度
// for(int i=0;i<speedary.length;i++){
// double tmp = speedary[i]-avgspeed;
// var = var + (tmp*tmp);
// }
// var = var / speedary.length;
// varspeed = var;
// }
// if (sx.length >3){
// if (speedary2 == null) lengthInPixel();
// avgspeed2 = length2/kukan2;//平均速度
// for(int i=0;i<speedary2.length;i++){
// double tmp2 = speedary2[i]-avgspeed2;
// var2 = var2 + (tmp2*tmp2);
// }
// var2 = var2 / kukan2;
// varspeed2 = var2;
// }
// return var;
// }
// //なす角のcosを求める.1なら反復,-1なら直進
// public static double getAngle(Point2D m1, Point2D m2, Point2D m3){
// double a = m1.distance(m2);
// double b = m2.distance(m3);
// double c = m3.distance(m1);
// double cosC = (a*a+b*b-c*c)/(2*a*b);
// // System.out.println("a "+a+" b "+b+" c "+c+" cosC "+cosC);
// return cosC;
// }
/**
* 途中までの線を構築する
*/
public void showSubpath(int pos) {
reset();
setPathTo(shapel.get(pos));
}
public String getDateTime() {
SimpleDateFormat sdf = new SimpleDateFormat("\"yyyy/MM/dd HH:mm:ss\"");
return sdf.format(time);
}
//ストローク終了時刻とストローク開始時刻の差
public String toCsvTeinei() {
return null;
}
public long current_begin;
public double current_begin_duration;
public int sec10size;
public int sec30size;
public int sec60size;
}
/*
* for(int i=0;i<sx.length;i++){ float x = sx[i]; float y = sy[i]; if (x !=
* ttx1 && y != tty1){ if (((tty1-tty2)*(x-ttx1))!=((ttx1-ttx2)*(y-tty1))){
* double[] tt = new double[2]; tt[0] = x; tt[1] = y; v.add(tt); } ttx2 = ttx1;
* tty2 = tty1; } ttx1 = x; tty1 = y; }
*/