• R/O
  • SSH
  • HTTPS

marathon: コミット


コミットメタ情報

リビジョン291 (tree)
日時2007-05-13 21:01:54
作者hogepiyo

ログメッセージ

*** empty log message ***

変更サマリ

差分

--- marathon/trunk/MapEditorOne/src/PresetPolygon.cpp (nonexistent)
+++ marathon/trunk/MapEditorOne/src/PresetPolygon.cpp (revision 291)
@@ -0,0 +1,62 @@
1+#include "PresetPolygon.h"
2+#include "HPLLib/HPLAlephLib.h"
3+
4+/**
5+ 頂点の数を指定して生成
6+ @param n the number of edges
7+*/
8+mapeditorone::PresetPolygon::PresetPolygon(int n)
9+{
10+ //3角形以下はダメなので3角形にする
11+ if(n < 3){
12+ n = 3;
13+ }
14+
15+ //8角形より上ではエラーを起こす
16+ if(n > 8){
17+ n = 8;
18+ }
19+ this->num = n;
20+}
21+mapeditorone::PresetPolygon::~PresetPolygon()
22+{
23+}
24+
25+const int ROUND_DEGREE = 360;
26+
27+/**
28+ 範囲指定からポリゴン座標を得ます
29+*/
30+void mapeditorone::PresetPolygon::getPoints(int x0, int y0, int x1, int y1, int *dest)
31+{
32+ //p0が左上、p1が右下になるようにセット
33+ if(x0 > x1){
34+ hpl::math::exchange<int>(&x0, &x1);
35+ }
36+ if(y0 > y1){
37+ hpl::math::exchange<int>(&y0, &y1);
38+ }
39+ //中心座標→頂点までの距離を半径とする円を想定する
40+ int centerX = x0 + (x1 - x0) / 2;
41+ int centerY = y0 + (y1 - y0) / 2;
42+ int r = sqrt(pow(centerX - x0, 2) + pow(centerY - y0, 2));
43+
44+ //円を元に正n角形を取得する
45+ //求める円周上の点
46+ int points[8][2];
47+ //正n角形の各辺に対する中心角
48+ int degInterval = ROUND_DEGREE / this->num;
49+ for(int degStep = 0; degStep < this->num; degStep ++){
50+ int degree = degStep * degInerval;
51+
52+ //水平右が0度、真下が90度なので、-90する
53+ degree -= (ROUND_DEGREE / 4);
54+
55+ double rad = hpl::math::getRadianFromDegree(degree);
56+ points[degStep][0] = cos(rad) * r;
57+ points[degStep][1] = sin(rad) * r;
58+
59+ //長方形との交点を求める
60+
61+ }
62+}
--- marathon/trunk/MapEditorOne/src/PresetPolygon.h (nonexistent)
+++ marathon/trunk/MapEditorOne/src/PresetPolygon.h (revision 291)
@@ -0,0 +1,32 @@
1+/**
2+ 標準で準備されたポリゴン情報
3+ a polygon information which is preset
4+*/
5+#ifndef _PRESET_POLYGON_
6+#define _PRESET_POLYGON_
7+
8+namespace mapeditorone{
9+ class PresetPolygon{
10+ private:
11+
12+ /**
13+ 頂点の数
14+ the number of edges
15+ */
16+ int num;
17+
18+ public:
19+ /**
20+ 頂点の数を指定して生成
21+ @param n the number of edges
22+ */
23+ PresetPolygon(int n);
24+ ~PresetPolygon();
25+
26+ /**
27+ 範囲指定からポリゴン座標を得ます
28+ */
29+ void getPoints(int x0, int y0, int x1, int y1, int *dest);
30+ };
31+};
32+#endif
--- marathon/trunk/MapEditorOne/src/MapEditorSDI.cpp (revision 290)
+++ marathon/trunk/MapEditorOne/src/MapEditorSDI.cpp (revision 291)
@@ -289,6 +289,7 @@
289289
290290 CMapEditorSDIApp::~CMapEditorSDIApp()
291291 {
292+ delete gridManager;
292293 if(!setting.saveSetting()){
293294 AfxMessageBox(CString("fail to save setting:") + setting.getFilePath());
294295 }
--- marathon/trunk/MapEditorOne/src/MapEditorOneInnerSetting.cpp (revision 290)
+++ marathon/trunk/MapEditorOne/src/MapEditorOneInnerSetting.cpp (revision 291)
@@ -11,43 +11,59 @@
1111
1212 mapeditorone::MapEditorOneInnerSetting::MapEditorOneInnerSetting(const char* tagNameFilePath, const char* dataFilePath)
1313 {
14- std::ifstream ifs;
15- ifs.open(tagNameFilePath);
16- if(!ifs.is_open()){
17- MessageBox(NULL, L"Cannot open tag file", L"", MB_OK);
18- exit(-1);
19- }
20- //タグ読み取り
2114 char buf[MAX_FILE_PATH];
22- int counter = 0;
23- while(ifs.getline(buf, MAX_FILE_PATH) != NULL){
24- if(strcmp(buf, "")){
25- continue;
15+ {
16+ std::ifstream ifs;
17+ ifs.open(tagNameFilePath);
18+ if(!ifs.is_open()){
19+ MessageBox(NULL, L"Cannot open tag file", L"", MB_OK);
20+ exit(-1);
2621 }
27- std::string src(buf);
28- tagMap[counter] = src;
22+ //タグ読み取り
23+ int counter = 0;
24+ while(ifs.getline(buf, MAX_FILE_PATH) != NULL){
25+ if(strcmp(buf, "") == 0){
26+ continue;
27+ }
28+ std::string src(buf);
29+ tagMap[counter] = src;
30+ counter ++;
31+ }
32+ if(counter < mapeditorone::TagType::MaxTagTypes){
33+ MessageBox(NULL, L"The number of InnerSetting tags is too few", L"Error", MB_OK);
34+ exit(1);
35+ }
36+ ifs.close();
2937 }
30- ifs.close();
3138
32- ifs.open(dataFilePath);
33- if(!ifs.is_open()){
34- MessageBox(NULL, L"Cannot open inner data file", L"", MB_OK);
35- exit(-1);
36- }
37- while(ifs.getline(buf, MAX_FILE_PATH) != NULL){
38- std::string src(buf);
39- std::vector<std::string> pair = hpl::string::Split(src, "=");
40- if(pair.size() < 2){
41- //空白は無視
42- continue;
39+ {
40+ ifstream ifs(dataFilePath);
41+ if(!ifs.is_open()){
42+ MessageBox(NULL, L"Cannot open inner data file", L"", MB_OK);
43+ exit(-1);
4344 }
44- for(int i = 0; i < mapeditorone::TagType::MaxTagTypes; i ++){
45- if(pair[0].compare(tagMap[i]) == 0){
46- datas[i] = pair[1];
45+ int counter = 0;
46+ while(ifs.getline(buf, MAX_FILE_PATH) != NULL){
47+ std::string src(buf);
48+ std::vector<std::string> pair = hpl::string::Split(src, "=");
49+ if(pair.size() < 2){
50+ //空白は無視
51+ continue;
4752 }
53+ for(int i = 0; i < mapeditorone::TagType::MaxTagTypes; i ++){
54+ if(pair[0].compare(tagMap[i]) == 0){
55+ datas[i] = pair[1];
56+ counter ++;
57+ break;
58+ }
59+ }
4860 }
61+ if(counter < mapeditorone::TagType::MaxTagTypes){
62+ MessageBox(NULL, L"The number of InnerSetting datas is too few", L"Error", MB_OK);
63+ exit(1);
64+ }
65+ ifs.close();
4966 }
50- ifs.close();
5167 }
5268 mapeditorone::MapEditorOneInnerSetting::~MapEditorOneInnerSetting()
5369 {
--- marathon/trunk/MapEditorOne/src/MapEditorSDIView.h (revision 290)
+++ marathon/trunk/MapEditorOne/src/MapEditorSDIView.h (revision 291)
@@ -18,7 +18,6 @@
1818 // 操作
1919 public:
2020
21-// オーバーライド
2221 public:
2322 void drawBackground(CDC *cdc);
2423 void drawGrid(CDC *cdc);
@@ -27,7 +26,9 @@
2726 void drawPoints(CDC *cdc);
2827 void drawObjects(CDC *cdc);
2928 void drawStrings(CDC *cdc);
29+ void setupSelectDataGroupOffsets(POINT point);
3030
31+// オーバーライド
3132 virtual void OnDraw(CDC* pDC); // このビューを描画するためにオーバーライドされます。
3233 virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
3334 protected:
@@ -34,7 +35,7 @@
3435 virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
3536 virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
3637 virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
37- void addZoom(int step);
38+ //void addZoom(int step);
3839 void createDoubleBuffer();
3940 void moveMapOffset(int newPx, int newPy);
4041 void setStartPointForSelectGroup(int px, int py);
--- marathon/trunk/MapEditorOne/src/resource.h (revision 290)
+++ marathon/trunk/MapEditorOne/src/resource.h (revision 291)
@@ -82,6 +82,8 @@
8282 #define IDD_DIALOG_TEXTURE 247
8383 #define IDD_DIALOG6 248
8484 #define IDD_DIALOG_TEXTURE_CHILD 248
85+#define IDB_BITMAP1 249
86+#define IDB_BITMAP_PATTERN_INVALID 249
8587 #define IDC_LIST1 1000
8688 #define IDC_LIST2 1002
8789 #define IDC_COMBO1 1003
@@ -210,7 +212,7 @@
210212 //
211213 #ifdef APSTUDIO_INVOKED
212214 #ifndef APSTUDIO_READONLY_SYMBOLS
213-#define _APS_NEXT_RESOURCE_VALUE 249
215+#define _APS_NEXT_RESOURCE_VALUE 250
214216 #define _APS_NEXT_COMMAND_VALUE 32809
215217 #define _APS_NEXT_CONTROL_VALUE 1059
216218 #define _APS_NEXT_SYMED_VALUE 104
--- marathon/trunk/MapEditorOne/src/MapEditorSDIView.cpp (revision 290)
+++ marathon/trunk/MapEditorOne/src/MapEditorSDIView.cpp (revision 291)
@@ -700,12 +700,19 @@
700700 */
701701 BOOL CMapEditorSDIView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
702702 {
703- static short oldZDelta = zDelta;
703+// static short oldZDelta = zDelta;
704704
705705
706706 // TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。
707707 if(nFlags & MK_CONTROL){
708- addZoom( -1 * hpl::math::sgn<int>(zDelta) * ZOOM_DIVISION_STEP);
708+ //addZoom( -1 * hpl::math::sgn<int>(zDelta) * ZOOM_DIVISION_STEP);
709+ CRect rect;
710+ GetClientRect(&rect);
711+ if(zDelta < 0){
712+ theApp.gridManager->zoomIn(rect.Width(), rect.Height());
713+ }else{
714+ theApp.gridManager->zoomOut(rect.Width(), rect.Height());
715+ }
709716 Invalidate(FALSE);
710717 }
711718 return CView::OnMouseWheel(nFlags, zDelta, pt);
--- marathon/trunk/MapEditorOne/src/MapEditorSDIView_Event.cpp (revision 290)
+++ marathon/trunk/MapEditorOne/src/MapEditorSDIView_Event.cpp (revision 291)
@@ -89,20 +89,14 @@
8989 //selecting tool = TI_ARROW
9090 //矢印ツール時
9191
92- if(/*!(nFlags & MK_SHIFT) && */!(nFlags & MK_CONTROL)){
92+ if(!(nFlags & MK_CONTROL)){
9393 //コントロールキーを押さずに
9494 //clik without modify key
95-
96- //→移動準備
97- //->ready for move
9895
99- //既に選択している状態
100- //group selected
101- if(//theApp.isSelectingGroup &&
102- theApp.selectDatas.isSelected()){
96+ if(theApp.selectDatas.isSelected())
97+ {
98+ //複数を選択中
10399
104- //点をクリックしたかどうか
105- //is point in objects/points/lines/polygons?
106100 if(isPointInSelection(point.x, point.y,
107101 OFFSET_X_VIEW, OFFSET_Y_VIEW, OFFSET_X_WORLD, OFFSET_Y_WORLD,
108102 POINT_DISTANCE_EPSILON, LINE_DISTANCE_EPSILON, OBJECT_DISTANCE_EPSILON,
@@ -109,73 +103,12 @@
109103 &theApp.selectDatas, theApp.viewHeightMax, theApp.viewHeightMin,
110104 DIV))
111105 {
106+ //複数選択をクリック
107+
112108 //click on selecting group
113109 //->remember offset, ready to move
110+ this->setupSelectDataGroupOffsets(point);
114111
115- //points
116- std::vector<struct hpl::aleph::map::SelPoint>* selpoints = theApp.selectDatas.getSelPoints();
117- for(int i = 0; i < (int)selpoints->size(); i ++){
118- endpoint_data* ep = &EndpointList[selpoints->at(i).index];
119- //set pos to view
120- int x = ep->vertex.x;
121- int y = ep->vertex.y;
122- //ビュー座標に変換
123- int drawP[2];
124- getViewPointFromWorldPoint2D(ep->vertex, drawP);
125-
126- //sub to offset
127- selpoints->at(i).offset[0] = drawP[0] - point.x;
128- selpoints->at(i).offset[1] = drawP[1] - point.y;
129- }
130-
131- //lines
132- std::vector<struct hpl::aleph::map::SelLine>* sellines = theApp.selectDatas.getSelLines();
133- for(int i = 0; i < (int)sellines->size(); i ++){
134- struct hpl::aleph::map::SelLine* selData = &sellines->at(i);
135- line_data* line = &LineList[selData->index];
136- endpoint_data* begin = &EndpointList[line->endpoint_indexes[0]];
137- endpoint_data* end = &EndpointList[line->endpoint_indexes[1]];
138- int beginViewP[2], endViewP[2];
139- getViewPointFromWorldPoint2D(begin->vertex, beginViewP);
140- getViewPointFromWorldPoint2D(end->vertex, endViewP);
141- //set offsets
142- sellines->at(i).offset[0][0] = beginViewP[0] - point.x;
143- sellines->at(i).offset[0][1] = beginViewP[1] - point.y;
144- sellines->at(i).offset[1][0] = endViewP[0] - point.x;
145- sellines->at(i).offset[1][1] = endViewP[1] - point.y;
146-
147- }
148-
149- /*
150- //polygons
151- std::vector<struct hpl::aleph::map::SelPolygon>* selpolygons = theApp.selectDatas.getSelPolygons();
152- for(int i = 0; i < (int)selpolygons->size(); i ++){
153- struct hpl::aleph::map::SelPolygon* selData = &selpolygons->at(i);
154- //set offset
155- polygon_data *polygon = &PolygonList[selData->index];
156- int num = polygon->vertex_count;
157- selpolygons->at(i).num = num;
158- for(int j = 0; j < num; j ++){
159- int drawViewP[2];
160- hpl::aleph::map::getViewPointFromWorldPoint2D(EndpointList[polygon->endpoint_indexes[j]].vertex, drawViewP,
161- OFFSET_X_WORLD, OFFSET_Y_WORLD, DIV, viewOffset[0], viewOffset[1]);
162-
163- }
164- }
165- */
166- //objects
167- std::vector<struct hpl::aleph::map::SelObject>* selobjects = theApp.selectDatas.getSelObjects();
168- for(int i = 0; i < (int)selobjects->size(); i ++){
169- struct hpl::aleph::map::SelObject* selData = &selobjects->at(i);
170- map_object* obj = &SavedObjectList[selData->index];
171- //set pos to view
172- int drawViewP[2];
173- getViewPointFromWorldPoint2D(obj->location.x, obj->location.y, drawViewP);
174-
175- //sub to offset
176- selData->offset[0] = drawViewP[0] - point.x;
177- selData->offset[1] = drawViewP[1] - point.y;
178- }
179112 }else{
180113 //release all selection
181114 theApp.selectDatas.clear();
@@ -314,8 +247,12 @@
314247 //////////////////////////////////
315248 //ここからの処理はほかよりも後に書く
316249 if(!theApp.selectDatas.isSelected()){
250+ //選択されなかった
251+ //no selection found
252+
317253 //範囲選択
318254 //始点登録
255+ //
319256 setStartPointForSelectGroup(point.x, point.y);
320257
321258 theApp.selectDatas.clear();
@@ -436,6 +373,78 @@
436373 }
437374
438375 /**
376+ セットアップ
377+*/
378+void CMapEditorSDIView::setupSelectDataGroupOffsets(POINT point)
379+{
380+ //points
381+ std::vector<struct hpl::aleph::map::SelPoint>* selpoints = theApp.selectDatas.getSelPoints();
382+ for(int i = 0; i < (int)selpoints->size(); i ++){
383+ endpoint_data* ep = &EndpointList[selpoints->at(i).index];
384+ //set pos to view
385+ int x = ep->vertex.x;
386+ int y = ep->vertex.y;
387+ //ビュー座標に変換
388+ int drawP[2];
389+ getViewPointFromWorldPoint2D(ep->vertex, drawP);
390+
391+ //sub to offset
392+ selpoints->at(i).offset[0] = drawP[0] - point.x;
393+ selpoints->at(i).offset[1] = drawP[1] - point.y;
394+ }
395+
396+ //lines
397+ std::vector<struct hpl::aleph::map::SelLine>* sellines = theApp.selectDatas.getSelLines();
398+ for(int i = 0; i < (int)sellines->size(); i ++){
399+ struct hpl::aleph::map::SelLine* selData = &sellines->at(i);
400+ line_data* line = &LineList[selData->index];
401+ endpoint_data* begin = &EndpointList[line->endpoint_indexes[0]];
402+ endpoint_data* end = &EndpointList[line->endpoint_indexes[1]];
403+ int beginViewP[2], endViewP[2];
404+ getViewPointFromWorldPoint2D(begin->vertex, beginViewP);
405+ getViewPointFromWorldPoint2D(end->vertex, endViewP);
406+ //set offsets
407+ sellines->at(i).offset[0][0] = beginViewP[0] - point.x;
408+ sellines->at(i).offset[0][1] = beginViewP[1] - point.y;
409+ sellines->at(i).offset[1][0] = endViewP[0] - point.x;
410+ sellines->at(i).offset[1][1] = endViewP[1] - point.y;
411+
412+ }
413+
414+ //polygons
415+ std::vector<struct hpl::aleph::map::SelPolygon>* selpolygons = theApp.selectDatas.getSelPolygons();
416+ for(int i = 0; i < (int)selpolygons->size(); i ++){
417+ struct hpl::aleph::map::SelPolygon* selData = &selpolygons->at(i);
418+ //set offset
419+ polygon_data *polygon = &PolygonList[selData->index];
420+ int num = polygon->vertex_count;
421+ selpolygons->at(i).num = num;
422+ for(int j = 0; j < num; j ++){
423+ int drawViewP[2];
424+ getViewPointFromWorldPoint2D(
425+ EndpointList[polygon->endpoint_indexes[j]].vertex, drawViewP);
426+ selData->offset[j][0] = drawViewP[0] - point.x;
427+ selData->offset[j][1] = drawViewP[1] - point.y;
428+ }
429+ }
430+
431+ //objects
432+ std::vector<struct hpl::aleph::map::SelObject>* selobjects = theApp.selectDatas.getSelObjects();
433+ for(int i = 0; i < (int)selobjects->size(); i ++){
434+ struct hpl::aleph::map::SelObject* selData = &selobjects->at(i);
435+ map_object* obj = &SavedObjectList[selData->index];
436+ //set pos to view
437+ int drawViewP[2];
438+ getViewPointFromWorldPoint2D(obj->location.x, obj->location.y, drawViewP);
439+
440+ //sub to offset
441+ selData->offset[0] = drawViewP[0] - point.x;
442+ selData->offset[1] = drawViewP[1] - point.y;
443+ }
444+}
445+
446+
447+/**
439448 ポリゴンを選択したかどうか判断します
440449 */
441450 void checkPolygonSelect(UINT nFlags, CPoint point)
@@ -491,6 +500,7 @@
491500 theApp.isPressLButtonWithCtrl = true;
492501 }
493502 if(nFlags & MK_CONTROL){
503+ //Ctrlを押しながら
494504 }else{
495505 doLButtonDownDrawMode(nFlags, point);
496506 }
@@ -527,11 +537,15 @@
527537 SetCapture();
528538 }
529539
540+/**
541+ オフセット移動
542+*/
530543 void CMapEditorSDIView::moveMapOffset(int newPx, int newPy){
531544 int oldMousePoint[2];
532545 theApp.gridManager->getOldMousePoint(oldMousePoint);
533546 int deltaX = newPx - oldMousePoint[0];
534547 int deltaY = newPy - oldMousePoint[1];
548+
535549 int offset[2];
536550 theApp.gridManager->getOffset(offset);
537551 offset[0] += deltaX;
@@ -561,12 +575,16 @@
561575 }
562576 #else
563577 if(nFlags & MK_LBUTTON && ((nFlags & MK_CONTROL && theApp.isPressLButtonWithCtrl) ||
564- (theApp.getEditMode() == EM_DRAW && theApp.selectingToolType == TI_HAND))){
578+ (theApp.getEditMode() == EM_DRAW && theApp.selectingToolType == TI_HAND)))
579+ {
580+ //コントロールキー押しながら左→オフセット移動
565581 //Control+L=move map view
566582 moveMapOffset(point.x, point.y);
567583 }else{
568584 if(theApp.getEditMode() == EM_DRAW){
585+ //ドローモード
569586 if(theApp.selectingToolType == TI_ARROW){
587+ //矢印ツール
570588 if(!theApp.isPressLButtonWithCtrl &&
571589 (nFlags & MK_LBUTTON) && /*!(nFlags & MK_CONTROL) && */
572590 !(nFlags & MK_CONTROL))
@@ -671,6 +689,8 @@
671689 void CMapEditorSDIView::OnLButtonUp(UINT nFlags, CPoint point)
672690 {
673691 // TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。
692+
693+ //Ctrlを押しながら左ボタンを押しているか
674694 theApp.isPressLButtonWithCtrl = false;
675695
676696 if(theApp.selectingToolType == TI_ARROW){
@@ -686,18 +706,11 @@
686706 //ポリゴン情報更新
687707 theApp.polygonPropertyDialog->setupDialog(theApp.selectDatas.getSelPolygons()->at(0).index);
688708 }
709+
689710 if(theApp.isSelectingGroup){
690- /*if(isNearbyPoints(point.x, point.y,
691- theApp.selectStartPoint.x, theApp.selectStartPoint.y, SELECT_GROUP_DISTANCE_THRESHOLD))
692- {
693- //
694- theApp.selectDatas.setSelected(false);
695- }else{
696- okSelect = true;
697- }*/
698- okSelect = true;
699- }
700- if(okSelect){
711+ //範囲選択中
712+
713+
701714 //if selecting is only 1 object. setup property dialog
702715
703716 //int OFFSET_X_VIEW = theApp.offset.x;
@@ -823,6 +836,7 @@
823836 }else if(theApp.selectingToolType == TI_SKULL){
824837 }else if(theApp.selectingToolType == TI_TEXT){
825838 }
839+ //ボタンアップ→選択解除
826840 theApp.isSelectingGroup = false;
827841 Invalidate(FALSE);
828842 ReleaseCapture();
--- marathon/trunk/HPLLib/HPLMath.h (revision 290)
+++ marathon/trunk/HPLLib/HPLMath.h (revision 291)
@@ -3,6 +3,17 @@
33
44 namespace hpl{
55 namespace math{
6+ /**
7+ 線の種類
8+ */
9+ namespace LineType{
10+ enum{
11+ Normal,
12+ Horizontal,
13+ Vertical,
14+ };
15+ };
16+
617 //exchange between a and b
718 template<class T>
819 void exchange(T *a, T *b)
@@ -113,6 +124,55 @@
113124 */
114125 double optimizeDegree(double deg);
115126 double optimizeRadian(double rad);
127+
128+ /////////////////////////////////////////////////////
129+ ///////////// cross ///////////////////////////////
130+ /**
131+ 2つの線分が交差した点を取得します。
132+ @param line0 線0
133+ @param line1 線1
134+ @return 2つの線分が交差していない場合偽
135+ */
136+ bool getCrossPointOfTwoLines(double line0[2][2],
137+ double line1[2][2], double dest[2]);
138+
139+ /**
140+ 線分の端点データから、その線の傾きと切片を求めます
141+ 水平線か垂直な線の場合は傾きが逆軸になってるので注意
142+ @param line line datas ([0][0],[0][1])-([1][0],[1][1])
143+ @param
144+ */
145+ int getLineAngleAndSlice(double line[2][2], double *degree, double *slice);
146+
147+ /**
148+ 線の傾きを角度から得ます
149+ */
150+ double getAngleFromDegree(double degree);
151+
152+ ///////////////////
153+ /**
154+ 点から線分への距離(垂線の長さ)を求めます
155+ <en>get
156+ */
157+ double getPointDistanceFromLine(double px, double py,
158+ double lx0, double ly0, double lx1, double ly1);
159+
160+ /**
161+ <jp>三平方の定理で長さを求める
162+ <en>get length of (0,0)-(x,y)
163+ */
164+ double getLength(double x, double y);
165+
166+ /**
167+ <jp>内積を求めます
168+ */
169+ double getInnerProduct(double x0, double y0, double x1, double y1);
170+
171+ /**
172+ 点から降ろした垂線が線分と交差するか判断
173+ */
174+ bool isCrossPointLine(double px, double py,
175+ double lx0, double ly0, double lx1, double ly1);
116176 };
117177 };
118178 #endif
--- marathon/trunk/HPLLib/HPLViewGridManager.cpp (revision 290)
+++ marathon/trunk/HPLLib/HPLViewGridManager.cpp (revision 291)
@@ -34,7 +34,7 @@
3434 */
3535 void hpl::aleph::view::HPLViewGridManager::zoomIn(int viewW, int viewH)
3636 {
37- this->addZoom(this->zoomProperties.zoomDivisionStep, viewW, viewH);
37+ this->addZoom(-this->zoomProperties.zoomDivisionStep, viewW, viewH);
3838 }
3939
4040 /**
@@ -61,12 +61,13 @@
6161 void hpl::aleph::view::HPLViewGridManager::addZoom(int step, int viewW, int viewH)
6262 {
6363 int oldZoomDiv = this->zoomDivision;
64-
64+
6565 //拡大割率が閾値を越えたら増減速度Down
6666 //<en>set zoom step small when division num is over threshold
6767 if(zoomDivision < this->zoomProperties.zoomDivStepThreshold){
6868 step = hpl::math::sgn<int>(step) * this->zoomProperties.zoomDivisionStepDetail;
6969 }
70+ this->zoomDivision += step;
7071
7172 //adjustment
7273 if(this->zoomDivision < this->zoomProperties.zoomDivisionMin){
--- marathon/trunk/HPLLib/HPLMapTool.cpp (revision 290)
+++ marathon/trunk/HPLLib/HPLMapTool.cpp (revision 291)
@@ -104,6 +104,7 @@
104104 */
105105 void hpl::aleph::map::fixLine(int index, bool isDeleteOldSide)
106106 {
107+ //TODO
107108 if(index < 0 || index >= (int)LineList.size()){
108109 return;
109110 }
@@ -151,6 +152,28 @@
151152 line->length = static_cast<int>(length);
152153 }
153154
155+/**
156+ 線情報を線を構成する点によって取得します
157+ get line index with two point indexes
158+ @return 線が存在しない場合NONE
159+*/
160+int hpl::aleph::map::getLineIndexFromTwoLPoints(int pindex0, int pindex1)
161+{
162+ for(int i = 0; i < (int)LineList.size(); i ++){
163+ line_data* line = get_line_data(i);
164+ int ep0 = line->endpoint_indexes[0];
165+ int ep1 = line->endpoint_indexes[1];
166+
167+ if((ep0 == pindex0 && ep1 == pindex1) ||
168+ (ep1 == pindex0 && ep0 == pindex1))
169+ {
170+ //双方が一致した場合のみ返す
171+ return i;
172+ }
173+ }
174+ return NONE;
175+}
176+
154177 /////////////////////// Sides ////////////////////////////////////////////
155178 void hpl::aleph::map::fixSide(int sideIndex)
156179 {
--- marathon/trunk/HPLLib/HPLMapTool.h (revision 290)
+++ marathon/trunk/HPLLib/HPLMapTool.h (revision 291)
@@ -117,6 +117,13 @@
117117 */
118118 void fixLine(int index, bool isDeleteOldSide);
119119
120+ /**
121+ 線情報を線を構成する点によって取得します
122+ get line index with two point indexes
123+ @return 線が存在しない場合NONE
124+ */
125+ int getLineIndexFromTwoLPoints(int pindex0, int pindex1);
126+
120127 ////////////////////////////////////////////////////////////////////////
121128 /////////// Sides ////////////////////////////////////////////////////
122129
@@ -157,6 +164,18 @@
157164 bool isValidPolygon(int index);
158165
159166 /**
167+ 座標を取り囲むポリゴンのうち、ポリゴンとして成立しているものをさがします
168+ すでにポリゴンが存在している場合は無視します
169+ @param wpoint 探索基点。ここを囲むポリゴンを探す
170+ @param heightMin 高さ制限最小値
171+ @param heightMax 高さ制限最大値
172+ @param pointIndexes 見つかった場合ここに点番号が「右回り順」で入れられます
173+ @param lineIndexes 見つかった場合ここに線番号が「右回り順」で入れられます
174+ */
175+ bool searchValidPolygon(world_point2d wpoint, int heightMin, int heightMax,
176+ int poinIndexes[]. int lineIndexes[]);
177+
178+ /**
160179 二つの線が織り成す角度を求めます
161180 @param pIndexA1,2 線分A1-A2の点インデックス
162181 @param pIndexB1,2 線分B1-B2の点インデックス
--- marathon/trunk/HPLLib/HPLMath.cpp (revision 290)
+++ marathon/trunk/HPLLib/HPLMath.cpp (revision 291)
@@ -3,40 +3,12 @@
33 #include <cmath>
44
55 static double PI = 3.1415926;
6+const int ROUND_DEGREE = 360;
67
7-/////////////////////////////////////////////////////////////////////////////
8-//////////// Static Methods (Private / Inner Methods) /////////////////////
9-//////////// Prototypes ///////////////////////////////////////////////////
10-/////////////////////////////////////////////////////////////////////////////
118 /**
12- 点から線分への距離(垂線の長さ)を求めます
13- <en>get
9+ 点(px,py)から線(lx0,ly0)-(lx1,ly1)への垂線の距離を求める
1410 */
15-static double getPointDistanceFromLine(double px, double py,
16- double lx0, double ly0, double lx1, double ly1);
17-
18-/**
19- <jp>三平方の定理で長さを求める
20- <en>get length of (0,0)-(x,y)
21-*/
22-static double getLength(double x, double y);
23-
24-/**
25- <jp>内積を求めます
26-*/
27-static double getInnerProduct(double x0, double y0, double x1, double y1);
28-
29-/**
30- 点から降ろした垂線が線分と交差するか判断
31-*/
32-static bool isCrossPointLine(double px, double py,
33- double lx0, double ly0, double lx1, double ly1);
34-
35-
36-/////////////////////////////////////////////////////////////////////////////
37-////////////// Static Methods /////////////////////////////////////////////
38-/////////////////////////////////////////////////////////////////////////////
39-double getPointDistanceFromLine(double px, double py,
11+double hpl::math::getPointDistanceFromLine(double px, double py,
4012 double lx0, double ly0, double lx1, double ly1)
4113 {
4214 //start->end
@@ -80,22 +52,24 @@
8052 double distance = ((double)pointvectorDistance * sqrt(1 - costheta * costheta));
8153 return distance;
8254 }
83-static double getLength(double x, double y)
55+double hpl::math::getLength(double x, double y)
8456 {
8557 double length = (double)sqrt((double)(x * x + y * y));
8658 return length;
8759 }
8860
89-static double getInnerProduct(double x0, double y0, double x1, double y1)
61+double hpl::math::getInnerProduct(double x0, double y0, double x1, double y1)
9062 {
9163 double num = x0 * x1 + y0 * y1;
9264 return num;
9365 }
9466
95-static bool isCrossPointLine(double px, double py,
67+/**線と点の近さの閾値*/
68+const double EPSILON = 0.01;
69+
70+bool hpl::math::isCrossPointLine(double px, double py,
9671 double lx0, double ly0, double lx1, double ly1)
9772 {
98- const double EPSILON = 0.00001;
9973 double lineDeltaX = lx1 - lx0;
10074 double lineDeltaY = ly1 - ly0;
10175
@@ -354,3 +328,172 @@
354328 double optRad = hpl::math::getRadianFromDegree(optDeg);
355329 return optRad;
356330 }
331+
332+/////////////////////////////////////////////////////
333+///////////// cross ///////////////////////////////
334+/**
335+ 2つの線分が交差した点を取得します。
336+ @return 2つの線分が交差していない場合偽
337+*/
338+bool hpl::math::getCrossPointOfTwoLines(double line0[2][2],
339+ double line1[2][2], double dest[2])
340+{
341+ //それぞれの線の傾きと切片
342+ double degree[2] = {0,0};
343+ double slice[2] = {0,0};
344+
345+ int lineType0 = hpl::math::getLineAngleAndSlice(line0, &degree[0], &slice[0]);
346+ int lineType1 = hpl::math::getLineAngleAndSlice(line1, &degree[1], &slice[1]);
347+
348+ //平行線
349+ if(degree[0] == degree[1]){
350+ return false;
351+ }
352+ if(lineType0 == hpl::math::LineType::Normal){
353+ if(lineType1 == hpl::math::LineType::Normal){
354+ //傾き
355+ //y=a0x+b0
356+ //y=a1x+b1
357+ //x=(b1-b0)/(a1-a0)
358+ double angle[2];
359+ for(int i = 0; i < 2; i ++){
360+ angle[i] = hpl::math::getAngleFromDegree(degree[i]);
361+ }
362+ dest[0] = (slice[1] - slice[0]) / (angle[1] - angle[0]);
363+ dest[1] = dest[0] * angle[0] + slice[0];
364+ }else if(lineType1 == hpl::math::LineType::Vertical){
365+ //垂直
366+ //交点はx=line1[0][0]のもの
367+ //y=ax+b
368+ //傾き
369+ double angle0 = hpl::math::getAngleFromDegree(degree[0]);
370+ dest[0] = line1[0][0];
371+ dest[1] = angle0 * dest[0] + slice[0];
372+ }else{
373+ //水平
374+ //交点はy=line1[0][1]のもの
375+ //x=(y-b)/a
376+ double angle0 = hpl::math::getAngleFromDegree(degree[0]);
377+ dest[1] = line1[0][1];
378+ dest[0] = (dest[1] - slice[0]) / angle0;
379+ }
380+ }else if(lineType0 == hpl::math::LineType::Horizontal){
381+ if(lineType1 == hpl::math::LineType::Normal){
382+ //交点はy=line0[0][1]
383+ //x=(y-b)/a
384+ double angle1 = hpl::math::getAngleFromDegree(degree[1]);
385+ dest[1] = line0[0][1];
386+ dest[0] = (dest[1] - slice[1]) / angle1;
387+ }else if(lineType1 == hpl::math::LineType::Vertical){
388+ //水平線0 AND 垂直線1
389+ //交点はx=line1[0][0], y=line0[0][1]
390+ dest[0] = line1[0][0];
391+ dest[1] = line0[0][1];
392+ }else{
393+ //水平線*水平線
394+ return false;
395+ }
396+ }else{
397+ //垂直線0
398+ if(lineType1 == hpl::math::LineType::Normal){
399+ //交点はx=line0[0][0]
400+ //y=ax+b
401+ double angle1 = hpl::math::getAngleFromDegree(degree[1]);
402+ dest[0] = line0[0][0];
403+ dest[1] = angle1 * dest[0] + slice[1];
404+ }else if(lineType1 == hpl::math::LineType::Vertical){
405+ //垂直線0 AND 垂直線1
406+ return false;
407+ }else{
408+ //垂直線0*水平線1
409+ //交点はx=line0[0][0], y=line1[0][1]
410+ dest[0] = line0[0][0];
411+ dest[1] = line1[0][1];
412+ }
413+ }
414+
415+
416+ //範囲チェック
417+ if(!hpl::math::isPointInRect<double>(dest[0], dest[1],
418+ line0[0][0], line0[0][1], line0[1][0], line0[1][1]))
419+ {
420+ return false;
421+ }
422+ if(!hpl::math::isPointInRect<double>(dest[0], dest[1],
423+ line1[0][0], line1[0][1], line1[1][0], line1[1][1]))
424+ {
425+ return false;
426+ }
427+
428+ return true;
429+}
430+
431+/**
432+ 線分の端点データから、その線の傾きと切片を求めます
433+ 水平線か垂直な線の場合は傾きが反対の軸
434+ @param line line datas ([0][0],[0][1])-([1][0],[1][1])
435+ @param
436+ @return LineType
437+*/
438+int getLineAngleAndSlice(double line[2][2], double *degree, double *slice)
439+{
440+ double lineDeltaX = line[1][0] - line[0][0];
441+ double lineDeltaY = line[1][1] - line[0][1];
442+
443+ //線が垂直、水平
444+ if((int)lineDeltaX == 0){
445+ //垂直 x0==x1
446+
447+ if(lineDeltaY > 0){
448+ //下向き
449+ *degree = ROUND_DEGREE / 4.0;
450+ }else{
451+ //上向き
452+ *degree = ROUND_DEGREE / 4.0 * 3.0;
453+ }
454+ return hpl::math::LineType::Vertical;
455+ }
456+ if((int)lineDeltaY == 0){
457+ //水平 y0==y1
458+ if(lineDeltaX > 0){
459+ //右向き
460+ *degree = 0;
461+ }else{
462+ //左向き
463+ *degree = ROUND_DEGREE / 2.0;
464+ }
465+ return hpl::math::LineType::Horizontal;
466+ }
467+
468+ //傾き
469+ double angle = lineDeltaY / lineDeltaX;
470+ *degree = hpl::math::getDegreeFromVector(lineDeltaX, lineDeltaY);
471+
472+ //切片(x=0)
473+ //y0=ax0+b (1)
474+ //y1=ax1+b (2)
475+ //bで代入
476+ //a=(y2-y1)/(x2-x1)
477+ //(1)に代入
478+ //b=y0-ax0
479+ *slice = line[0][1] - lineDeltaY / lineDeltaX * line[0][0];
480+
481+ return hpl::math::LineType::Normal;
482+}
483+
484+/**
485+ 線の傾きを角度から得ます
486+*/
487+double hpl::math::getAngleFromDegree(double degree)
488+{
489+ //ラジアンにします
490+ double rad = hpl::math::getRadianFromDegree(degree);
491+ double cs = cos(rad);
492+ if(cs == 0){
493+ //X軸移動量が0(垂直)ならば
494+ //0.000001くらいにする
495+ cs = 0.0000001;
496+ }
497+ double angle = sin(rad) / cs;
498+ return angle;
499+}
旧リポジトリブラウザで表示