public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { float MinPhotoSize = Browser.MinPhotoScale(Browser.Instance.ClientWidth, Browser.Instance.ClientHeight, Browser.MAXX, Browser.MAXY, photos.Count); //MinPhotoSize = 0f;// ムービー用 float MaxPhotoSize = Browser.MaxPhotoScale(Browser.Instance.ClientWidth, Browser.Instance.ClientHeight, Browser.MAXX, Browser.MAXY, photos.Count); weight_ = weight.ScaleWeight; // アトラクター選択 foreach (Photo a in photos) { // スケール速度 float ds = 0; // added by Gengdai //realMinScale = a.Width > a.Height ? MinPhotoSize * Browser.MAXX / a.Width : MinPhotoSize * Browser.MAXY / a.Height; //realMaxScale = a.Width > a.Height ? MaxPhotoSize * Browser.MAXX / a.Width : MaxPhotoSize * Browser.MAXY / a.Height; realMinScale = a.Width > a.Height ? MinPhotoSize / a.Width : MinPhotoSize / a.Height; realMaxScale = a.Width > a.Height ? MaxPhotoSize / a.Width : MaxPhotoSize / a.Height; followMinScale = realMinScale * 5f; if (followMinScale > realMaxScale) followMinScale = realMaxScale; // 重ならないように制約 if (a.Adjacency.Count == 0) { // 周りに画像がなければMaxPhotoSizeまで拡大させる ds += (realMaxScale - a.Scale) * 0.01f * weight_; } // サイズがMinPhotoSize以下もしくはMaxPhotoSize以上になるのを防ぐ制約 if (a.IsFollowing && a.Scale < followMinScale) { ds += (followMinScale - a.Scale) * 0.02f * weight_; } else if (!a.IsFollowing && a.Scale < realMinScale) { ds += (realMinScale - a.Scale) * 0.02f * weight_; } //if (a.Scale < realMinScale) //{ // ds += (realMinScale - a.Scale) * 0.02f * weight_; //} else if (a.Scale > realMaxScale) { ds -= (a.Scale - realMaxScale) * 0.02f * weight_; } //ノイズを付加する if (false) { float variance = weight.NoiseWeight * 0.2f; float noise = (float)randbm.NextDouble(variance); ds += noise; } a.AddScale(ds); } }
public PhotoDisplay(SystemState st, Dock d, ScrollBar s, StrokeBoxCollection str) { systemState = st; dock = d; sBar = s; strokes = str; //photos = p; weight = new AttractorWeight( NonOverlapWeight, ScaleWeight, AttractToMouseWeight, ScaleUpMouseWeight, TagWeight, NoiseWeight); Stop = false; }
public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { float MinPhotoSize = Browser.MinPhotoScale(Browser.Instance.ClientWidth, Browser.Instance.ClientHeight, Browser.MAXX, Browser.MAXY, photos.Count) * 5; float MaxPhotoSize = Browser.MaxPhotoScale(Browser.Instance.ClientWidth, Browser.Instance.ClientHeight, Browser.MAXX, Browser.MAXY, photos.Count) * 2; weight_ = weight.ScaleUpMouseWeight; // アトラクター選択 foreach (Photo a in activePhotos) { float ds = 0; // スケール // added by Gengdai //realMinScale = a.Width > a.Height ? MinPhotoSize * Browser.MAXX / a.Width : MinPhotoSize * Browser.MAXY / a.Height; //realMaxScale = a.Width > a.Height ? MaxPhotoSize * Browser.MAXX / a.Width : MaxPhotoSize * Browser.MAXY / a.Height; realMinScale = a.Width > a.Height ? MinPhotoSize / a.Width : MinPhotoSize / a.Height; realMaxScale = a.Width > a.Height ? MaxPhotoSize / a.Width : MaxPhotoSize / a.Height; // マウスに重なっているほど大きくしたい //if (a.IsGazeds) { ds += (realMaxScale - a.Scale) * weight_ * 0.05f; // サイズが最小値以下もしくは最大値以上になるのを防ぐ制約 if (a.Scale < realMinScale) { ds += (realMinScale - a.Scale) * weight_ * 0.01f; } else if (a.Scale > realMaxScale) { ds -= (a.Scale - realMaxScale) * weight_ * 0.01f; } // ノイズを付加する if (false) { float variance = weight.NoiseWeight * 0.2f; float noise = (float)randbm.NextDouble(variance); ds += noise; } } a.AddScale(ds); } }
public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { weight_ = weight.NonOverlapWeight; //List<Stroke> strokes = strokeCol.strokeList; for (int i = 0, ilen = strokes.Count; i < ilen; ++i) { if (strokes[i].IsClosed) { foreach (Photo a in photos) { Vector2 v = Vector2.Zero; // 到最近锚点的矢量 Vector2 v2n = Vector2.One * float.MaxValue; foreach (Vector2 s in strokes[i].Strokes) { Vector2 dist = s - a.Position; if (dist.LengthSquared() < v2n.LengthSquared()) { v2n = dist; } } bool inner = strokes[i].IsInternal(a.Position); #if STRICT bool inner1 = strokes[i][j].IsInternal(a.BoudingBox.Min); bool inner2 = strokes[i][j].IsInternal(new Vector2(a.BoudingBox.Min.X, a.BoudingBox.Max.Y)); bool inner3 = strokes[i][j].IsInternal(a.boudingBox_.Max); bool inner4 = strokes[i][j].IsInternal(new Vector2(a.BoudingBox.Max.X, a.BoudingBox.Min.Y)); if(inner || inner1 || inner2 || inner3 || inner4) { #else if (inner) { #endif int matchedTagCount = 0; foreach (string t in strokes[i].Tags) { if (a.containTag(t)) { ++matchedTagCount; break; } } if (matchedTagCount == 0) { v += v2n; v += (a.Position - strokes[i].Center); v *= 0.02f * INTO_DISPLAY * weight_; } #if STRICT } if (!inner || !inner1 || !inner2 || !inner3 || !inner4) { #else } else { #endif int matchedTagCount = 0; foreach (string t in strokes[i].Tags) { if (a.containTag(t)) { ++matchedTagCount; break; } } if (matchedTagCount > 0) { v += v2n; v += (strokes[i].Center - a.Position); v *= 0.02f * INTO_DISPLAY * weight_; } } // 添加噪音 if (false) { if (v != Vector2.Zero) { float variance = weight.NoiseWeight * 0.5f; Vector2 noise = new Vector2((float)randbm.NextDouble(variance), (float)randbm.NextDouble(variance)); v += noise; } } a.AddPosition(v); } } } } }
public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { weight_ = weight.NonOverlapWeight * (Browser.MAXX + Browser.MAXY); // 吸引子选择 foreach (Photo a in photos) { // 速度 Vector2 v = Vector2.Zero; // 避免相邻图像重叠的移动方向 foreach (AdjacentPhoto b in a) { if (a.IsGazeds && b.Photo.IsGazeds) { v += b.Direction * 0.2f * weight_ / 150f; if (a.touchCount != 0 && b.Photo.touchCount != 0) { if (a.touchCount <= b.Photo.touchCount && a.LayerDepth >= b.Photo.LayerDepth) { b.Photo.LayerDepth = a.LayerDepth + 0.001f; if (b.Photo.LayerDepth > 1f) b.Photo.LayerDepth = 1f; } else if (b.Photo.touchCount < a.touchCount && b.Photo.LayerDepth >= a.LayerDepth) { a.LayerDepth = b.Photo.LayerDepth + 0.001f; if (a.LayerDepth > 1f) a.LayerDepth = 1f; } } } else if(!a.IsGazeds) { v += b.Direction * 0.02f * weight_/ 150f; } } // 添加噪声 if (false) { float variance = weight.NoiseWeight * 0.5f; Vector2 noise = new Vector2((float)randbm.NextDouble(variance), (float)randbm.NextDouble(variance)); v += noise; } a.AddPosition(v); #if NO_ROTATION #else // 回転角 float va = 0f; foreach (AdjacentPhoto b in a) { va += b.AngleDirection; } // // float at = 0f; //// 1点を中心に回転させる //Vector2 spinCenter = new Vector2(input.WindowWidth / 2f, input.WindowHeight / 2f); ////spinCenter.Y = input.WindowHeight; //at = (float)(-Math.Atan2((double)(a.Position.X - (double)spinCenter.X), (double)(a.Position.Y - (double)spinCenter.Y))); //if (at > 0) //{ // at -= (float)Math.PI; //} //else //{ // at += (float)Math.PI; //} // できるだけ下を向かせる at = 0f; va += (at - a.Angle); // // // ノイズを付加する if (input.EnabledNoise) { float variance = weight.NoiseWeight * 0.1f; float noise = (float)randbm.NextDouble(variance); va += noise; } a.AddAngle(va); #endif } }
public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { weight_ = weight.NonOverlapWeight; // 吸引子选择 foreach (Photo a in photos) { // 速度 Vector2 v = Vector2.Zero; // 防止图像超出窗口范围 (强制约束) #if NO_ROTATION if (systemState.curState != SystemState.ATTRACTOR_TIME) { if (a.BoundingBox.Min.X < dock.DockBoundX) { v.X -= (a.BoundingBox.Min.X - dock.DockBoundX); } if (a.BoundingBox.Max.X > Browser.Instance.ClientWidth) { v.X -= (a.BoundingBox.Max.X - Browser.Instance.ClientWidth); } if (a.BoundingBox.Min.Y < 0) { v.Y -= (a.BoundingBox.Min.Y); } if (a.BoundingBox.Max.Y > Browser.Instance.ClientHeight) { v.Y -= (a.BoundingBox.Max.Y - Browser.Instance.ClientHeight); } v *= 0.02f * INTO_DISPLAY * weight_; } else { if (a.BoundingBox.Min.Y < sBar.BoundingBox.Max.Y) { v.Y -= (a.BoundingBox.Min.Y - sBar.BoundingBox.Max.Y); } if (a.BoundingBox.Max.Y > Browser.Instance.ClientHeight) { v.Y -= (a.BoundingBox.Max.Y - Browser.Instance.ClientHeight); } v *= 0.02f * INTO_DISPLAY * weight_; } #else float va = 0f; for (int i = 0; i < 4; ++i) { Vector2 v1 = a.Position - a.BoudingBox.Vertex[i]; v1.Normalize(); Vector2 v2 = Vector2.Zero; float dist = 0f; if (a.BoudingBox.Vertex[i].X < input.DockBound) { v2 = Vector2.UnitX; dist = input.DockBound - a.BoudingBox.Vertex[i].X ; } if (a.BoudingBox.Vertex[i].X > input.WindowWidth) { v2 = -Vector2.UnitX; dist = a.BoudingBox.Vertex[i].X - input.WindowWidth; } if (a.BoudingBox.Vertex[i].Y < 0) { v2 = Vector2.UnitY; dist = -a.BoudingBox.Vertex[i].Y; } if (a.BoudingBox.Vertex[i].Y > input.WindowHeight) { v2 = -Vector2.UnitY; dist = a.BoudingBox.Vertex[i].Y - input.WindowHeight; } //v += v1 * (float)(dist * Math.Abs(v1.X * v2.X + v1.Y * v2.Y)); v += dist * v2; va += -(v1.X * v2.Y - v1.Y * v2.X) * INTO_DISPLAY; } v *= 0.02f * INTO_DISPLAY * weight_; #endif // 噪声添加 if (false) { float variance = weight.NoiseWeight * 0.5f; Vector2 noise = new Vector2((float)randbm.NextDouble(variance), (float)randbm.NextDouble(variance)); v += noise; } a.AddPosition(v); #if NO_ROTATION #else if (input.EnabledNoise) { float variance = weight.NoiseWeight * 0.1f; float noise = (float)randbm.NextDouble(variance); va += noise; } a.AddAngle(va); #endif } }
public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { float MinPhotoSize = Browser.MinPhotoScale(Browser.Instance.ClientWidth, Browser.Instance.ClientHeight, Browser.MAXX, Browser.MAXY, photos.Count); //MinPhotoSize = 0f;// movie用 float MaxPhotoSize = Browser.MaxPhotoScale(Browser.Instance.ClientWidth, Browser.Instance.ClientHeight, Browser.MAXX, Browser.MAXY, photos.Count); weight_ = weight.ScaleWeight; // 吸引子选择 foreach (Photo a in photos) { // 大规模速度 float ds = 0; // added by Gengdai //realMinScale = a.Width > a.Height ? MinPhotoSize * Browser.MAXX / a.Width : MinPhotoSize * Browser.MAXY / a.Height; //realMaxScale = a.Width > a.Height ? MaxPhotoSize * Browser.MAXX / a.Width : MaxPhotoSize * Browser.MAXY / a.Height; realMinScale = a.Width > a.Height ? MinPhotoSize / a.Width : MinPhotoSize / a.Height; realMaxScale = a.Width > a.Height ? MaxPhotoSize / a.Width : MaxPhotoSize / a.Height; aPhotoArea = a.Scale * a.Width * a.Scale * a.Height; // 避免重叠的约束 if (a.Adjacency.Count > 0) { foreach (AdjacentPhoto b in a) { bPhotoArea = b.Photo.Scale * b.Photo.Width * b.Photo.Scale * b.Photo.Height; // 如果对方小 // 为防止重叠,MinPhotoSize会缩小 //if (a.IsGazeds) continue; if (bPhotoArea < aPhotoArea) { //if (b.Photo.IsGazeds) //{ // ds -= (a.Scale - realMinScale) * 0.1f * weight_; //} if (a.IsGazeds) continue; else { ds -= (a.Scale - realMinScale) * 0.01f * weight_; } } } } // 防止MinPhotoSize大于MaxPhotoSize if (a.Scale < realMinScale) { ds += (realMinScale - a.Scale) * 0.02f * weight_; } else if (a.Scale > realMaxScale) { ds -= (a.Scale - realMaxScale) * 0.02f * weight_; } // 噪声添加 if (false) { float variance = weight.NoiseWeight * 0.2f; float noise = (float)randbm.NextDouble(variance); ds += noise; } a.AddScale(ds); } }
public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { weight_ = weight.TagWeight; // ���ڂ���Ă���摜��temActivePhoto�Ƃ��� foreach (Photo a in activePhotos) { if (a.activeTag.Count == 0 || (a.activeTag.Count == 1 && a.activeTag.Contains("Color"))) continue; // �e�摜�̈ړ� foreach (Photo photo in photos) { if (photo.ID == a.ID) continue; bool matched = false; foreach (String tag in a.activeTag) { if (tag.Equals("Color")) continue; if (photo.equalTag(tag)) { matched = true; break; } } Vector2 v = a.Position - photo.Position; if (matched) { photo.IsFollowing = true; Vector2 tempdir = Vector2.Zero; float tempdira = 0f; if (a.boundingBox_.Overrap(photo.boundingBox_, ref tempdir, ref tempdira)) { v *= -1f; } v *= (float)3f; } else { v *= -1f; } v *= weight_ / 128f; // noise if (v != Vector2.Zero && false) // noise enabled { float noise = (float)((1 - Math.Exp(-rand.NextDouble())) * Math.PI); noise *= (float)Math.Log(photo.Adjacency.Count + 1); if (rand.NextDouble() < 0.5) { noise *= -1; } float cnoise = (float)Math.Cos(noise); float snoise = (float)Math.Sin(noise); Vector2 noisyv = new Vector2(v.X * cnoise - v.Y * snoise, v.X * snoise + v.Y * cnoise); v = noisyv; } photo.AddPosition(v); } } }
public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { Photo clickedPhoto = null; // 找到被点击的图片 // foreach (Photo a in activePhotos) // { // if (a.IsClicked == true) // { // List<PeopleTag> currentTagList = a.PTags.pTags; // string selectedPeopleName = null; // // 如果被选中的图片没有人物标签则返回,不予处理 // if (currentTagList == null) // return; // foreach (PeopleTag p in currentTagList) // { // Rectangle box = p.Box; // Rectangle newbox = new Rectangle((int)((float)box.X * clickedPhoto.ScaleDisplay), (int)((float)box.Y * clickedPhoto.ScaleDisplay) // , (int)((float)box.Width * clickedPhoto.ScaleDisplay), (int)((float)box.Height * clickedPhoto.ScaleDisplay)); // if (newbox.Contains((int)clickedPhoto.ClickedPoint.X, (int)clickedPhoto.ClickedPoint.Y)) // { // selectedPeopleName = p.People; // break; // } // } // // 如果选中了某人 // if (selectedPeopleName != null) // { // foreach (Photo ph in photos) // { // Vector2 v = Vector2.Zero; // if (a.Tag.Contains(selectedPeopleName)) // 对于那些被吸引的图像 // { // v = clickedPhoto.Position - a.Position; // 吸引 // v *= weight_1 / 2f;// 10f; // } // else // 为被吸引的图像 // { // v = a.Position - clickedPhoto.Position; // 排斥 // v *= weight_2 / 3.0f;// 10f; // } // // 改变噪声方向 // if (v != Vector2.Zero && false) // { // float noise = (float)((1 - Math.Exp(-rand.NextDouble())) * Math.PI); // noise *= (float)Math.Log(a.Adjacency.Count + 1); // if (rand.NextDouble() < 0.5) // { // noise *= -1; // } // float cnoise = (float)Math.Cos(noise) / 3f; // float snoise = (float)Math.Sin(noise) / 3f; // Vector2 noisyv = new Vector2(v.X * cnoise - v.Y * snoise, v.X * snoise + v.Y * cnoise); // v = noisyv; // } // // 将改变的向量v作用于图像 // a.AddPosition(v); // } // } // //deal with one photo everytime // break; // } // } }
//private List<SStringIntInt> geotagList_ = new List<SStringIntInt>(); public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { weight_ = weight.NonOverlapWeight; baseX = Browser.Instance.ClientWidth; baseY = Browser.Instance.ClientHeight; // 从ini文件获取geotag信息 if (countryInfo.Count < 1) {//84.034319, 179.947926-51.289405, -148.059888 //83.842130, 170.423871 leftup.Add(-160.210936f); leftup.Add(88.780861f); rightDown.Add(170.976559f); rightDown.Add(-79.319496f); //leftup.Add(-179.947926f); //leftup.Add(84.034319f); //rightDown.Add(148.059888f); //rightDown.Add(-51.289405f); dx = rightDown[0] - leftup[0]; dy = rightDown[1] - leftup[1]; string home = "C:\\PhotoViewer"; string iniName = "geotagList_AA.ini"; if (File.Exists(home + "\\" + iniName)) { string gtl = File.ReadAllText(home + "\\" + iniName); string[] sep = new string[1]; sep[0] = "\r\n"; string[] gts = gtl.Split(sep, StringSplitOptions.RemoveEmptyEntries); for (int i = 0, ilen = gts.Length; i < ilen; ++i) { sep[0] = ":"; string[] gt = gts[i].Split(sep, StringSplitOptions.RemoveEmptyEntries); sep[0] = ","; string[] xy = gt[1].Split(sep, StringSplitOptions.RemoveEmptyEntries); List<float> degree = new List<float>(); degree.Add((float.Parse(xy[1]) - leftup[0])/dx); degree.Add((float.Parse(xy[0]) - leftup[1])/dy); countryInfo[gt[0]] = degree; // 地名,xy坐标 } } } foreach (Photo a in photos) { Vector2 v = Vector2.Zero; bool flag = false; //foreach (var str in strokes) //{ // if (str.relatedPhotos.Contains(a)) // { // flag = true; // break; // } //} //if (flag) // continue; foreach (string country in countryInfo.Keys) { if (a.containTag(country)) { Vector2 target = new Vector2(countryInfo[country][0] * Browser.Instance.ClientWidth, countryInfo[country][1] * Browser.Instance.ClientHeight); v += target - a.Position; break; } } // 改变噪声方向 if (v != Vector2.Zero && false) { float noise = (float)((1 - Math.Exp(-rand.NextDouble())) * Math.PI); noise *= (float)Math.Log(a.Adjacency.Count + 1); if (rand.NextDouble() < 0.5) { noise *= -1; } float cnoise = (float)Math.Cos(noise); float snoise = (float)Math.Sin(noise); Vector2 noisyv = new Vector2(v.X * cnoise - v.Y * snoise, v.X * snoise + v.Y * cnoise); v = noisyv; } a.AddPosition(v); } }
public void select(Dock dock, ScrollBar sBar, AttractorWeight weight, List<Photo> photos, List<Photo> activePhotos, List<Stroke> strokes, SystemState systemState) { weight_ = weight.NonOverlapWeight; // 最も古い写真と新しい写真の撮影日時を取得 DateTime mindt = DateTime.MaxValue; DateTime maxdt = DateTime.MinValue; foreach (Photo a in photos) { if (a.ptag.startDate == 0) { continue; } DateTime start = new DateTime(a.ptag.startDate,1,1); DateTime end = new DateTime(a.ptag.endDate,12,31); if (mindt > start) { mindt = start; } if (maxdt < end) { maxdt = end; } } sBar.Oldest = mindt; sBar.Newest = maxdt; // ウインドウ表示範囲内で最も古い写真と新しい写真の撮影日時を指定 double max = maxdt.Subtract(mindt).TotalSeconds; double minw = max * (double)sBar.Min / (double)sBar.Width; double maxw = max * (double)sBar.Max / (double)sBar.Width; foreach (Photo a in photos) { Vector2 v = Vector2.Zero; if (a.ptag.startDate == 0) continue; DateTime start = new DateTime(a.ptag.startDate, 1, 1); DateTime end = new DateTime(a.ptag.endDate, 12, 31); double x = start.Subtract(mindt).TotalSeconds; x -= minw; if (x < 0 && end.Year > start.Year) { x = end.Subtract(mindt).TotalSeconds; x -= minw; } x *= (double)sBar.Width / Math.Max((maxw - minw), 1d); if(x + a.Width/2 > sBar.Width) v = Vector2.UnitX * (float)(x - a.Position.X - a.Width/2) * 0.02f * weight_; else if(x - a.Width/2 < 0) v = Vector2.UnitX * (float)(x - a.Position.X + a.Width/2) * 0.02f * weight_; else v = Vector2.UnitX * (float)(x - a.Position.X) * 0.02f * weight_; // ノイズで方向を変化させる if (v != Vector2.Zero && false) { float noise = (float)((1 - Math.Exp(-rand.NextDouble())) * Math.PI); noise *= (float)Math.Log(a.Adjacency.Count + 1); if (rand.NextDouble() < 0.5) { noise *= -1; } float cnoise = (float)Math.Cos(noise); float snoise = (float)Math.Sin(noise); Vector2 noisyv = new Vector2(v.X * cnoise - v.Y * snoise, v.X * snoise + v.Y * cnoise); v = noisyv; } a.AddPosition(v); } }