HELP: How to convert a Region object to a GraphicsPath object

  • Thread starter Thread starter Altramagnus
  • Start date Start date
A

Altramagnus

I have a complicated Region object, which I need to draw the outline, but
not fill
How can I convert the Region object to GraphicsPath object?
or How can I draw the outline of the Region object?
 
Altramagnus,

This kind of more special questions get probably a better answer in one of
these newsgroups depending the language you use

microsoft.public.dotnet.languages.vb
microsoft.public.dotnet.languages.csharp
and than crosspostes (as one message) to
microsoft.public.dotnet.framework.drawings

I hope this helps?

Cor
 
Altramagnus,
Instead of starting with a Region and creating a GraphicsPath, have you
considered starting with a GraphicsPath and creating a Region?

Or simply using a GraphicsPath only?

Hope this helps
Jay
 
Yes, I got my Region from GraphicsPath.
The reason is I need to get the union.

OK. This is my requirement:
I have n number of circles. Some of them might overlap.
But I need the outline after union all the circles.
Creating GraphicsPath of 1 circle is easy.
But how do I create the graphicsPath of the union shape?

Thanks.
 
Altramagnus,
Unfortunately, fortunately actually, I only see that you can create a Region
from a GraphicsPath, and not a GraphicsPath from a Region.

As Charles Petzold in "Programming Microsoft Windows with Microsoft Visual
Basic .NET - Core Reference" from MS Press, suggests that "They (Regions)
might even be ignored altogether if not for the role they play in clipping".
Which makes sense to me, almost every thing I would want to do with a Region
I can directly do with a GraphicsPath, hence my suggestion of using a
GraphicsPath only.

The only way I see to visual get what you want is something like:

Dim path As New GraphicsPath(FillMode.Winding)
path.AddEllipse(50, 50, 50, 50)
path.AddEllipse(75, 75, 50, 50)
path.AddEllipse(150, 150, 50, 50)
e.Graphics.FillPath(SystemBrushes.WindowText, path)
path.Dispose()

If the above is not what you had in mind, you might want to ask "how to get
the outline of a graphics path" in the
microsoft.public.dotnet.framework.drawing newsgroup. As I'm not convinced
that Union of a Region is really what you want, at least it doesn't feel
like how to achieve it.

Hope this helps
Jay
 
Thanks. But I do not think this is what I want.
The code would end up filling the entire area.
If that is the case, I could simply use:

Graphics.FillRegion( region );

I need to draw the outline.


Regards,
Altramagnus.
 
Surprisingly it is extremely easy implementing in Java.
I did the following 2 test codes:

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

public class TestShape {
private static class DisplayComponent extends JComponent {
private Shape s;
private GeneralPath p = new GeneralPath();
private Area a;

public DisplayComponent() {
this.setSize( 500, 500 );
this.setPreferredSize( new Dimension( 500, 500 ) );
p.append( new Ellipse2D.Double( 50, 50, 50, 50 ), false );
p.append( new Ellipse2D.Double( 75, 75, 50, 50 ), false );
p.append( new Ellipse2D.Double( 150, 150, 50, 50 ), false );
a = new Area( p );
} // end DisplayComponent

public void paintComponent( Graphics g ) {
Graphics2D g2d= (Graphics2D)g;
g2d.setColor( new Color( 255, 0, 0 ) );
g2d.draw( a );
} // end paintComponent
} // end clas

public static void main( String[] args ) {
JFrame frame = new JFrame();
DisplayComponent c = new DisplayComponent();
frame.getContentPane().add( c );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.pack();
frame.show();
} // end main
} // end class TestShape

The corresponding CSharp test program.

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace TestGraphicsPath
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox pictureBox1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(55, 35);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(670, 410);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
this.pictureBox1.Paint += new
System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(832, 553);
this.Controls.Add(this.pictureBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void pictureBox1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
GraphicsPath p1 = new GraphicsPath();
GraphicsPath p2 = new GraphicsPath();
GraphicsPath p3 = new GraphicsPath();
p1.AddEllipse( 50, 50, 50, 50 );
p2.AddEllipse( 75, 75, 50, 50 );
p3.AddEllipse( 150, 150, 50, 50 );
Region r = new Region( p1 );
r.Union( p2 );
r.Union( p3 );
g.FillRegion( Brushes.White, r );
}
}
}


For java, Area is the Region equivalent.
Java , you call call graphics.draw( Area ) and it will draw the outline of
the area.
In CSharp, there isn't graphics.draw( Region ) there is only
graphics.Fill( Region )

Thanks. However, I still need help to implement in CSharp.

Regards,
Altramagnus
 
Altramagnus,
As I stated "the only way I see", which doesn't necessarily mean it is the
only way.

As I stated I would ask in the microsoft.public.dotnet.framework.drawing
newsgroup.

Just be prepared for, you simply cannot do it. I have not checked .NET 2.0
to see if the functionality was added there or not.

I hope you understand that .NET is not Java & Java is not .NET, just because
Java has that ability doesn't really mean that .NET does or should. Although
I follow what you want and agree it would be useful in some specific cases.
Hence my suggesting you ask in the drawing newsgroup.

Hope this helps
Jay
 
Hi,

I think Java uses the GDI FrameRgn function to achieve this effect.
As far as I know, this function is not accessible from the .NET framework.

So I think that the only solution for you is to:
use Graphics.GetHdc and Region.GetHrgn to grab their native handles
make a call to Win32 API FrameRgn with them (you'll need a HBRUSH too)

I hope this will solve your problem.

Have a nice day,
joel dumas
 
I wish I could tell my customers that .NET cannot do something Java can do.
"What! you telling me .NET cannot do such simple thing when Java can?!"
What am I suppose to say then?
Never mind.

Thanks anyway.

Regards,
Altramagnus
 
Back
Top