Eeschem: fix bug when moving fields in schematic: incorrect field move for rotated+mirrored components
(added InverseTransform( ) in TRANSFORM class)
This commit is contained in:
parent
f43f7af5fe
commit
42b9e0e676
|
@ -653,7 +653,7 @@ void MODULE::Draw3D( Pcb3D_GLCanvas* glcanvas )
|
|||
pad->Draw3D( glcanvas );
|
||||
}
|
||||
|
||||
/* Draw module shape: 3D shape if exists (or module edge if not exists) */
|
||||
/* Draw module shape: 3D shape if exists (or module outlines if not exists) */
|
||||
S3D_MASTER* Struct3D = m_3D_Drawings;
|
||||
bool As3dShape = FALSE;
|
||||
if( g_Parm_3D_Visu.m_Draw3DModule )
|
||||
|
|
|
@ -46,16 +46,9 @@ void SCH_EDIT_FRAME::StartMoveCmpField( SCH_FIELD* aField, wxDC* DC )
|
|||
|
||||
pos = comp->m_Pos;
|
||||
|
||||
/* Positions are computed by the transpose matrix. Rotating mirror. */
|
||||
/* Positions are computed by the rotation/mirror transform. */
|
||||
newpos = aField->m_Pos - pos;
|
||||
|
||||
// Empirically this is necessary. The Y coordinate appears to be inverted
|
||||
// under some circumstances, but that inversion is not preserved by all
|
||||
// combinations of mirroring and rotation. The following clause is true
|
||||
// when the number of rotations and the number of mirrorings are both odd.
|
||||
if( comp->GetTransform().x2 * comp->GetTransform().y1 < 0 )
|
||||
NEGATE( newpos.y );
|
||||
|
||||
newpos = comp->GetTransform().TransformCoordinate( newpos ) + pos;
|
||||
|
||||
DrawPanel->CursorOff( DC );
|
||||
|
@ -206,10 +199,14 @@ static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
|
|||
|
||||
pos = ( (SCH_COMPONENT*) currentField->GetParent() )->m_Pos;
|
||||
|
||||
/* Positions are calculated by the transpose matrix, Rotating mirror. */
|
||||
// Actual positions are calculated by the rotation/mirror transform
|
||||
// But here we want the relative position of the moved field
|
||||
// and we know the actual position.
|
||||
// So we are using the inverse rotation/mirror transform.
|
||||
wxPoint pt( panel->GetScreen()->m_Curseur - pos );
|
||||
|
||||
currentField->m_Pos = pos + component->GetTransform().TransformCoordinate( pt );
|
||||
TRANSFORM itrsfm = component->GetTransform().InverseTransform();
|
||||
currentField->m_Pos = pos + itrsfm.TransformCoordinate( pt );
|
||||
|
||||
currentField->Draw( panel, DC, wxPoint( 0, 0 ), g_XorMode );
|
||||
}
|
||||
|
|
|
@ -31,6 +31,30 @@ wxPoint TRANSFORM::TransformCoordinate( const wxPoint& aPoint ) const
|
|||
( x2 * aPoint.x ) + ( y2 * aPoint.y ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the Inverse mirror/rotation transform.
|
||||
*/
|
||||
TRANSFORM TRANSFORM::InverseTransform( ) const
|
||||
{
|
||||
int invx1;
|
||||
int invx2;
|
||||
int invy1;
|
||||
int invy2;
|
||||
|
||||
/* Calculates the inverse matrix coeffs:
|
||||
* for a matrix m{x1, x2, y1, y2}
|
||||
* the inverse matrix is 1/(x1*y2 -x2*y1) m{y2,-x2,-y1,x1)
|
||||
*/
|
||||
int det = x1*y2 -x2*y1; // Is never null, because the inverse matrix exists
|
||||
invx1 = y2/det;
|
||||
invx2 = -x2/det;
|
||||
invy1 = -y1/det;
|
||||
invy2 = x1/det;
|
||||
|
||||
TRANSFORM invtransform( invx1, invy1, invx2, invy2 );
|
||||
return invtransform;
|
||||
}
|
||||
|
||||
|
||||
bool TRANSFORM::MapAngles( int* aAngle1, int* aAngle2 ) const
|
||||
{
|
||||
|
|
|
@ -59,13 +59,24 @@ public:
|
|||
bool operator!=( const TRANSFORM& aTransform ) const { return !( *this == aTransform ); }
|
||||
|
||||
/**
|
||||
* Calculate new coordinate according to the transform.
|
||||
*
|
||||
* Calculate new coordinate according to the mirror/rotation transform.
|
||||
* Useful to calculate actual coordinates of a point
|
||||
* from coordinates relative to a component
|
||||
* which are given for a non rotated, non mirrored item
|
||||
* @param aPoint = The position to transform
|
||||
* @return The transformed coordinate.
|
||||
*/
|
||||
wxPoint TransformCoordinate( const wxPoint& aPoint ) const;
|
||||
|
||||
/**
|
||||
* Calculate the Inverse mirror/rotation transform.
|
||||
* Useful to calculate coordinates relative to a component
|
||||
* which must be for a non rotated, non mirrored item
|
||||
* from the actual coordinate.
|
||||
* @return The inverse transform.
|
||||
*/
|
||||
TRANSFORM InverseTransform( ) const;
|
||||
|
||||
/**
|
||||
* Calculate new angles according to the transform.
|
||||
*
|
||||
|
|
|
@ -1091,9 +1091,12 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
|
|||
int offsety = wxRound( vrmlm->m_MatPosition.y * UNITS_3D_TO_PCB_UNITS );
|
||||
double offsetz = vrmlm->m_MatPosition.z * UNITS_3D_TO_PCB_UNITS;
|
||||
|
||||
RotatePoint(&offsetx, &offsety, aModule->m_Orient);
|
||||
if ( isFlipped )
|
||||
NEGATE(offsetz);
|
||||
else // In normal mode, Y axis is reversed in Pcbnew.
|
||||
NEGATE(offsety);
|
||||
|
||||
RotatePoint(&offsetx, &offsety, aModule->m_Orient);
|
||||
|
||||
fprintf( aOutputFile, " translation %g %g %g\n",
|
||||
(double) (offsetx + aModule->m_Pos.x),
|
||||
|
|
|
@ -143,13 +143,24 @@ void BOARD_PRINTOUT_CONTROLER::DrawPage()
|
|||
|
||||
WinEDA_BasePcbFrame* pcbframe = (WinEDA_BasePcbFrame*) m_Parent;
|
||||
pcbframe->GetBoard()->ComputeBoundaryBox();
|
||||
EDA_Rect brd_BBox = pcbframe->GetBoard()->m_BoundaryBox;
|
||||
// In module editor, the module is located at 0,0 but for printing
|
||||
// it is moved to SheetSize.x/2, SheetSize.y/2.
|
||||
// So the equivalent board must be moved:
|
||||
if( m_Parent->m_Ident == MODULE_EDITOR_FRAME )
|
||||
{
|
||||
wxPoint mv_offset;
|
||||
mv_offset.x = SheetSize.x / 2;
|
||||
mv_offset.y = SheetSize.y / 2;
|
||||
brd_BBox.Move( mv_offset );
|
||||
}
|
||||
/* Compute the PCB size in internal units*/
|
||||
userscale = m_PrintParams.m_PrintScale;
|
||||
if( userscale == 0 ) // fit in page
|
||||
{
|
||||
int extra_margin = 4000*2; // Margin = 4000 units pcb = 0.4 inch
|
||||
SheetSize.x = pcbframe->GetBoard()->m_BoundaryBox.GetWidth() + extra_margin;
|
||||
SheetSize.y = pcbframe->GetBoard()->m_BoundaryBox.GetHeight() + extra_margin;
|
||||
SheetSize.x = brd_BBox.GetWidth() + extra_margin;
|
||||
SheetSize.y = brd_BBox.GetHeight() + extra_margin;
|
||||
userscale = 0.99;
|
||||
}
|
||||
|
||||
|
@ -157,8 +168,8 @@ void BOARD_PRINTOUT_CONTROLER::DrawPage()
|
|||
if( (m_PrintParams.m_PrintScale > 1.0) // scale > 1 -> Recadrage
|
||||
|| (m_PrintParams.m_PrintScale == 0) ) // fit in page
|
||||
{
|
||||
DrawOffset += pcbframe->GetBoard()->m_BoundaryBox.Centre();
|
||||
}
|
||||
DrawOffset += brd_BBox.Centre();
|
||||
}
|
||||
|
||||
if( m_PrintParams.m_PageSetupData )
|
||||
{
|
||||
|
@ -266,7 +277,7 @@ void BOARD_PRINTOUT_CONTROLER::DrawPage()
|
|||
* for scales > 1, the DrawOffset was already computed to have the board centre
|
||||
* to the middle of the page.
|
||||
*/
|
||||
wxPoint pcb_centre = pcbframe->GetBoard()->m_BoundaryBox.Centre();
|
||||
wxPoint pcb_centre = brd_BBox.Centre();
|
||||
if( userscale <= 1.0 )
|
||||
DrawOffset.y += pcb_centre.y - (ysize / 2);
|
||||
#ifdef USE_WX_ZOOM
|
||||
|
|
Loading…
Reference in New Issue