I am trying to create a vanishing point perspective transformation of 2D polygons, for example transforming the red polygon into the blue polygon:
p1 = Polygon[{{0, 0}, {1, 0}, {1, 1}, {0, 1}}];
p2 = Polygon[{{0, 0}, {1, 0}, {0.55, 0.5}, {0.45, 0.5}}];
Graphics[{FaceForm[None], EdgeForm[Red], p1, EdgeForm[Blue], p2}]
I can find the transformation easily enough with {err, tr} = FindGeometricTransform[First@p2, First@p1]
; however, since the transformation is not an affine mapping, it cannot be handled by GeometricTransformation
. Instead, I need to transform the points that make up the polygon:
Graphics[{FaceForm[None], EdgeForm[Red], p1, EdgeForm[Blue], Polygon@tr@First@p1}]
All seems well. If I try to apply a texture to the transformed polygon, things get ugly:
vop = VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
Graphics[{Texture[ExampleData[{"Texture", "Bricks3"}]], EdgeForm[Red],
Polygon[tr@First@p1, vop]}]
It appears that the internals of Texture
can't handle the non-affine mapping very well, despite being able to handle affine transforms:
str = ShearingTransform[30 Degree, {1, 0}, {0, 1}]
Graphics[{Texture[ExampleData[{"Texture", "Bricks3"}]], EdgeForm[Red],
Polygon[str@First@p1, vop]}]
A rather clunky way around this problem is to use ImagePerspectiveTransformation
, which was mentioned previously as having the ability to map any type of transform (affine or not).
ipt = ImagePerspectiveTransformation[
ExampleData[{"Texture", "Bricks3"}], tr, Padding -> None]
Show[ipt,
Graphics[{FaceForm[None], EdgeForm[{Thick, Red}],
Polygon[First@ImageDimensions[ipt]*p2[[1]]]}], ImageSize -> 400]
This problem (I think) boils down to performing a non-affine transform to a texture, so I am wondering how (or if) this might be done efficiently than to perform the ImagePerspectiveTransformation on the texture image first?
ipt
as a texture if you also apply the transformation to the texture coordinates:Graphics[{Texture[ipt], EdgeForm[Directive[Red, Thick]], Append[p2, VertexTextureCoordinates -> tr[p1[[1]]]]}]
$\endgroup$