Model2D.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. #include "Model2D.h"
  2. #include "Bild.h"
  3. #include "FrameworkMath.h"
  4. #include "Mat3.h"
  5. #ifdef WIN32
  6. #include "MausEreignis.h"
  7. #endif
  8. using namespace Framework;
  9. // Inhalt der Model2DData Klasse aus Model2D.h
  10. // Konstruktor
  11. Model2DData::Model2DData()
  12. : polygons( 0 ),
  13. vListen( 0 ),
  14. minP( 0, 0 ),
  15. maxP( 0, 0 )
  16. {
  17. ref = 1;
  18. }
  19. // Destruktor
  20. Model2DData::~Model2DData()
  21. {
  22. if( polygons )
  23. {
  24. int anz = polygons->getEintragAnzahl();
  25. for( int i = 0; i < anz; i++ )
  26. {
  27. #ifdef WIN32
  28. if( polygons->get( i ).tKordinaten )
  29. polygons->get( i ).tKordinaten->release();
  30. #endif
  31. if( polygons->get( i ).vertex )
  32. polygons->get( i ).vertex->release();
  33. }
  34. polygons = polygons->release();
  35. }
  36. if( vListen )
  37. vListen->release();
  38. }
  39. // privat
  40. bool Model2DData::istPunktInnen( Vertex p, int polygonId ) const
  41. {
  42. if( p < minP || p > maxP || !polygons )
  43. return 0;
  44. int num = 0;
  45. for( auto *polygon = &polygons->getArray(); polygon && polygon->set; polygon = polygon->next, num++ )
  46. {
  47. if( polygonId >= 0 && num != polygonId )
  48. continue;
  49. int anz = polygon->var.vertex->getEintragAnzahl();
  50. int ola = outList.z( num )->getEintragAnzahl();
  51. bool c = 0;
  52. int j = anz - 1;
  53. for( int k = 0; k < ola; k++ )
  54. {
  55. Punkt out = outList.z( num )->get( k );
  56. if( out.x < out.y && j > out.x && j < out.y )
  57. j = out.x;
  58. if( out.x > out.y && ( j > out.x || j < out.y ) )
  59. j = out.x;
  60. }
  61. for( int i = 0; i < anz; i++ )
  62. {
  63. bool cont = 0;
  64. for( int k = 0; k < ola; k++ )
  65. {
  66. Punkt out = outList.z( num )->get( k );
  67. if( out.x < out.y && i > out.x && i < out.y )
  68. cont = 1;
  69. if( out.x > out.y && ( i > out.x || i < out.y ) )
  70. cont = 1;
  71. }
  72. if( cont )
  73. continue;
  74. Vertex a = polygon->var.vertex->get( i );
  75. Vertex b = polygon->var.vertex->get( j );
  76. if( ( ( a.y >= p.y ) != ( b.y >= p.y ) ) && ( p.x <= ( b.x - a.x ) * ( p.y - a.y ) / (float)( b.y - a.y ) + a.x ) )
  77. c = !c;
  78. j = i;
  79. }
  80. if( c )
  81. return 1;
  82. }
  83. return 0;
  84. }
  85. bool Model2DData::istLinieInnen( Vertex a, Vertex b, int polygonId ) const
  86. {
  87. if( !polygons )
  88. return 0;
  89. int pAnz = polygons->getEintragAnzahl();
  90. for( int p = 0; p < pAnz; p++ )
  91. {
  92. if( polygonId >= 0 && p != polygonId )
  93. continue;
  94. int ola = outList.z( p )->getEintragAnzahl();
  95. int anz = polygons->get( p ).vertex->getEintragAnzahl();
  96. int j = anz - 1;
  97. for( int k = 0; k < ola; k++ )
  98. {
  99. Punkt out = outList.z( p )->get( k );
  100. if( out.x < out.y && j > out.x && j < out.y )
  101. j = out.x;
  102. if( out.x > out.y && ( j > out.x || j < out.y ) )
  103. j = out.x;
  104. }
  105. for( int i = 0; i < anz; i++ )
  106. {
  107. bool cont = 0;
  108. for( int k = 0; k < ola; k++ )
  109. {
  110. Punkt out = outList.z( p )->get( k );
  111. if( out.x < out.y && i > out.x && i < out.y )
  112. cont = 1;
  113. if( out.x > out.y && ( i > out.x || i < out.y ) )
  114. cont = 1;
  115. }
  116. if( cont )
  117. continue;
  118. Punkt va = polygons->get( p ).vertex->get( i );
  119. Punkt vb = polygons->get( p ).vertex->get( j );
  120. if( (Punkt)a == va && (Punkt)b == vb )
  121. return 1;
  122. if( (Punkt)a == vb && (Punkt)b == va )
  123. return 1;
  124. j = i;
  125. }
  126. Vertex län = b - a;
  127. Vertex speed( län.x > 0 ? 1 : -1.f, län.y > 0 ? 1 : -1.f );
  128. int mLän = 0;
  129. if( fabs( län.x ) > fabs( län.y ) )
  130. {
  131. mLän = (int)fabs( län.x );
  132. speed.y = län.y / (float)fabs( län.x );
  133. }
  134. else
  135. {
  136. mLän = (int)fabs( län.y );
  137. speed.x = län.x / (float)fabs( län.y );
  138. }
  139. int i = 1;
  140. bool inside = 1;
  141. for( Vertex vp = speed + a; (Punkt)vp != (Punkt)( b - speed ) && inside && i < mLän - 1; vp += speed, i++ )
  142. inside &= istPunktInnen( vp, p );
  143. if( inside )
  144. return 1;
  145. }
  146. return 0;
  147. }
  148. // nicht constant
  149. bool Model2DData::erstelleModell( Array< Polygon2D > *polygons )
  150. {
  151. löscheModell();
  152. if( !polygons || !polygons->getEintragAnzahl() )
  153. {
  154. this->polygons = polygons;
  155. vListen = new RCArray< RCArray< DreieckListe< Vertex > > >();
  156. return 1;
  157. }
  158. this->polygons = polygons;
  159. int pAnz = polygons->getEintragAnzahl();
  160. vListen = new RCArray< RCArray< DreieckListe< Vertex > > >();
  161. for( int p = 0; p < pAnz; p++ )
  162. {
  163. Polygon2D pg = polygons->get( p );
  164. if( !pg.vertex || pg.vertex->getEintragAnzahl() < 3 )
  165. continue;
  166. vListen->add( new RCArray< DreieckListe< Vertex > >() );
  167. outList.set( new Array< Punkt >, p );
  168. int vAnz = pg.vertex->getEintragAnzahl();
  169. bool textur = pg.tKordinaten != 0;
  170. for( int i = 0; i < vAnz && textur; i++ )
  171. textur &= pg.tKordinaten->hat( i );
  172. for( int i = 0; i < vAnz; i++ )
  173. {
  174. if( maxP.x < fabs( pg.vertex->get( i ).x ) )
  175. maxP.x = abs( (int)pg.vertex->get( i ).x ) + 1;
  176. if( maxP.y < fabs( pg.vertex->get( i ).y ) )
  177. maxP.y = abs( (int)pg.vertex->get( i ).y ) + 1;
  178. }
  179. minP = -maxP;
  180. if( !textur )
  181. {
  182. if( pg.tKordinaten )
  183. pg.tKordinaten->leeren();
  184. }
  185. RCArray< RCArray< DreieckListe< Vertex > > > lists;
  186. int lauf = 0;
  187. while( 1 )
  188. {
  189. lists.set( new RCArray< DreieckListe< Vertex > >(), lauf );
  190. outList.z( p )->set( Punkt( 0, 0 ), lauf );
  191. bool fertig = 0;
  192. Vertex a;
  193. Vertex b;
  194. Array< Punkt > tmpOutList;
  195. for( int i = 0; i < vAnz; i++ )
  196. {
  197. bool cont = 0;
  198. int vorher = i - 1;
  199. int nachher = i + 1;
  200. if( nachher >= vAnz )
  201. nachher = 0;
  202. if( vorher < 0 )
  203. vorher = vAnz - 1;
  204. int ola = outList.z( p )->getEintragAnzahl();
  205. for( int j = 0; j < ola; j++ )
  206. {
  207. Punkt out = outList.z( p )->get( j );
  208. if( out.x < out.y )
  209. {
  210. if( nachher > out.x && nachher < out.y )
  211. nachher = out.y;
  212. if( vorher > out.x && vorher < out.y )
  213. vorher = out.x;
  214. }
  215. if( out.x > out.y )
  216. {
  217. if( nachher > out.x || nachher < out.y )
  218. nachher = out.y;
  219. if( vorher > out.x || vorher < out.y )
  220. vorher = out.x;
  221. }
  222. if( out.x < out.y && i > out.x && i < out.y )
  223. cont = 1;
  224. if( out.x > out.y && ( i > out.x || i < out.y ) )
  225. cont = 1;
  226. }
  227. if( cont )
  228. continue;
  229. if( vorher < 0 )
  230. a = pg.vertex->get( vAnz + vorher );
  231. else
  232. a = pg.vertex->get( vorher );
  233. if( nachher > vAnz - 1 )
  234. b = pg.vertex->get( nachher - vAnz + 1 );
  235. else
  236. b = pg.vertex->get( nachher );
  237. if( istLinieInnen( a, b, p ) )
  238. {
  239. DreieckListe< Vertex > *lowL = new DreieckListe< Vertex >();
  240. DreieckListe< Vertex > *hightL = new DreieckListe< Vertex >();
  241. lowL->addPunkt( new Vertex( pg.vertex->get( i ) ), textur ? new Punkt( pg.tKordinaten->get( i ) ) : 0 );
  242. hightL->addPunkt( new Vertex( pg.vertex->get( i ) ), textur ? new Punkt( pg.tKordinaten->get( i ) ) : 0 );
  243. int hight = i + 1;
  244. int low = i - 1;
  245. Punkt outL( 0, 0 );
  246. Punkt outH( 0, 0 );
  247. for( int k = 0; k < 2; k++ )
  248. {
  249. bool lowp = !k;
  250. while( 1 )
  251. {
  252. if( hight >= vAnz )
  253. hight = 0;
  254. if( low < 0 )
  255. low = vAnz - 1;
  256. for( int j = 0; j <= lauf; j++ )
  257. {
  258. Punkt out = outList.z( p )->get( j );
  259. if( out.x < out.y )
  260. {
  261. if( hight > out.x && hight < out.y )
  262. hight = out.y;
  263. if( low > out.x && low < out.y )
  264. low = out.x;
  265. }
  266. if( out.x > out.y )
  267. {
  268. if( hight > out.x || hight < out.y )
  269. hight = out.y;
  270. if( low > out.x || low < out.y )
  271. low = out.x;
  272. }
  273. }
  274. Vertex a = pg.vertex->get( hight );
  275. Vertex b = pg.vertex->get( low );
  276. if( low == hight )
  277. {
  278. fertig = 1;
  279. outList.z( p )->set( Punkt( 0, 0 ), lauf );
  280. if( !k )
  281. lowL->addPunkt( new Vertex( b ), textur ? new Punkt( pg.tKordinaten->get( low ) ) : 0 );
  282. else
  283. hightL->addPunkt( new Vertex( b ), textur ? new Punkt( pg.tKordinaten->get( low ) ) : 0 );
  284. break;
  285. }
  286. bool inside = istLinieInnen( a, b, p );
  287. if( inside )
  288. {
  289. if( !k )
  290. outL = Punkt( low, hight );
  291. else
  292. outH = Punkt( low, hight );
  293. outList.z( p )->set( Punkt( low, hight ), lauf );
  294. }
  295. if( lowp )
  296. {
  297. if( !k )
  298. lowL->addPunkt( new Vertex( b ), textur ? new Punkt( pg.tKordinaten->get( low ) ) : 0 );
  299. else
  300. hightL->addPunkt( new Vertex( b ), textur ? new Punkt( pg.tKordinaten->get( low ) ) : 0 );
  301. low--;
  302. }
  303. else
  304. {
  305. if( !k )
  306. lowL->addPunkt( new Vertex( a ), textur ? new Punkt( pg.tKordinaten->get( hight ) ) : 0 );
  307. else
  308. hightL->addPunkt( new Vertex( a ), textur ? new Punkt( pg.tKordinaten->get( hight ) ) : 0 );
  309. hight++;
  310. }
  311. lowp = !lowp;
  312. if( !inside )
  313. {
  314. hight = i + 1;
  315. low = i - 1;
  316. outList.z( p )->set( Punkt( 0, 0 ), lauf );
  317. break;
  318. }
  319. }
  320. if( fertig )
  321. break;
  322. }
  323. if( lowL->getDreieckAnzahl() > hightL->getDreieckAnzahl() )
  324. {
  325. lists.z( lauf )->set( lowL, i );
  326. tmpOutList.set( outL, i );
  327. hightL->release();
  328. }
  329. else
  330. {
  331. lists.z( lauf )->set( hightL, i );
  332. tmpOutList.set( outH, i );
  333. lowL->release();
  334. }
  335. }
  336. else
  337. lists.z( lauf )->set( new DreieckListe< Vertex >(), i );
  338. if( fertig )
  339. break;
  340. }
  341. int maxP = -1;
  342. int max = 0;
  343. for( int i = 0; i < vAnz; i++ )
  344. {
  345. if( lists.z( lauf )->z( i ) && lists.z( lauf )->z( i )->getDreieckAnzahl() > max )
  346. {
  347. max = lists.z( lauf )->z( i )->getDreieckAnzahl();
  348. maxP = i;
  349. }
  350. }
  351. if( !max || maxP < 0 )
  352. break;
  353. vListen->z( p )->add( lists.z( lauf )->get( maxP ) );
  354. outList.z( p )->set( tmpOutList.get( maxP ), lauf );
  355. if( fertig )
  356. break;
  357. lauf++;
  358. }
  359. outList.z( p )->leeren();
  360. }
  361. return 1;
  362. }
  363. void Model2DData::löscheModell() // setzt die Vertex daten zurück
  364. {
  365. if( polygons )
  366. {
  367. int anz = polygons->getEintragAnzahl();
  368. for( int i = 0; i < anz; i++ )
  369. {
  370. if( polygons->get( i ).tKordinaten )
  371. polygons->get( i ).tKordinaten->release();
  372. if( polygons->get( i ).vertex )
  373. polygons->get( i ).vertex->release();
  374. }
  375. polygons = polygons->release();
  376. }
  377. if( vListen )
  378. vListen = vListen->release();
  379. outList.leeren();
  380. minP = Punkt( 0, 0 );
  381. maxP = Punkt( 0, 0 );
  382. }
  383. // Reference Counting
  384. Model2DData *Model2DData::getThis()
  385. {
  386. ref++;
  387. return this;
  388. }
  389. Model2DData *Model2DData::release()
  390. {
  391. ref--;
  392. if( !ref )
  393. delete this;
  394. return 0;
  395. }
  396. // Inhalt der Model2D Klasse aus Model2D.h
  397. // Konstruktor
  398. Model2D::Model2D()
  399. #ifdef WIN32
  400. : Zeichnung(),
  401. textur( 0 )
  402. #endif
  403. {
  404. #ifdef WIN32
  405. farbe = 0;
  406. style = 0;
  407. #else
  408. pos = Punkt( 0, 0 );
  409. #endif
  410. rData = 0;
  411. drehung = 0;
  412. größe = 1;
  413. ref = 1;
  414. }
  415. // Destruktor
  416. Model2D::~Model2D()
  417. {
  418. if( rData )
  419. rData->release();
  420. #ifdef WIN32
  421. if( textur )
  422. textur->release();
  423. #endif
  424. }
  425. // nicht constant
  426. void Model2D::setModel( Model2DData *mdl )
  427. {
  428. if( rData )
  429. rData->release();
  430. rData = mdl;
  431. }
  432. void Model2D::setDrehung( float drehung )
  433. {
  434. this->drehung = drehung;
  435. while( this->drehung > PI * 2 )
  436. this->drehung -= (float)PI * 2;
  437. while( this->drehung < 0 )
  438. this->drehung += (float)PI * 2;
  439. #ifdef WIN32
  440. rend = 1;
  441. #endif
  442. }
  443. void Model2D::addDrehung( float drehung )
  444. {
  445. this->drehung += drehung;
  446. while( this->drehung > PI * 2 )
  447. this->drehung -= (float)PI * 2;
  448. while( this->drehung < 0 )
  449. this->drehung += (float)PI * 2;
  450. #ifdef WIN32
  451. rend = 1;
  452. #endif
  453. }
  454. void Model2D::setGröße( float größe )
  455. {
  456. this->größe = größe;
  457. #ifdef WIN32
  458. rend = 1;
  459. #endif
  460. }
  461. void Model2D::addGröße( float größe )
  462. {
  463. this->größe += größe;
  464. #ifdef WIN32
  465. rend = 1;
  466. #endif
  467. }
  468. #ifdef WIN32
  469. void Model2D::setTextur( Bild *t )
  470. {
  471. if( textur )
  472. textur->release();
  473. textur = t;
  474. }
  475. void Model2D::setFarbe( int f )
  476. {
  477. farbe = f;
  478. rend = 1;
  479. }
  480. void Model2D::doMausEreignis( MausEreignis &me )
  481. {
  482. if( !Mak || me.verarbeitet || !istPunktInnen( Punkt( me.mx, me.my ) ) )
  483. return;
  484. me.mx -= pos.x;
  485. me.my -= pos.y;
  486. Mak( makParam, this, me );
  487. me.mx += pos.x;
  488. me.my += pos.y;
  489. me.verarbeitet = 1;
  490. }
  491. bool Model2D::tick( double tickVal )
  492. {
  493. bool ret = rend;
  494. rend = 0;
  495. return ret;
  496. }
  497. void Model2D::render( Bild &zRObj )
  498. {
  499. if( !rData || hatStyleNicht( Model2D::Style::Sichtbar ) || !rData->polygons )
  500. return;
  501. __super::render( zRObj );
  502. int num = 0;
  503. for( auto *p = &rData->vListen->getArray(); p && p->set; p = p->next, num++ )
  504. {
  505. Mat3< float > mat = Mat3< float >::translation( pos ) * Mat3< float >::rotation( drehung ) * Mat3< float >::scaling( größe );
  506. if( hatStyle( Model2D::Style::Textur ) )
  507. {
  508. if( !textur || !rData->polygons->get( num ).tKordinaten )
  509. {
  510. for( auto *i = &p->var->getArray(); i && i->set; i = i->next )
  511. {
  512. for( auto *j = &i->var->zListe()->getArray(); j->next->next && j->next->next->set; j = j->next )
  513. {
  514. Vertex a = mat * *j->var->punkt;
  515. Vertex b = mat * *j->next->var->punkt;
  516. Vertex c = mat * *j->next->next->var->punkt;
  517. if( hatStyle( Model2D::Style::Alpha ) )
  518. zRObj.drawDreieckAlpha( a, b, c, farbe );
  519. else
  520. zRObj.drawDreieck( a, b, c, farbe );
  521. }
  522. }
  523. }
  524. else
  525. {
  526. for( auto *i = &p->var->getArray(); i && i->set; i = i->next )
  527. {
  528. for( auto *j = &i->var->zListe()->getArray(); j->next->next && j->next->next->set; j = j->next )
  529. {
  530. Vertex a = mat * *j->var->punkt;
  531. Vertex b = mat * *j->next->var->punkt;
  532. Vertex c = mat * *j->next->next->var->punkt;
  533. if( hatStyle( Model2D::Style::Alpha ) )
  534. zRObj.drawDreieckTexturAlpha( a, b, c, *j->var->textur, *j->next->var->textur, *j->next->next->var->textur, *textur );
  535. else
  536. zRObj.drawDreieckTextur( a, b, c, *j->var->textur, *j->next->var->textur, *j->next->next->var->textur, *textur );
  537. }
  538. }
  539. }
  540. }
  541. if( hatStyle( Model2D::Style::Mesh ) )
  542. {
  543. for( auto *i = &p->var->getArray(); i && i->set; i = i->next )
  544. {
  545. for( auto *j = &i->var->zListe()->getArray(); j->next->next && j->next->next->set; j = j->next )
  546. {
  547. Vertex a = mat * *j->var->punkt;
  548. Vertex b = mat * *j->next->var->punkt;
  549. Vertex c = mat * *j->next->next->var->punkt;
  550. if( hatStyle( Model2D::Style::Alpha ) )
  551. {
  552. zRObj.drawLinieAlpha( a, b, farbe );
  553. zRObj.drawLinieAlpha( b, c, farbe );
  554. zRObj.drawLinieAlpha( c, a, farbe );
  555. }
  556. else
  557. {
  558. zRObj.drawLinie( a, b, farbe );
  559. zRObj.drawLinie( b, c, farbe );
  560. zRObj.drawLinie( c, a, farbe );
  561. }
  562. }
  563. }
  564. }
  565. if( hatStyle( Model2D::Style::Rahmen ) )
  566. {
  567. ArrayEintrag< Vertex > &beg = rData->polygons->get( num ).vertex->getArray();
  568. if( beg.set )
  569. {
  570. ArrayEintrag< Vertex > *letzter = 0;
  571. for( ArrayEintrag< Vertex > *e = &beg; e && e->next && e->set && e->next->set; e = e->next )
  572. {
  573. if( hatStyle( Model2D::Style::Alpha ) )
  574. zRObj.drawLinieAlpha( mat * e->var, mat * e->next->var, farbe );
  575. else
  576. zRObj.drawLinie( mat * e->var, mat * e->next->var, farbe );
  577. letzter = e->next;
  578. }
  579. if( letzter && letzter->set )
  580. {
  581. if( hatStyle( Model2D::Style::Alpha ) )
  582. zRObj.drawLinieAlpha( mat * letzter->var, mat * beg.var, farbe );
  583. else
  584. zRObj.drawLinie( mat * letzter->var, mat * beg.var, farbe );
  585. }
  586. }
  587. }
  588. }
  589. }
  590. #else
  591. void Model2D::setPosition( Punkt p )
  592. {
  593. pos = p;
  594. }
  595. #endif
  596. // constant
  597. float Model2D::getDrehung() const
  598. {
  599. return drehung;
  600. }
  601. float Model2D::getGröße() const
  602. {
  603. return größe;
  604. }
  605. bool Model2D::istPunktInnen( Vertex p ) const
  606. {
  607. if( !rData )
  608. return 0;
  609. p -= pos;
  610. if( p < Mat3< float >::scaling( größe ) * rData->minP || p > Mat3< float >::scaling( größe ) * rData->maxP || !rData->polygons )
  611. return 0;
  612. int num = 0;
  613. for( auto *polygon = &rData->polygons->getArray(); polygon && polygon->set; polygon = polygon->next, num++ )
  614. {
  615. Mat3< float > mat = Mat3< float >::rotation( drehung ) * Mat3< float >::scaling( größe );
  616. int anz = polygon->var.vertex->getEintragAnzahl();
  617. bool c = 0;
  618. int j = anz - 1;
  619. for( int i = 0; i < anz; i++ )
  620. {
  621. Vertex a = mat * polygon->var.vertex->get( i );
  622. Vertex b = mat * polygon->var.vertex->get( j );
  623. if( ( ( a.y >= p.y ) != ( b.y >= p.y ) ) && ( p.x <= ( b.x - a.x ) * ( p.y - a.y ) / (float)( b.y - a.y ) + a.x ) )
  624. c = !c;
  625. j = i;
  626. }
  627. if( c )
  628. return 1;
  629. }
  630. return 0;
  631. }
  632. bool Model2D::istLinieInnen( Vertex a, Vertex b ) const
  633. {
  634. if( !rData || !rData->polygons )
  635. return 0;
  636. int pAnz = rData->polygons->getEintragAnzahl();
  637. for( int p = 0; p < pAnz; p++ )
  638. {
  639. Mat3< float > mat = Mat3< float >::rotation( drehung ) * Mat3< float >::scaling( größe );
  640. int anz = rData->polygons->get( p ).vertex->getEintragAnzahl();
  641. int j = anz - 1;
  642. for( int i = 0; i < anz; i++ )
  643. {
  644. Punkt va = mat * rData->polygons->get( p ).vertex->get( i );
  645. Punkt vb = mat * rData->polygons->get( p ).vertex->get( j );
  646. if( (Punkt)a == pos + va && (Punkt)b == pos + vb )
  647. return 1;
  648. if( (Punkt)a == pos + vb && (Punkt)b == pos + va )
  649. return 1;
  650. j = i;
  651. }
  652. Vertex län = b - a;
  653. Vertex speed( län.x > 0 ? 1 : -1.f, län.y > 0 ? 1 : -1.f );
  654. int mLän = 0;
  655. if( fabs( län.x ) > fabs( län.y ) )
  656. {
  657. mLän = (int)fabs( län.x );
  658. speed.y = län.y / (float)fabs( län.x );
  659. }
  660. else
  661. {
  662. mLän = (int)fabs( län.y );
  663. speed.x = län.x / (float)fabs( län.y );
  664. }
  665. int i = 1;
  666. bool inside = 1;
  667. for( Vertex vp = speed + a; (Punkt)vp != (Punkt)( b - speed ) && inside && i < mLän - 1; vp += speed, i++ )
  668. inside &= istPunktInnen( vp );
  669. if( inside )
  670. return 1;
  671. }
  672. return 0;
  673. }
  674. bool Model2D::istModelInnen( const Model2D *zMdl, bool end ) const
  675. {
  676. if( !end )
  677. {
  678. Vertex min = (Vertex)rData->minP * größe + pos;
  679. Vertex max = (Vertex)rData->maxP * größe + pos;
  680. Vertex min2 = (Vertex)zMdl->zModel()->minP * zMdl->getGröße() + zMdl->getPosition();
  681. Vertex max2 = (Vertex)zMdl->zModel()->maxP * zMdl->getGröße() + zMdl->getPosition();
  682. if( max.x < min2.x || min.x > max2.x || max.y < min2.y || min.y > max2.y )
  683. return 0;
  684. }
  685. Mat3< float > mat = Mat3< float >::translation( pos ) * Mat3< float >::rotation( drehung ) * Mat3< float >::scaling( größe );
  686. for( auto *polygon = &rData->polygons->getArray(); polygon && polygon->set; polygon = polygon->next )
  687. {
  688. int anz = polygon->var.vertex->getEintragAnzahl();
  689. for( int i = 0; i < anz; i++ )
  690. {
  691. if( zMdl->istPunktInnen( mat * polygon->var.vertex->get( i ) ) )
  692. return 1;
  693. }
  694. }
  695. if( end )
  696. return 0;
  697. return zMdl->istModelInnen( this, 1 );
  698. }
  699. Model2DData *Model2D::getModel() const
  700. {
  701. return rData ? rData->getThis() : 0;
  702. }
  703. Model2DData *Model2D::zModel() const
  704. {
  705. return rData;
  706. }
  707. #ifndef WIN32
  708. Punkt Model2D::getPosition() const
  709. {
  710. return pos;
  711. }
  712. #endif
  713. // Reference Counting
  714. Model2D *Model2D::getThis()
  715. {
  716. ++ref;
  717. return this;
  718. }
  719. Model2D *Model2D::release()
  720. {
  721. --ref;
  722. if( !ref )
  723. delete this;
  724. return 0;
  725. }