math - Calculating if or not a 3D eyepoint is behind a 2D plane or upwards -
the setup
draw xy-coordinate axes on piece of paper. write word on along x-axis, word's centerpoint @ origo (half on positive side of x/y, other half on negative side of x/y).
now, if flip paper upside down you'll notice word mirrored in relation both x- , y-axis. if behind paper, it's mirrored in relation y-axis. if @ behind , upside down, it's mirrored in relation x-axis.
ok, have points in 2d-plane (vertices) created in similar way @ origo , need apply same rule them. make things interesting:
- the 2d plane 3d, each point (vertex) being (x, y, 0). vertices positioned origo , normal pn(0,0,1). => correctly seen when looked @ point pn towards origo.
- the vertex-plane has it's own rotation matrix [rp] , position p(x,y,z) in 3d-world. rotation applied before positioning.
- the 3d world "right handed". viewer looking towards origo distance along positive z-axis world oriented rotation matrix [rw]. [rw] * (0,0,1) point directly viewer's eye.
from need calculate when vertex-plane should mirrored , axis. mirroring can done before applying [rp] , p by:
vertices vertices = get2dplanepoints(); int mirrorx = 1; // -1 mirror, 1 not mirror int mirrory = 1; // -1 mirror, 1 not mirror matrix worldrotation = getworldrotationmatrix(); mirrorx = getmirrorxfactor(worldrotation); mirrory = getmirroryfactor(worldrotation); foreach(vertex v in vertices) { v.x = v.x * mirrorx * mirrory; v.y = v.y * mirrory; } // apply rotation... // add position...
the question
so need getmirrorxfactor() & ..yfactor() -functions return -1 if viewer's eyepoint @ greater "x/y"-angle +-90 degrees in relation vertex-plane's normal after rotation , world orientation. i have solved this, i'm looking more "elegant" mathematics. know rotation matrices somehow contain info how rotated axis , believe can utilized here.
my solution mirrorx:
// matrix multiplications. vectors vertical matrices here. pnr = [rp] * pn // rotated vertices's normal pur = [rp] * (0,1,0) // rotated vertices's "up-vector" wnr = [rw] * (0,0,1) // rotated eye-vector world's orientation // = vector pointing directly @ viewer's eye // use rotated up-vector normal new plane , project viewer's // eye on it. dot = dot product between vectors. wnrx = wnr - (wnr dot pur) * pur // "x-projected" eye. // calculate angle between eye's x-component , plane's rotated normal. // ||v|| = v's norm. angle = arccos( (wnrx dot pnr) / ( ||wnrx|| * ||pnr|| ) ) if (angle > pi / 2) mirrorx = -1; // mirror else mirrorx = 1; // don't mirror
solution mirrory can done in similar way using viewer's , vertex-plane's right -vectors.
better solution?
if (([rp]*(1,0,0)) dot ([rw]*(1,0,0))) < 0 mirrorx = -1; // mirror else mirrorx = 1; // don't mirror if (([rp]*(0,1,0)) dot ([rw]*(0,1,0))) < 0 mirrory = -1; // mirror else mirrory = 1; // don't mirror
explaining in more detail difficult without diagrams, if have trouble solution can work through cases.
Comments
Post a Comment