473,657 Members | 2,499 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Augmenting 3D graphics with 2D labels


I am writing a 3D graphing component built upon WPF and would like to have
2D vector graphics (e.g. typeset mathematics) as labels laid out from 3D
coordinates. For example, a tick on an axis has a 3D coordinate and its 2D
label might be right-aligned to the 2D projection of that 3D point.

The following Mathematica plot illustrates the functionality I am after:

http://math.arizona.edu/~goriely/M32...omplexFunc.jpg

I have done some Googling but not found a solution. Some people use 3D
labels but these are ugly and suffer from various artefacts (e.g. they
become heavily distorted or disappear completely when viewed at the wrong
angle).

The best solution I can imagine is a 2D DrawingVisual overlaid over my 3D
Viewport but I need a function to project 3D coordinates onto 2D
coordinates and WPF does not seem to provide one. I can reverse engineer
the projection algorithm used by WPF but Microsoft may change the algorithm
in the future and break my code.

Any ideas?

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #1
4 5226
Jon Harrop wrote:
I am writing a 3D graphing component built upon WPF and would like to have
2D vector graphics (e.g. typeset mathematics) as labels laid out from 3D
coordinates. For example, a tick on an axis has a 3D coordinate and its 2D
label might be right-aligned to the 2D projection of that 3D point.

The following Mathematica plot illustrates the functionality I am after:

http://math.arizona.edu/~goriely/M32...omplexFunc.jpg

I have done some Googling but not found a solution. Some people use 3D
labels but these are ugly and suffer from various artefacts (e.g. they
become heavily distorted or disappear completely when viewed at the wrong
angle).

The best solution I can imagine is a 2D DrawingVisual overlaid over my 3D
Viewport but I need a function to project 3D coordinates onto 2D
coordinates and WPF does not seem to provide one. I can reverse engineer
the projection algorithm used by WPF but Microsoft may change the
algorithm in the future and break my code.

Any ideas?
To answer my own question: I finally got this working reliably after several
days of work and it is not easy. Moreover, there is a lot of unfortunate
ugliness because WPF exposes less functionality than alternatives like
OpenGL so you have to do a lot of work just to get something that works but
is inefficient.

To overlay 2D graphics over 3D graphics, I initially tried StackPanel,
DockPanel and the Canvas. StackPanel and DockPanel are not suitable because
their layout algorithms either overlay but provide too much space (the
default infinite space crashes WPF if it reaches a Viewport3D) or they
stack or dock the Viewports as expected but not as wanted. Canvas lets you
place the controls but it also provides infinite space for layout and that
crashes WPF. You can make the space finite but it needs to be a function of
the space available to the parent and that is not available.

So the most elegant solution I came up with was to derive from Panel and
implement my own MeasureOverride and ArrangeOverride , which were derived
from those in the other controls, gleaned from PresentationCor e.dll using
Reflector.

That works beautifully in providing a 3D projection with a 2D overlay but
there is still the problem of projecting 3D coordinates into 2D
coordinates. Again, the required code can all be seen in
PresentationCor e.dll using reflector but Microsoft have made it internal so
it cannot be reused. So the only solution is to reimplement this yourself.
I copied their code for ViewMatrix and ProjectionMatri x for a
PerspectiveCame ra and used it to create a MatrixCamera from explicit
matrices, checked that it gave the same results and then went on. Next, I
used the uncommon Point4D type to transform the 3D coordinate without
losing the essential W coordinate of the resulting point. The projected 2D
coordinate is then (x/w, y/w) as usual.

I am extremely happy with the results (most notably that it should work
reliably on customers' computers) but a bit miffed that it was so much
harder to implement with WPF than OpenGL.

The next problem I face is drawing lines in a 3D plot. Apparently WPF also
lacks this functionality so even though I have hardware capable of
accelerating anti-aliased line rendering with z-buffering (fully accessible
from OpenGL), WPF is going to force me to implement this in software by
retesselating everything into 3D triangles every time the view or scene
changes. Ugh.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #2
I have done something similar using a somewhat different approach. I had a
canvas containing the Viewport3D. In the 3D scene I placed 2D visuals using
Viewport2DVisua l3D. To find the coordinates of these visuals relative to the
canvas, I used Visual.PointToS creen. I could then map these coordinates to
the canvas using Canvas.PointFro mScreen and place labels etc. on the canvas
using the coordinates.

It is a very simple approach and not as general as your method of
calculating the projection as it requires visuals in the 3D scene but it is
very simple and easy to use.

BTW, using tooltips of visuals in the 3D scene is another extremely easy way
of showing content in response to hovering the mouse.

Kind regards, Jakob.

"Jon Harrop" wrote:
Jon Harrop wrote:
I am writing a 3D graphing component built upon WPF and would like to have
2D vector graphics (e.g. typeset mathematics) as labels laid out from 3D
coordinates. For example, a tick on an axis has a 3D coordinate and its 2D
label might be right-aligned to the 2D projection of that 3D point.

The following Mathematica plot illustrates the functionality I am after:

http://math.arizona.edu/~goriely/M32...omplexFunc.jpg

I have done some Googling but not found a solution. Some people use 3D
labels but these are ugly and suffer from various artefacts (e.g. they
become heavily distorted or disappear completely when viewed at the wrong
angle).

The best solution I can imagine is a 2D DrawingVisual overlaid over my 3D
Viewport but I need a function to project 3D coordinates onto 2D
coordinates and WPF does not seem to provide one. I can reverse engineer
the projection algorithm used by WPF but Microsoft may change the
algorithm in the future and break my code.

Any ideas?

To answer my own question: I finally got this working reliably after several
days of work and it is not easy. Moreover, there is a lot of unfortunate
ugliness because WPF exposes less functionality than alternatives like
OpenGL so you have to do a lot of work just to get something that works but
is inefficient.

To overlay 2D graphics over 3D graphics, I initially tried StackPanel,
DockPanel and the Canvas. StackPanel and DockPanel are not suitable because
their layout algorithms either overlay but provide too much space (the
default infinite space crashes WPF if it reaches a Viewport3D) or they
stack or dock the Viewports as expected but not as wanted. Canvas lets you
place the controls but it also provides infinite space for layout and that
crashes WPF. You can make the space finite but it needs to be a function of
the space available to the parent and that is not available.

So the most elegant solution I came up with was to derive from Panel and
implement my own MeasureOverride and ArrangeOverride , which were derived
from those in the other controls, gleaned from PresentationCor e.dll using
Reflector.

That works beautifully in providing a 3D projection with a 2D overlay but
there is still the problem of projecting 3D coordinates into 2D
coordinates. Again, the required code can all be seen in
PresentationCor e.dll using reflector but Microsoft have made it internal so
it cannot be reused. So the only solution is to reimplement this yourself.
I copied their code for ViewMatrix and ProjectionMatri x for a
PerspectiveCame ra and used it to create a MatrixCamera from explicit
matrices, checked that it gave the same results and then went on. Next, I
used the uncommon Point4D type to transform the 3D coordinate without
losing the essential W coordinate of the resulting point. The projected 2D
coordinate is then (x/w, y/w) as usual.

I am extremely happy with the results (most notably that it should work
reliably on customers' computers) but a bit miffed that it was so much
harder to implement with WPF than OpenGL.

The next problem I face is drawing lines in a 3D plot. Apparently WPF also
lacks this functionality so even though I have hardware capable of
accelerating anti-aliased line rendering with z-buffering (fully accessible
from OpenGL), WPF is going to force me to implement this in software by
retesselating everything into 3D triangles every time the view or scene
changes. Ugh.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jun 27 '08 #3
Jakob Christensen wrote:
I have done something similar using a somewhat different approach. I had
a canvas containing the Viewport3D. In the 3D scene I placed 2D visuals
using Viewport2DVisua l3D. To find the coordinates of these visuals
relative to the canvas, I used Visual.PointToS creen. I could then map
these coordinates to the canvas using Canvas.PointFro mScreen and place
labels etc. on the canvas using the coordinates.
Very interesting. That is probably what Microsoft had intended for me to
use. I shall check that out. Thanks!
It is a very simple approach and not as general as your method of
calculating the projection as it requires visuals in the 3D scene but it
is very simple and easy to use.
You say that it is not as general but what can I do with my technique that
you cannot do with yours? Are your 2D graphics antialiased? Are they
z-buffered so that 3D objects can obscure them?

Also, I am now considering writing my own implementation of 2D lines
projected back into 3D world space and rendered as triangles. Given the
number of existing libraries that already implement this functionality I
assume there is no easy solution to plotting 3D lines using WPF?
BTW, using tooltips of visuals in the 3D scene is another extremely easy
way of showing content in response to hovering the mouse.
For some reason I didn't cite our product pages after we shipped the code
but they clearly show the effects I was after (the ticks):

http://www.ffconsultancy.com/product...ion/demo1.html
http://www.ffconsultancy.com/product...ion/demo2.html

For an update: I am really happy with the resulting 2D/3D visual effect for
real-time interactive visualizations integrated with Visual Studio. The
software will now be easy to maintain and customers are very happy with
reliability. Performance is adequate on a fast machine but vastly slower
than OpenGL under Linux on the same machine, which is a bit of a shame.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u
Jul 1 '08 #4
You say that it is not as general but what can I do with my technique that
you cannot do with yours? Are your 2D graphics antialiased? Are they
z-buffered so that 3D objects can obscure them?
My method requires a Viewport2DVisua l3D containing 2D visuals. The visuals
can be invisible though.
>
Also, I am now considering writing my own implementation of 2D lines
projected back into 3D world space and rendered as triangles. Given the
number of existing libraries that already implement this functionality I
assume there is no easy solution to plotting 3D lines using WPF?
No, there is no easy solution to plotting lines.
http://www.ffconsultancy.com/product...ion/demo1.html
http://www.ffconsultancy.com/product...ion/demo2.html
Looks nice!

Jul 1 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
5096
by: Matthew | last post by:
I am not the most talented programmer to grace the earth by a long shot. But I've got a gripe I need to air about the .NET implementaion of Visual Basic. I can live with alot of the major changes to the structure and syntax of the code but I thought the purpose of re-engineering the damn thing would result in improved performance all around, well the .NET seems to really suck doing things graphically on forms that VB6 Seemed to do fine....
1
1491
by: Midas NDT Sales | last post by:
Hopefully this is a simple question. I am trying to output a report from Access to Word, everything goes OK except the graphics. How can you get Access to output the graphics (a logo and a few dividing lines) as well as the text and labels. Any help would be greatly appreciated.
3
1667
by: Ace Calhoon | last post by:
Hello, I'm encountering a strange error when printing my forms and reports in Access. Printed documents will intermittently fail to contain graphical elements (i.e. charts will only print labels, printed forms will only contain text, etc.). When viewed in print preview, the graphics display correctly. Initially this problem only occured once in a great while. More recently it has persisted through a complete shut down and re-boot of...
0
304
by: Martin | last post by:
I am using graphics as backgrounds for forms,buttons,labels etc. The question is: is it faster to load all graphics from files on app start or to use it embeded (places in editor during design). Reason for my question is that application has 5mb, while without graphics it has cca 400kb. Graphic files (bmps) take about 200kb (in program, they are repeated many times, ie almost all labels (around 200) have same background image)). Also,...
4
3356
by: Martin | last post by:
I am using graphics as backgrounds for forms,buttons,labels etc. The question is: is it faster to load all graphics from files on app start or to use it embeded (places in editor during design). Reason for my question is that application has 5mb, while without graphics it has cca 400kb. Graphic files (bmps) take about 200kb (in program, they are repeated many times, ie almost all labels (around 200) have same background image)). Also,...
2
7582
by: Dean Slindee | last post by:
It appears that I have two routines that don't play well together! First routine: a form's background is shaded with a gradient color. Second routine: then, the background of all labels on the form are made transparent. What results is the label's backcolor appearing as blocks of 'control' colored background. Setting the label's backcolor to color.transparent does not make it transparent (evidently the text is repainted with a...
3
2027
by: will_456 | last post by:
I have a form containing many controls which receive their properties at design time. Trouble is the form displays large transparent squares all over it while pictures and labels are being filled. It also flashes several times which is quite annoying to watch. Is there a way to keep the form hidden until everything is ready for display?
3
1332
by: Paulo da Silva | last post by:
I need to make some data representation. Basically a major window for a 2D chart, a scrollable window with some few small 2D graphics. The rest is a normal form with buttons, labels and entries. I thought of doing that using Tkinter+pmw+blt. But now I'm considering use a web solution. Is there anything that make this stuff easy? I'm not searching for professional look. This
11
2190
by: raiderdav | last post by:
Is there a common way to embed a graphic or icon into a label? I want to have something like "Press <<IMGBTN1>To Continue" or "Press <<IMGBTN2>For Help". Normally I'd just create a graphic for the whole string, but this will be translated in multiple languages and I want to keep the images generic and only translate text.
0
8397
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8827
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
7333
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5632
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4158
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4315
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2731
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1957
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1620
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.