Так как координаты Windows находятся на экране по оси z (x пересекают y), я бы использовал что-то вроде
screenY = viewPort.ActualHeight * (1 - screenY);
вместо
screenY = screenY * viewPort.ActualHeight;
чтобы исправить screenY для размещения Windows.
Либо вы можете использовать OpenGL. Когда вы устанавливаете диапазон просмотра x / y / z, вы можете оставить его в «родных» единицах и позволить OpenGL преобразовать в экранные координаты.
Edit:
Так как ваше происхождение является центром. Я бы попробовал
screenX = viewPort.ActualWidth * (screenX + 1.0) / 2.0
screenY = viewPort.ActualHeight * (1.0 - ((screenY + 1.0) / 2.0))
Экран + 1,0 преобразуется из [-1,0, 1,0] в [0,0, 2,0]. В этот момент вы делите на 2,0, чтобы получить [0,0, 1,0] для умножения. Чтобы учесть, что Windows y переворачивается с декартовой y, вы конвертируете из [1.0, 0.0] (слева направо в нижний левый угол) в [0.0, 1.0] (сверху вниз), вычитая предыдущий экран из 1.0. Затем вы можете масштабировать до ActualHeight.