00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include "camtypes.h"
00104 #include "moldpers.h"
00105
00106
00107
00108
00109
00110 #include "blobs.h"
00111
00112 #include "moldedit.h"
00113
00114
00115 #include <math.h>
00116
00117 DECLARE_SOURCE("$Revision: 1282 $");
00118
00119 CC_IMPLEMENT_MEMDUMP(GPerspective, GMould)
00120 CC_IMPLEMENT_DYNAMIC(MouldPerspective, MouldGeometry)
00121 CC_IMPLEMENT_DYNCREATE(RecordPerspectiveAction,Action)
00122
00123
00124 #define new CAM_DEBUG_NEW
00125 #define EPSILON 1e-10
00126 #define equal(a,b) ( fabs( (a) - (b) ) <= (EPSILON) )
00127 #define notequal(a,b) ( fabs( (a) - (b) ) > (EPSILON) )
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 MouldPerspective::MouldPerspective()
00145 {
00146 GridState = 0;
00147
00148
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 MouldPerspective::~MouldPerspective()
00165 {
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 BOOL MouldPerspective::Validate(Path* const pPath, UINT32& errorID)
00186 {
00187
00188 INT32 numc=pPath->GetNumCoords();
00189 if ((numc!=PER_NUMCOORDS+1))
00190 {
00191 errorID = _R(IDE_PERS_NUMCOORDERR);
00192 return FALSE;
00193 }
00194
00195
00196 DocCoord* Coords = pPath->GetCoordArray();
00197 PathVerb* Verbs = pPath->GetVerbArray();
00198
00199
00200 if (Verbs[0]!=PT_MOVETO)
00201 {
00202 errorID = _R(IDE_PERS_BADELEMENT);
00203 return FALSE;
00204 }
00205
00206
00207 if (Coords[0]!=Coords[numc-1])
00208 {
00209 errorID = _R(IDE_PERS_NOTCLOSED);
00210 return FALSE;
00211 }
00212
00213 INT32 i,j;
00214
00215 for (i=1; i<numc; i++)
00216 {
00217 if ( (Verbs[i] & (~PT_CLOSEFIGURE))!=PT_LINETO )
00218 {
00219 errorID = _R(IDE_PERS_NOTALLLINES);
00220 return FALSE;
00221 }
00222 }
00223
00224
00225 for (i=1; i<numc; i++)
00226 {
00227 for (j=i+1; j<numc; j++)
00228 {
00229 if (Coords[i] == Coords[j])
00230 {
00231 errorID = _R(IDE_PERS_COINCIDENT);
00232 return FALSE;
00233 }
00234 }
00235 }
00236
00237
00238 POINT* p = (POINT*)(Coords);
00239 if (!WillBeValid(p))
00240 {
00241 errorID = _R(IDE_PERS_CROSSING);
00242 return FALSE;
00243 }
00244
00245
00246 return TRUE;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 BOOL MouldPerspective::WillBeValid(POINT* P)
00264 {
00265 INT32 MinX, MaxX, MinY, MaxY, Width, Depth ;
00266 DPOINT V0,V1,V2,V3;
00267
00268 MinX = MaxX = P[0].x ;
00269 MinY = MaxY = P[0].y ;
00270 MinX = min( MinX, INT32(P[1].x) ) ; MaxX = max( MaxX, INT32(P[1].x) ) ;
00271 MinY = min( MinY, INT32(P[1].y) ) ; MaxY = max( MaxY, INT32(P[1].y) ) ;
00272 MinX = min( MinX, INT32(P[2].x) ) ; MaxX = max( MaxX, INT32(P[2].x) ) ;
00273 MinY = min( MinY, INT32(P[2].y) ) ; MaxY = max( MaxY, INT32(P[2].y) ) ;
00274 MinX = min( MinX, INT32(P[3].x) ) ; MaxX = max( MaxX, INT32(P[3].x) ) ;
00275 MinY = min( MinY, INT32(P[3].y) ) ; MaxY = max( MaxY, INT32(P[3].y) ) ;
00276 Width = MaxX-MinX ;
00277 Depth = MaxY-MinY ;
00278
00279 if (Width==0 || Depth==0)
00280 return FALSE;
00281
00282 V0.x = (double)(P[0].x-MinX)/Width ;
00283 V0.y = (double)(P[0].y-MinY)/Depth ;
00284 V1.x = (double)(P[1].x-MinX)/Width ;
00285 V1.y = (double)(P[1].y-MinY)/Depth ;
00286 V2.x = (double)(P[2].x-MinX)/Width ;
00287 V2.y = (double)(P[2].y-MinY)/Depth ;
00288 V3.x = (double)(P[3].x-MinX)/Width ;
00289 V3.y = (double)(P[3].y-MinY)/Depth ;
00290
00291 BOOL F = (V1.x-V0.x)*(V3.y-V0.y) > (V1.y-V0.y)*(V3.x-V0.x) ;
00292 if ( F != ((V2.x-V1.x)*(V0.y-V1.y) > (V2.y-V1.y)*(V0.x-V1.x)) ) return FALSE ;
00293 if ( F != ((V3.x-V2.x)*(V1.y-V2.y) > (V3.y-V2.y)*(V1.x-V2.x)) ) return FALSE ;
00294 if ( F != ((V0.x-V3.x)*(V2.y-V3.y) > (V0.y-V3.y)*(V2.x-V3.x)) ) return FALSE ;
00295
00296 return TRUE;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 BOOL MouldPerspective::Define(Path* const pPath, DocRect* const pOrigBBox)
00319 {
00320 ERROR2IF(pPath==NULL && pOrigBBox==NULL, FALSE,"MouldPerspective::Define() called with NULL parameters");
00321
00322 RECT ObjRect = BuildRectangle(pOrigBBox);
00323
00324
00325 POINT TempArray[PER_NUMCOORDS];
00326 RECT TempRect=Perspective.GetSourceBBox();
00327 Perspective.CopyShape(TempArray);
00328
00329
00330 POINT* pPoints = TempArray;
00331 if (pPath!=NULL)
00332 pPoints=(POINT*)pPath->GetCoordArray();
00333
00334
00335 Perspective.Define(pPoints,&ObjRect,MouldThreshold);
00336
00337
00338 if (!Perspective.Valid())
00339 {
00340
00341 Perspective.Define(TempArray,&TempRect,MouldThreshold);
00342 return FALSE;
00343 }
00344
00345 return TRUE;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 BOOL MouldPerspective::BuildShape(POINT* pPoints, DocRect* const pOrigBBox)
00366 {
00367 ERROR2IF(pPoints==NULL,FALSE,"MouldPerspective::BuildShape() called with NULL point list");
00368
00369 RECT ObjRect = BuildRectangle(pOrigBBox);
00370
00371 Perspective.Define(pPoints,&ObjRect,MouldThreshold);
00372
00373 return TRUE;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 RECT MouldPerspective::BuildRectangle(DocRect* const pOrigBBox)
00392 {
00393 RECT ObjRect;
00394 if (pOrigBBox!=NULL)
00395 {
00396 ObjRect.left = pOrigBBox->lo.x;
00397 ObjRect.bottom = pOrigBBox->lo.y;
00398 ObjRect.right = pOrigBBox->hi.x;
00399 ObjRect.top = pOrigBBox->hi.y;
00400 }
00401 else
00402 ObjRect = Perspective.GetSourceBBox();
00403
00404 return ObjRect;
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 BOOL MouldPerspective::MouldPathToPath(Path* pSourcePath, Path* pDestinPath)
00428 {
00429 ERROR2IF(pSourcePath==NULL, FALSE, "MouldPerspective::MouldPathToPath() passed a NULL source pointer");
00430 ERROR2IF(pDestinPath==NULL, FALSE, "MouldPerspective::MouldPathToPath() passed a NULL destin pointer");
00431
00432
00433 DWORD ilength = (DWORD)pSourcePath->GetNumCoords();
00434
00435
00436 if (ilength<1)
00437 return TRUE;
00438
00439 INT32 freespace = ilength*4;
00440 INT32 maxspace = ilength*16;
00441 BOOL ok;
00442 INT32 added;
00443
00444 Path TempPath;
00445 if (!TempPath.Initialise(freespace,24))
00446 return FALSE;
00447
00448 do
00449 {
00450
00451 POINT* icoords = (POINT*)pSourcePath->GetCoordArray();
00452 BYTE* iverbs = (BYTE*)pSourcePath->GetVerbArray();
00453 POINT* ocoords = (POINT*)TempPath.GetCoordArray();
00454 BYTE* overbs = (BYTE*)TempPath.GetVerbArray();
00455
00456
00457 added = Perspective.FitPath(icoords,iverbs,ilength,ocoords,overbs,freespace);
00458
00459 if (added==-1)
00460 {
00461 freespace*=2;
00462
00463 ok = TempPath.EnsureVolume(freespace);
00464 if (!ok)
00465 return FALSE;
00466 }
00467
00468 } while ((added==-1) && freespace<=maxspace);
00469
00470
00471 if (added<=1)
00472 return FALSE;
00473
00474
00475 ok = TempPath.ExternalArraysReplaced(added);
00476 if (ok)
00477 TempPath.InitialiseFlags(0,added);
00478
00479 if (ok)
00480 {
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 ok = pDestinPath->CloneFrom(TempPath);
00531 }
00532
00533 return ok;
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 BOOL MouldPerspective::MouldPoint(DocCoord p,DocCoord& q)
00554 {
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 POINT r,s;
00569
00570 r.x = p.x;
00571 r.y = p.y;
00572
00573 Perspective.FitPoint(r,s);
00574
00575 q.x = s.x;
00576 q.y = s.y;
00577
00578 return TRUE;
00579 }
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 BOOL MouldPerspective::MouldBitmapToTile(KernelBitmap* pSourceBlit, KernelBitmap* pDestinBlit)
00600 {
00601
00602 return FALSE;
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 void MouldPerspective::MouldPathRender(Path* pPath, RenderRegion* pRegion)
00620 {
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 void MouldPerspective::MouldBitmapRender(KernelBitmap* pBlit,
00642 DocCoord* Parallel,
00643 RenderRegion* pRegion)
00644 {
00645 pRegion->SaveContext();
00646
00647
00648 pRegion->SetLineColour(COLOUR_TRANS);
00649
00650 pRegion->RestoreContext();
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 void MouldPerspective::ToggleControlBlobs(Spread* pSpread)
00665 {
00666
00667 if (GridState>1) return;
00668
00669 GridState ^= 1;
00670 if (pSpread!=NULL)
00671 RenderGrid(pSpread);
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 void MouldPerspective::EnableControlBlobs()
00686 {
00687 if (GridState>1) GridState--;
00688 }
00689
00690 void MouldPerspective::DisableControlBlobs()
00691 {
00692 if (GridState>0) GridState++;
00693 }
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 void MouldPerspective::RenderControlBlobs(RenderRegion* pRegion)
00708 {
00709 #if !defined(EXCLUDE_FROM_RALPH)
00710 ERROR3IF(pRegion==NULL,"MouldPerspective::RenderControlBlobs passed a NULL region");
00711 if (pRegion==NULL)
00712 return;
00713 if (GridState==1)
00714 RenderGrid(pRegion);
00715
00716 RenderVanishingPoints(pRegion);
00717 #endif
00718 }
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 void MouldPerspective::RenderDragBlobs(Spread* pSpread)
00733 {
00734 #if !defined(EXCLUDE_FROM_RALPH)
00735 ERROR3IF(pSpread==NULL,"MouldPerspective::RenderControlBlobs passed a NULL spread");
00736 if (pSpread==NULL)
00737 return;
00738 if (GridState>0)
00739 RenderGrid(pSpread);
00740
00741 RenderVanishingPoints(pSpread);
00742 #endif
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 void MouldPerspective::RenderGrid(Spread* pSpread)
00757 {
00758 #if !defined(EXCLUDE_FROM_RALPH)
00759 ERROR3IF(pSpread==NULL,"MouldPerspective::RenderGrid() passed a NULL spread");
00760 DocRect Rect = Perspective.GetBoundingRect();
00761 RenderRegion* pRegion = DocView::RenderOnTop( &Rect, pSpread, ClippedEOR );
00762 while ( pRegion )
00763 {
00764 RenderGrid(pRegion);
00765 pRegion = DocView::GetNextOnTop(NULL);
00766 }
00767 #endif
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 void MouldPerspective::RenderGrid(RenderRegion* pRegion)
00784 {
00785 #if !defined(EXCLUDE_FROM_RALPH)
00786 ERROR3IF(pRegion==NULL,"MouldPerspective::RenderBlobs() passed a NULL region");
00787 if (pRegion==NULL) return;
00788
00789
00790 MouldGeometry::RenderControlBlobs(pRegion);
00791
00792 pRegion->SetLineWidth(0);
00793 pRegion->SetLineColour(GREEN);
00794 pRegion->SetFillColour(GREEN);
00795
00796 RenderGridPoints(pRegion);
00797 #endif
00798 }
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 void MouldPerspective::RenderGridPoints(RenderRegion* pRegion)
00814 {
00815 #if !defined(EXCLUDE_FROM_RALPH)
00816
00817
00818
00819 INT32 p0 = 8;
00820 INT32 p1 = 4*p0;
00821 INT32 a,b,x,y;
00822 POINT sU,dU;
00823 DocCoord pU;
00824 RECT Bounds = Perspective.GetSourceBBox();
00825 INT32 dX = Bounds.right - Bounds.left;
00826 INT32 dY = Bounds.top - Bounds.bottom;
00827
00828 for (a=1; a<p0; a++)
00829 {
00830 x = Bounds.left + a*dX/p0;
00831 y = Bounds.bottom + a*dY/p0;
00832
00833 for (b=1; b<p1; b++)
00834 {
00835 if (b % (p1/p0))
00836 {
00837 sU.x = Bounds.left + b*dX/p1;
00838 sU.y = y;
00839 Perspective.FitPoint(sU,dU);
00840 pU.x = dU.x;
00841 pU.y = dU.y;
00842 pRegion->DrawPixel(pU);
00843 }
00844
00845 sU.x = x;
00846 sU.y = Bounds.bottom + b*dY/p1;
00847 Perspective.FitPoint(sU,dU);
00848 pU.x = dU.x;
00849 pU.y = dU.y;
00850 pRegion->DrawPixel(pU);
00851 }
00852 }
00853 #endif
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868 void MouldPerspective::RenderVanishingPoints(Spread* pSpread)
00869 {
00870 #if !defined(EXCLUDE_FROM_RALPH)
00871 ERROR3IF(pSpread==NULL,"MouldPerspective::RenderVanishingPoints() passed a NULL spread");
00872 DocCoord v0,v1;
00873 GetVanishingPoints(v0,v1);
00874 RenderVanishingPoint(pSpread,v0);
00875 RenderVanishingPoint(pSpread,v1);
00876 #endif
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 void MouldPerspective::RenderVanishingPoint(Spread* pSpread, const DocCoord& dcPos)
00892 {
00893 #if !defined(EXCLUDE_FROM_RALPH)
00894 DocRect Rect;
00895 if (dcPos.x!=PER_UNDEFINED)
00896 {
00897 Rect=CalcBlobClipRect(dcPos);
00898 RenderRegion* pRegion = DocView::RenderOnTop(&Rect, pSpread, ClippedEOR );
00899 while ( pRegion )
00900 {
00901 pRegion->SetLineColour(COLOUR_XORSELECT);
00902 PORTNOTE("other", "DrawBitmapBlob removed");
00903
00904 pRegion = DocView::GetNextOnTop(NULL);
00905 }
00906 }
00907 #endif
00908 }
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 void MouldPerspective::RenderVanishingPoints(RenderRegion* pRegion)
00922 {
00923 #if !defined(EXCLUDE_FROM_RALPH)
00924 pRegion->SetLineColour(COLOUR_XORSELECT);
00925
00926
00927 DocCoord v0,v1;
00928 GetVanishingPoints(v0,v1);
00929
00930 PORTNOTE("other", "DrawBitmapBlob removed");
00931
00932
00933
00934
00935 #endif
00936 }
00937
00938
00939 void MouldPerspective::ShowVPoints()
00940 {
00941 DocCoord v0,v1;
00942 GetVanishingPoints(v0,v1);
00943
00944
00945 }
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962 DocRect MouldPerspective::CalcBlobClipRect(const DocCoord& dcPos)
00963 {
00964 #if !defined(EXCLUDE_FROM_RALPH)
00965 BlobManager* pBlobManager = GetApplication()->GetBlobManager();
00966 INT32 nSize = pBlobManager->GetBlobSize() + 2;
00967 return DocRect(DocCoord(dcPos.x - nSize, dcPos.y - nSize),
00968 DocCoord(dcPos.x + nSize, dcPos.y + nSize));
00969 #else
00970 return DocRect(0,0,0,0);
00971 #endif
00972 }
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 DocRect MouldPerspective::GetBlobBoundingRect()
00989 {
00990 #if !defined(EXCLUDE_FROM_RALPH)
00991 DocCoord v0,v1;
00992 GetVanishingPoints(v0,v1);
00993
00994 DocRect Rect;
00995
00996 if (v0.x!=PER_UNDEFINED)
00997 Rect=Rect.Union(CalcBlobClipRect(v0));
00998
00999 if (v1.x!=PER_UNDEFINED)
01000 Rect=Rect.Union(CalcBlobClipRect(v1));
01001
01002 return Rect;
01003 #else
01004 return DocRect(0,0,0,0);
01005 #endif
01006 }
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 void MouldPerspective::GetVanishingPoints(DocCoord& p0, DocCoord& p1)
01024 {
01025 POINT v0,v1;
01026 Perspective.VanishingPoints(v0,v1);
01027 p0.x=v0.x; p0.y=v0.y;
01028 p1.x=v1.x; p1.y=v1.y;
01029 }
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 BOOL MouldPerspective::MoveVanishingPoint(DocCoord OldPoint, DocCoord& NewPoint)
01055 {
01056 #if !defined(EXCLUDE_FROM_RALPH)
01057 BOOL Flag;
01058 if (OldPoint.x==PER_UNDEFINED || OldPoint.y==PER_UNDEFINED)
01059 return FALSE;
01060
01061 POINT p;
01062 p.x=OldPoint.x;
01063 p.y=OldPoint.y;
01064
01065 if (!Perspective.WhichVanishingPoint(p, Flag))
01066 return FALSE;
01067
01068
01069 POINT TempArray[PER_NUMCOORDS];
01070 Perspective.CopyShape(TempArray);
01071 POINT TempArray1[PER_NUMCOORDS];
01072 Perspective.CopyShape(TempArray1);
01073 INT32 SCode = Perspective.GetVPointState();
01074
01075 p.x=NewPoint.x;
01076 p.y=NewPoint.y;
01077
01078 Perspective.DragVanishingPoints(p,Flag,TempArray1);
01079 BuildShape(TempArray1,NULL);
01080 INT32 ECode = Perspective.GetVPointState();
01081
01082
01083 if ((!Perspective.Valid()) || (SCode!=ECode))
01084 {
01085
01086 BuildShape(TempArray,NULL);
01087 return FALSE;
01088 }
01089
01090 DocCoord v0,v1;
01091 GetVanishingPoints(v0,v1);
01092 Flag ? (NewPoint=v1) : (NewPoint=v0);
01093 #endif
01094 return TRUE;
01095 }
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114 void MouldPerspective::CopyShape(DocCoord* pCoords)
01115 {
01116 POINT TempArray[PER_NUMCOORDS];
01117 Perspective.CopyShape(TempArray);
01118
01119 INT32 i;
01120 for( i = 0; i < PER_NUMCOORDS; i++ )
01121 {
01122 pCoords[i].x = TempArray[i].x;
01123 pCoords[i].y = TempArray[i].y;
01124 }
01125
01126
01127 pCoords[i].x=TempArray[0].x;
01128 pCoords[i].y=TempArray[0].y;
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 MouldGeometry* MouldPerspective::MakeCopy()
01146 {
01147
01148 MouldPerspective* pShape = new MouldPerspective;
01149 if (pShape == NULL)
01150 return NULL;
01151
01152 BOOL ok = CopyContents(pShape);
01153 if (!ok)
01154 {
01155 delete pShape;
01156 return NULL;
01157 }
01158
01159 return (pShape);
01160 }
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177 BOOL MouldPerspective::CopyContents(MouldPerspective* pPerspective)
01178 {
01179 ERROR3IF(pPerspective==NULL, "MouldPerspective::CopyContents() passed a null pointer");
01180
01181 if (!MouldGeometry::CopyContents(pPerspective))
01182 return FALSE;
01183
01184
01185 POINT TempArray[PER_NUMCOORDS];
01186 RECT TempRect = Perspective.GetSourceBBox();
01187 DocRect Rect = ConvRectToDocRect(TempRect);
01188 Perspective.CopyShape(TempArray);
01189
01190
01191 return (pPerspective->BuildShape(TempArray, &Rect));
01192 }
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207 DocRect MouldPerspective::GetSourceRect()
01208 {
01209 RECT Rect = Perspective.GetSourceBBox();
01210 return ConvRectToDocRect(Rect);
01211 }
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236 BOOL MouldPerspective::OnClick( DocCoord PointerPos,
01237 ClickType CType,
01238 ClickModifiers Mods,
01239 Spread* pSpread,
01240 NodeMould* pNodeMould)
01241 {
01242 BOOL Claimed=FALSE;
01243
01244 #ifndef STANDALONE
01245
01246
01247 BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
01248 if (pBlobMgr == NULL)
01249 return FALSE;
01250 if (!pBlobMgr->GetCurrentInterest().Object)
01251 return FALSE;
01252
01253 PerspectiveClick WhatToDo = DetermineClickEffect(PointerPos,pSpread);
01254
01255 switch (CType)
01256 {
01257 case CLICKTYPE_SINGLE:
01258 switch (WhatToDo)
01259 {
01260 case PClick_EditVPoint0:
01261 {
01262 Claimed=TRUE;
01263 OpDragOrigin* pOpDragOrigin = new OpDragOrigin;
01264 if (pOpDragOrigin!=NULL)
01265 pOpDragOrigin->DoDragVanishPoint(pSpread,PointerPos,Mods,pNodeMould,FALSE);
01266 }
01267 break;
01268
01269 case PClick_EditVPoint1:
01270 {
01271 Claimed=TRUE;
01272 OpDragOrigin* pOpDragOrigin = new OpDragOrigin;
01273 if (pOpDragOrigin!=NULL)
01274 pOpDragOrigin->DoDragVanishPoint(pSpread,PointerPos,Mods,pNodeMould,TRUE);
01275 }
01276 break;
01277 default: break;
01278 }
01279 break;
01280
01281 case CLICKTYPE_DOUBLE:
01282 break;
01283 case CLICKTYPE_DRAG:
01284 break;
01285 default: break;
01286 }
01287
01288 #endif
01289
01290 return Claimed;
01291 }
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312 BOOL MouldPerspective::OnMouseMove(DocCoord Coord,
01313 Spread* pSpread,
01314 ClickModifiers Mods,
01315 INT32* ctype,
01316 INT32* msgres)
01317 {
01318 #ifndef STANDALONE
01319
01320 ERROR2IF(ctype==NULL,FALSE,"MouldPerspective::OnMouseMove passed a null cursor type ptr");
01321 ERROR2IF(msgres==NULL,FALSE,"MouldPerspective::OnMouseMove passed a null msg res ptr");
01322
01323 PerspectiveClick Click = DetermineClickEffect(Coord, pSpread);
01324 switch (Click)
01325 {
01326 case PClick_EditVPoint0:
01327 case PClick_EditVPoint1:
01328 *ctype = 2;
01329 *msgres = 2;
01330 return TRUE;
01331 break;
01332 default: break;
01333 }
01334
01335 #endif
01336
01337 return FALSE;
01338 }
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356 PerspectiveClick MouldPerspective::DetermineClickEffect(DocCoord PointerPos,Spread* pSpread)
01357 {
01358 #if !defined(EXCLUDE_FROM_RALPH)
01359 DocRect Rect;
01360 DocCoord v0,v1;
01361
01362 GetVanishingPoints(v0,v1);
01363
01364 if (v0.x!=PER_UNDEFINED)
01365 {
01366 Rect=CalcBlobClipRect(v0);
01367 if (Rect.ContainsCoord(PointerPos))
01368 return PClick_EditVPoint0;
01369 }
01370
01371 if (v1.x!=PER_UNDEFINED)
01372 {
01373 Rect=CalcBlobClipRect(v1);
01374 if (Rect.ContainsCoord(PointerPos))
01375 return PClick_EditVPoint1;
01376 }
01377
01378 #endif
01379 return PClick_DoNothing;
01380 }
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403 void MouldPerspective::Transform(Path* const pNewGeom,
01404 DocRect* const pRect,
01405 TransformBase& Trans )
01406 {
01407
01408 Define(pNewGeom,pRect);
01409 }
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426 ChangeCode MouldPerspective::RecordContext(UndoableOperation* pOp)
01427 {
01428 if (pOp!=NULL)
01429 {
01430 RecordPerspectiveAction* PerAction;
01431 ActionCode Act;
01432
01433
01434 Act = RecordPerspectiveAction::Init(pOp, pOp->GetUndoActionList(), this, (Action**)(&PerAction));
01435
01436 if (Act == AC_FAIL)
01437 return CC_FAIL;
01438 if (Act == AC_NORECORD)
01439 return CC_NORECORD;
01440 }
01441 return CC_OK;
01442 }
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459 ChangeCode MouldPerspective::RecordBlobs(UndoableOperation* pOp, Spread* pSpread)
01460 {
01461 #ifndef STANDALONE
01462
01463 if (pOp!=NULL)
01464 {
01465 ActionCode Act;
01466 DocCoord v0,v1;
01467 DocRect Rect;
01468
01469 GetVanishingPoints(v0,v1);
01470
01471 if (v0.x!=PER_UNDEFINED)
01472 {
01473 Rect=CalcBlobClipRect(v0);
01474 Act=InvalidateRectAction::DoRecord(pOp,Rect,pSpread);
01475
01476 if (Act == AC_FAIL)
01477 return CC_FAIL;
01478 if (Act == AC_NORECORD)
01479 return CC_NORECORD;
01480 }
01481
01482 if (v1.x!=PER_UNDEFINED)
01483 {
01484 Rect=CalcBlobClipRect(v1);
01485 Act=InvalidateRectAction::DoRecord(pOp,Rect,pSpread);
01486
01487 if (Act == AC_FAIL)
01488 return CC_FAIL;
01489 if (Act == AC_NORECORD)
01490 return CC_NORECORD;
01491 }
01492
01493 }
01494 #endif
01495
01496 return CC_OK;
01497 }
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513 RecordPerspectiveAction::RecordPerspectiveAction()
01514 {
01515 pCPerspective=NULL;
01516 }
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529 RecordPerspectiveAction::~RecordPerspectiveAction()
01530 {
01531 }
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564 ActionCode RecordPerspectiveAction::Init(Operation* pOp,
01565 ActionList* pActionList,
01566 MouldPerspective* pPerspective,
01567 Action** NewAction)
01568 {
01569 ActionCode Ac = AC_FAIL;
01570 if (pPerspective!=NULL)
01571 {
01572 UINT32 ActSize = sizeof(RecordPerspectiveAction);
01573 Ac = Action::Init( pOp, pActionList, ActSize, CC_RUNTIME_CLASS(RecordPerspectiveAction), NewAction);
01574 if (Ac==AC_OK)
01575 {
01576 RecordPerspectiveAction* pAct = ((RecordPerspectiveAction*)*NewAction);
01577 if (pAct)
01578 {
01579 pAct->pCPerspective = pPerspective;
01580 pPerspective->Perspective.CopyShape(pAct->RecordArray);
01581 }
01582 }
01583 }
01584 return Ac;
01585 }
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608 ActionCode RecordPerspectiveAction::Execute()
01609 {
01610
01611 RecordPerspectiveAction* EnvAction;
01612 ActionCode Act;
01613 Act = RecordPerspectiveAction::Init(pOperation, pOppositeActLst, pCPerspective, (Action**)(&EnvAction));
01614
01615
01616
01617
01618 if (pCPerspective)
01619 pCPerspective->BuildShape(RecordArray,NULL);
01620
01621 return Act;
01622 }
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646 BOOL PerspectiveShapes::Rectangular(Path* pPath)
01647 {
01648 ERROR2IF(pPath==NULL,FALSE,"NULL path pointer passed to PerspectiveShapes::Rectangular()");
01649
01650 DocCoord point[PER_NUMCOORDS];
01651
01652 point[0].x = 0;
01653 point[0].y = 0;
01654 point[1].x = 0;
01655 point[1].y = 72000;
01656 point[2].x = 72000;
01657 point[2].y = 72000;
01658 point[3].x = 72000;
01659 point[3].y = 0;
01660
01661 return MakeShape(pPath,point);
01662 }
01663
01664
01665 BOOL PerspectiveShapes::LeftWall(Path* pPath)
01666 {
01667 ERROR2IF(pPath==NULL,FALSE,"NULL path pointer passed to PerspectiveShapes::LeftWall()");
01668
01669 DocCoord point[PER_NUMCOORDS];
01670
01671 point[0].x = 0;
01672 point[0].y = 0;
01673 point[1].x = 0;
01674 point[1].y = 72000;
01675 point[2].x = 72000;
01676 point[2].y = 45000;
01677 point[3].x = 72000;
01678 point[3].y = 27000;
01679
01680 return MakeShape(pPath,point);
01681 }
01682
01683
01684 BOOL PerspectiveShapes::RightWall(Path* pPath)
01685 {
01686 ERROR2IF(pPath==NULL,FALSE,"NULL path pointer passed to PerspectiveShapes::RightWall()");
01687
01688 DocCoord point[PER_NUMCOORDS];
01689
01690 point[0].x = 0;
01691 point[0].y = 27000;
01692 point[1].x = 0;
01693 point[1].y = 45000;
01694 point[2].x = 72000;
01695 point[2].y = 72000;
01696 point[3].x = 72000;
01697 point[3].y = 0;
01698
01699 return MakeShape(pPath,point);
01700 }
01701
01702
01703 BOOL PerspectiveShapes::Floor(Path* pPath)
01704 {
01705 ERROR2IF(pPath==NULL,FALSE,"NULL path pointer passed to PerspectiveShapes::Floor()");
01706
01707 DocCoord point[PER_NUMCOORDS];
01708
01709 point[0].x = 0;
01710 point[0].y = 0;
01711 point[1].x = 27000;
01712 point[1].y = 72000;
01713 point[2].x = 45000;
01714 point[2].y = 72000;
01715 point[3].x = 72000;
01716 point[3].y = 0;
01717
01718 return MakeShape(pPath,point);
01719 }
01720
01721
01722 BOOL PerspectiveShapes::Ceiling(Path* pPath)
01723 {
01724 ERROR2IF(pPath==NULL,FALSE,"NULL path pointer passed to PerspectiveShapes::Ceiling()");
01725
01726 DocCoord point[PER_NUMCOORDS];
01727
01728 point[0].x = 27000;
01729 point[0].y = 0;
01730 point[1].x = 0;
01731 point[1].y = 72000;
01732 point[2].x = 72000;
01733 point[2].y = 72000;
01734 point[3].x = 45000;
01735 point[3].y = 0;
01736
01737 return MakeShape(pPath,point);
01738 }
01739
01740
01741
01742 BOOL PerspectiveShapes::MakeShape(Path* pPath, DocCoord* point)
01743 {
01744 PathFlags flags;
01745 flags.IsSelected = FALSE;
01746
01747
01748 BOOL ok = (pPath->AddMoveTo(point[0],&flags));
01749 if (!ok) return FALSE;
01750
01751 ok = (pPath->AddLineTo(point[1],&flags));
01752 if (!ok) return FALSE;
01753
01754 ok = (pPath->AddLineTo(point[2],&flags));
01755 if (!ok) return FALSE;
01756
01757 ok = (pPath->AddLineTo(point[3],&flags));
01758 if (!ok) return FALSE;
01759
01760 ok = (pPath->AddLineTo(point[0],&flags));
01761 if (!ok) return FALSE;
01762
01763 ok = (pPath->CloseSubPath());
01764
01765 return (ok);
01766 }
01767
01768
01769
01770
01771
01773
01774
01775
01777
01778 GPerspective::GPerspective()
01779 {
01780
01781 P0.x = 0; P0.y = 0;
01782 P1.x = 0; P1.y = 1;
01783 P2.x = 1; P2.y = 1;
01784 P3.x = 1; P3.y = 0;
01785
01786 ScaleView();
01787 CalcViewConsts();
01788 }
01789
01790
01791 BOOL GPerspective::Redefine( POINT *P )
01792 {
01793
01794 P0.x = P[0].x ; P0.y = P[0].y ;
01795 P1.x = P[1].x ; P1.y = P[1].y ;
01796 P2.x = P[2].x ; P2.y = P[2].y ;
01797 P3.x = P[3].x ; P3.y = P[3].y ;
01798
01799
01800 CalcViewBBox();
01801 if (Width<1024) Width=1024;
01802 if (Depth<1024) Depth=1024;
01803
01804 ScaleView();
01805 CalcViewConsts();
01806
01807 return TRUE;
01808 }
01809
01810
01811 void GPerspective::CalcViewBBox()
01812 {
01813 MinX = MaxX = P0.x ;
01814 MinY = MaxY = P0.y ;
01815 MinX = min( MinX, INT32(P1.x) ) ; MaxX = max( MaxX, INT32(P1.x) ) ;
01816 MinY = min( MinY, INT32(P1.y) ) ; MaxY = max( MaxY, INT32(P1.y) ) ;
01817 MinX = min( MinX, INT32(P2.x) ) ; MaxX = max( MaxX, INT32(P2.x) ) ;
01818 MinY = min( MinY, INT32(P2.y) ) ; MaxY = max( MaxY, INT32(P2.y) ) ;
01819 MinX = min( MinX, INT32(P3.x) ) ; MaxX = max( MaxX, INT32(P3.x) ) ;
01820 MinY = min( MinY, INT32(P3.y) ) ; MaxY = max( MaxY, INT32(P3.y) ) ;
01821 Width = MaxX-MinX ;
01822 Depth = MaxY-MinY ;
01823 }
01824
01825
01826 void GPerspective::ScaleView()
01827 {
01828
01829 V0.x = (double)(P0.x-MinX)/Width ;
01830 V0.y = (double)(P0.y-MinY)/Depth ;
01831 V1.x = (double)(P1.x-MinX)/Width ;
01832 V1.y = (double)(P1.y-MinY)/Depth ;
01833 V2.x = (double)(P2.x-MinX)/Width ;
01834 V2.y = (double)(P2.y-MinY)/Depth ;
01835 V3.x = (double)(P3.x-MinX)/Width ;
01836 V3.y = (double)(P3.y-MinY)/Depth ;
01837 }
01838
01839
01840 void GPerspective::CalcViewConsts()
01841 {
01842
01843 double N, D ;
01844 D = (V1.y-V0.y)*(V2.x-V3.x) - (V1.x-V0.x)*(V2.y-V3.y) ;
01845
01846 if (( I0flag = (fabs(D) >= EPSILON) ))
01847 {
01848 N = (V3.y-V0.y)*(V2.x-V3.x) - (V3.x-V0.x)*(V2.y-V3.y) ;
01849 I0pos = (N<0.0) ^ (D<0.0) ;
01850 I0.x = V0.x+(V1.x-V0.x)*N/D ;
01851 I0.y = V0.y+(V1.y-V0.y)*N/D ;
01852 A.x = (V0.x-I0.x)*(V1.x-I0.x) ;
01853 A.y = (V0.y-I0.y)*(V1.y-I0.y) ;
01854 B.x = (V3.x-I0.x)*(V2.x-I0.x) ;
01855 B.y = (V3.y-I0.y)*(V2.y-I0.y) ;
01856 }
01857
01858 D = (V0.y-V3.y)*(V1.x-V2.x) - (V0.x-V3.x)*(V1.y-V2.y) ;
01859
01860 if (( I1flag = (fabs(D) >= EPSILON) ))
01861 {
01862 N = (V2.y-V3.y)*(V1.x-V2.x) - (V2.x-V3.x)*(V1.y-V2.y) ;
01863 I1pos = (N<0.0) ^ (D<0.0) ;
01864 I1.x = V3.x+(V0.x-V3.x)*N/D ;
01865 I1.y = V3.y+(V0.y-V3.y)*N/D ;
01866 }
01867 }
01868
01869
01870
01871 void GPerspective::CopyShape(POINT* P)
01872 {
01873 P[0].x = P0.x ; P[0].y = P0.y ;
01874 P[1].x = P1.x ; P[1].y = P1.y ;
01875 P[2].x = P2.x ; P[2].y = P2.y ;
01876 P[3].x = P3.x ; P[3].y = P3.y ;
01877 }
01878
01879
01880
01881 BOOL GPerspective::Valid()
01882 {
01883 BOOL F = (
01884 ((V0.x==V1.x) && (V0.y==V1.y)) ||
01885 ((V1.x==V2.x) && (V1.y==V2.y)) ||
01886 ((V2.x==V3.x) && (V2.y==V3.y)) ||
01887 ((V3.x==V0.x) && (V3.y==V0.y))
01888 );
01889
01890 if (F) return FALSE;
01891
01892 F = (V1.x-V0.x)*(V3.y-V0.y) > (V1.y-V0.y)*(V3.x-V0.x) ;
01893 if ( F != ((V2.x-V1.x)*(V0.y-V1.y) > (V2.y-V1.y)*(V0.x-V1.x)) ) return FALSE ;
01894 if ( F != ((V3.x-V2.x)*(V1.y-V2.y) > (V3.y-V2.y)*(V1.x-V2.x)) ) return FALSE ;
01895 if ( F != ((V0.x-V3.x)*(V2.y-V3.y) > (V0.y-V3.y)*(V2.x-V3.x)) ) return FALSE ;
01896 return TRUE ;
01897 }
01898
01899
01900 BOOL GPerspective::WhichVanishingPoint(POINT v, BOOL& b)
01901 {
01902 if (I0flag)
01903 {
01904 POINT a;
01905 InverseScale(I0,a);
01906 if (a.x==v.x && a.y==v.y)
01907 {
01908 b=FALSE;
01909 return TRUE;
01910 }
01911 }
01912
01913 if (I1flag)
01914 {
01915 POINT a;
01916 InverseScale(I1,a);
01917 if (a.x==v.x && a.y==v.y)
01918 {
01919 b=TRUE;
01920 return TRUE;
01921 }
01922 }
01923 return FALSE;
01924 }
01925
01926
01927 INT32 GPerspective::GetVPointState()
01928 {
01929 INT32 num=0;
01930 if (I0pos) num+=1;
01931 if (I1pos) num+=2;
01932 return num;
01933 }
01934
01935 void GPerspective::VanishingPoints( POINT& a, POINT& b )
01936 {
01937 if ( I0flag )
01938 InverseScale( I0, a ) ;
01939 else
01940 a.x = a.y = 0x80000000 ;
01941 if ( I1flag )
01942 InverseScale( I1, b ) ;
01943 else
01944 b.x = b.y = 0x80000000 ;
01945 }
01946
01947
01948
01949 void GPerspective::DragVanishingPoints( POINT& NewI, BOOL Flag, LPPOINT P )
01950 {
01951 DPOINT I ;
01952 Scale( NewI, I ) ;
01953 if ( !Flag )
01954 if ( !I0pos )
01955 {
01956 Intersect( I, V0, V1, V2, P[1] ) ;
01957 Intersect( I, V3, V1, V2, P[2] ) ;
01958 }
01959 else
01960 {
01961 Intersect( I, V1, V0, V3, P[0] ) ;
01962 Intersect( I, V2, V0, V3, P[3] ) ;
01963 }
01964 else
01965 if ( I1pos )
01966 {
01967 Intersect( I, V0, V3, V2, P[3] ) ;
01968 Intersect( I, V1, V3, V2, P[2] ) ;
01969 }
01970 else
01971 {
01972 Intersect( I, V3, V0, V1, P[0] ) ;
01973 Intersect( I, V2, V0, V1, P[1] ) ;
01974 }
01975 }
01976
01978
01979
01980 BOOL GPerspective::FitPath (
01981 CONST POINT* IPoints,
01982 CONST BYTE* ITypes,
01983 DWORD ILength,
01984 LPPOINT pOPoints,
01985 LPBYTE pOTypes,
01986 DWORD pOLength,
01987 BOOL Close
01988 )
01989 {
01990 OPoints = pOPoints ;
01991 OTypes = pOTypes ;
01992 OLength = pOLength ;
01993
01994 DPOINT C2, C4 ;
01995 DPOINT P0, P2, P4, P6 ;
01996 DPOINT T0, T2, T4, T6 ;
01997 while ( ILength )
01998 {
01999 switch ( *ITypes & PT_MOVETO )
02000 {
02001 case PT_MOVETO :
02002 case PT_LINETO :
02003 --ILength ;
02004 ScaleSrc( *IPoints++, P0 ) ;
02005 Transform( P0, T0 ) ;
02006 if ( !GenOp( *ITypes++, T0 ) ) return -1 ;
02007 break ;
02008 case PT_BEZIERTO :
02009 ILength -= 3 ;
02010 ScaleSrc( *IPoints++, C2 ) ;
02011 ScaleSrc( *IPoints++, C4 ) ;
02012 ScaleSrc( *IPoints++, P6 ) ;
02013 P2.x = (8*P0.x+12*C2.x+ 6*C4.x+ P6.x)/27 ;
02014 P2.y = (8*P0.y+12*C2.y+ 6*C4.y+ P6.y)/27 ;
02015 P4.x = ( P0.x+ 6*C2.x+12*C4.x+8*P6.x)/27 ;
02016 P4.y = ( P0.y+ 6*C2.y+12*C4.y+8*P6.y)/27 ;
02017 Transform( P2, T2 ) ;
02018 Transform( P4, T4 ) ;
02019 Transform( P6, T6 ) ;
02020 if ( !GenCurve( C2, C4, P0, P2, P4, P6, T0, T2, T4, T6 ) ) return -1 ;
02021 P0.x = P6.x ; P0.y = P6.y ;
02022 T0.x = T6.x ; T0.y = T6.y ;
02023 ITypes += 3 ;
02024 *(OTypes-1) = *(ITypes-1) ;
02025 break ;
02026 default :
02027 return -1 ;
02028 }
02029 }
02030 if ( ILength )
02031 return -1 ;
02032 return pOLength-OLength ;
02033 }
02034
02035
02036
02037 void GPerspective::Transform( DPOINT a, DPOINT& b )
02038 {
02039 DPOINT p, q ;
02040 p.x = V0.x ;
02041 p.y = V0.y ;
02042 q.x = V3.x ;
02043 q.y = V3.y ;
02044 if ( notequal(a.y,0) )
02045 if ( I0flag )
02046 {
02047 if ( notequal(V0.x,V1.x) )
02048 p.x = I0.x+A.x/(a.y*(V0.x-V1.x)+V1.x-I0.x) ;
02049 if ( notequal(V0.y,V1.y) )
02050 p.y = I0.y+A.y/(a.y*(V0.y-V1.y)+V1.y-I0.y) ;
02051 if ( notequal(V3.x,V2.x) )
02052 q.x = I0.x+B.x/(a.y*(V3.x-V2.x)+V2.x-I0.x) ;
02053 if ( notequal(V3.y,V2.y) )
02054 q.y = I0.y+B.y/(a.y*(V3.y-V2.y)+V2.y-I0.y) ;
02055 }
02056 else
02057 {
02058 p.x = V0.x+a.y*(V1.x-V0.x) ;
02059 p.y = V0.y+a.y*(V1.y-V0.y) ;
02060 q.x = V3.x+a.y*(V2.x-V3.x) ;
02061 q.y = V3.y+a.y*(V2.y-V3.y) ;
02062 }
02063 b.x = p.x ;
02064 b.y = p.y ;
02065 if ( notequal(a.x,0) )
02066 if ( I1flag )
02067 {
02068 if ( notequal(p.x,q.x) )
02069 b.x = I1.x+(p.x-I1.x)*(q.x-I1.x)/(a.x*(p.x-q.x)+q.x-I1.x) ;
02070 if ( notequal(p.y,q.y) )
02071 b.y = I1.y+(p.y-I1.y)*(q.y-I1.y)/(a.x*(p.y-q.y)+q.y-I1.y) ;
02072 }
02073 else
02074 {
02075 b.x = p.x+a.x*(q.x-p.x) ;
02076 b.y = p.y+a.x*(q.y-p.y) ;
02077 }
02078 }
02079
02080
02081 void GPerspective::Intersect( DPOINT I, DPOINT P0, DPOINT P1, DPOINT P2, POINT& O )
02082 {
02083 double N, D ;
02084 DPOINT T ;
02085 N = (P1.y-P0.y)*(P2.x-P1.x) - (P1.x-P0.x)*(P2.y-P1.y) ;
02086 D = ( I.y-P0.y)*(P2.x-P1.x) - ( I.x-P0.x)*(P2.y-P1.y) ;
02087 T.x = P0.x+(I.x-P0.x)*N/D ;
02088 T.y = P0.y+(I.y-P0.y)*N/D ;
02089 InverseScale( T, O ) ;
02090 }
02091