Re: Moving a series of points to be centered on a given point
Quote:
Originally Posted by MikeB
Should I call InitStar from inside all my properties set functions? Or let it be that it is called at the time of creation?
No, consequently, you would need to call InitStar() from any setter method that would require to recalculate the points. But this is still far better than calling it every time a WM_PAINT message is sent to your window. :)
Re: Moving a series of points to be centered on a given point
I haven't tried this, but for drawing your partially filled stars, I would consider using a clipping region.
Set up the clipping region to cover the entire star from top to bottom, but only the first 25% from left to right. Then draw the "complete" star (no need to change your drawing code) with a given brush.
Next, move the left and right limits of the clipping region to conver the last 75% from left to right. Draw the "complete" star again with a different brush.
I think that might be quicker for you.
Hope that at least gives you an idea.
Good luck.
Re: Moving a series of points to be centered on a given point
Quote:
Originally Posted by krmed
I haven't tried this, but for drawing your partially filled stars, I would consider using a clipping region.
Good point - you're right, using a clipping region would work even without offscreen DCs. You just need to be careful to properly combine it with the current clipping region when drawing to the DC - this can be quite a mess...
But another idea, Mike: If switching to GDI+ is an option for you, then you could use linear gradient fills - and let the gradient ramp determine the horizontal fill degree of the stars.
Re: Moving a series of points to be centered on a given point
Quote:
Originally Posted by krmed
I haven't tried this, but for drawing your partially filled stars, I would consider using a clipping region.
Set up the clipping region to cover the entire star from top to bottom, but only the first 25% from left to right. Then draw the "complete" star (no need to change your drawing code) with a given brush.
Next, move the left and right limits of the clipping region to conver the last 75% from left to right. Draw the "complete" star again with a different brush.
I think that might be quicker for you.
Hope that at least gives you an idea.
Good luck.
Yeah, this is pretty much what I was thinking of, not in the same terms, but basically the same. It is a good idea, and would be better then trying to find intersection points, then creating idividual polygons.
Thanks
Mike B
P.S., if you try the attached app, take it from me, do not try to creat a star
with 100,000 points. It crashed my laptop.
Re: Moving a series of points to be centered on a given point
Thanks.
What I'd probably do is in my drawing function, I would call another function designed to draw stars. In that DrawStars, I would set up the clipping region for only the stars and draw them (save the previous clipping region when you SelectObject for your star clipping region).
Then, as the last thing in DrawStars, restore the original clipping region and return to the main drawing routine.
Just a thought.
Re: Moving a series of points to be centered on a given point
Quote:
Originally Posted by gstercken
Good point - you're right, using a clipping region would work even without offscreen DCs. You just need to be careful to properly combine it with the current clipping region when drawing to the DC - this can be quite a mess...
But another idea, Mike: If switching to GDI+ is an option for you, then you could use linear gradient fills - and let the gradient ramp determine the horizontal fill degree of the stars.
Thanks, I will have to look into this as well. I have never attempted to use GDI+. Looks like I have some reading an experimenting to do! :)
Mike B
Re: Moving a series of points to be centered on a given point
Quote:
Originally Posted by krmed
Thanks.
What I'd probably do is in my drawing function, I would call another function designed to draw stars. In that DrawStars, I would set up the clipping region for only the stars and draw them (save the previous clipping region when you SelectObject for your star clipping region).
Then, as the last thing in DrawStars, restore the original clipping region and return to the main drawing routine.
Just a thought.
Thanks alot for all the help hrmed and gstercken. I do need a little more if you can spare the thought and time though.
I am not sure how to use regions. I have tried to use ExcludeClipRgn and this works for partial, but I am not able to understand how to get it to work totally.
I create to rectangles, one for each the left and right portions of the star.
I call these rects, rcFillRgn and rcNoFillRgn.
I call pDC->ExcludeClipRgn(&rcNoFillRgn) to draw the yellow portion of the star. This should draw the star leaving out the right side.
I then call pDC->ExcludeClipRgn(&rcFillRgn) to draw the right side, excluding the left.
The left portion gets drawn but the right side does not. I think it has something to do with restoring to the original clip region prior to the second call to ExcludeClipRgn() but I am not sure how to do this.
Code:
void CStar::DrawStar(CDC* pDC)
{
CRect rcFillRgn(GetContainingRect());
CRect rcNoFillRgn(rcFillRgn);
rcFillRgn.right = rcFillRgn.left + (int)(rcFillRgn.Width() * 0.75);
rcNoFillRgn.left = rcFillRgn.right;
pDC->ExcludeClipRect(&rcNoFillRgn);
CBrush brYellow(RGB(255,255,0));
CBrush brWhite(RGB(255,255,255));
CBrush* pOldBrush = pDC->SelectObject(&brYellow);
pDC->Polygon(m_ptsOuter, m_nPoints * 2);
// I probably have to restore to the original clip region prior to
this call, but I am unsure how to do this.
// pDC->ExcludeClipRect(&rcFillRgn);
// pDC->SelectObject(&brWhite);
// pDC->Polygon(m_ptsOuter, m_nPoints * 2);
pDC->SelectObject(pOldBrush);
}
Mike
Re: Moving a series of points to be centered on a given point
I think what you've done is excluded the rcNoFillRgn from the DC, so you won't draw on it. Then when you exclude the rcFillRgn, it ADDITIONALLY excludes that area (the noFillRgn is not added back in).
Instead I believe your should use a CRgn to create a region for your nofill and your fill areas (only).
Then use something like this: (You'll need to create your rects properly of course)
Code:
temp_rect = data_box;
CRgn oldRgn;
rcNoFillRgn.right -= m_iPpiHorz / 16;
rcNoFillRgn.bottom = data_text.y + text_string_size.cy;
clip_rgn.CreateRectRgnIndirect(&rcNoFillRgn);
pDc->GetClipRgn(hDC, &oldRgn);
pDc->SelectClipRgn(&clip_rgn);
// Draw your fill area
pDc->SelectClipRgn(&rcFillRgn);
// Draw your no fill area
pDc->SelectClipRgn(&oldRgn);
Hope that helps.
Re: Moving a series of points to be centered on a given point
Quote:
Originally Posted by krmed
I think what you've done is excluded the rcNoFillRgn from the DC, so you won't draw on it. Then when you exclude the rcFillRgn, it ADDITIONALLY excludes that area (the noFillRgn is not added back in).
That's basically what I meant when I said:
Quote:
Originally Posted by gstercken
You just need to be careful to properly combine it with the current clipping region when drawing to the DC - this can be quite a mess...
;)
Re: Moving a series of points to be centered on a given point
gstercken:
I couldn't agree more!
I knew that, but I think MikeB missed it. That's why I gave him the "easier???" way to do the same basic thing.
Re: Moving a series of points to be centered on a given point
Quote:
Originally Posted by krmed
I think what you've done is excluded the rcNoFillRgn from the DC, so you won't draw on it. Then when you exclude the rcFillRgn, it ADDITIONALLY excludes that area (the noFillRgn is not added back in).
Instead I believe your should use a CRgn to create a region for your nofill and your fill areas (only).
Then use something like this: (You'll need to create your rects properly of course)
Code:
temp_rect = data_box;
CRgn oldRgn;
rcNoFillRgn.right -= m_iPpiHorz / 16;
rcNoFillRgn.bottom = data_text.y + text_string_size.cy;
clip_rgn.CreateRectRgnIndirect(&rcNoFillRgn);
pDc->GetClipRgn(hDC, &oldRgn);
pDc->SelectClipRgn(&clip_rgn);
// Draw your fill area
pDc->SelectClipRgn(&rcFillRgn);
// Draw your no fill area
pDc->SelectClipRgn(&oldRgn);
Hope that helps.
Well, this seems to draw it nicely. I am not sure if the code will affect anything else. It shouldn't since I am restoring the original clip region?
Thanks
Mike
Code:
void CStar::DrawStar(CDC* pDC)
{
CRect rcFill(GetContainingRect());
CRect rcNoFill(rcFill);
CBrush brYellow(RGB(255,255,0));
CBrush brWhite(RGB(255,255,255));
rcFill.right = rcFill.left + (int)(rcFill.Width() * 0.75);
rcNoFill.left = rcFill.right;
CRgn rgOld, rgFill, rgNoFill;
::GetClipRgn(pDC->GetSafeHdc(), rgOld);
rgNoFill.CreateRectRgnIndirect(&rcNoFill);
pDC->SelectClipRgn(&rgNoFill);
CBrush* pOld = pDC->SelectObject(&brWhite);
pDC->Polygon(m_ptsOuter, m_nPoints * 2);
rgFill.CreateRectRgnIndirect(&rcFill);
pDC->SelectClipRgn(&rgFill);
pDC->SelectObject(&brYellow);
pDC->Polygon(m_ptsOuter, m_nPoints*2);
pDC->SelectClipRgn(&rgOld);
pDC->SelectObject(pOld);
}
Re: Moving a series of points to be centered on a given point
Since you restore the original clipping region, you should be fine.
However, you also need to delete the region objects after you select a new region object:
Code:
void CStar::DrawStar(CDC* pDC)
{
CRect rcFill(GetContainingRect());
CRect rcNoFill(rcFill);
CBrush brYellow(RGB(255,255,0));
CBrush brWhite(RGB(255,255,255));
rcFill.right = rcFill.left + (int)(rcFill.Width() * 0.75);
rcNoFill.left = rcFill.right;
CRgn rgOld, rgFill, rgNoFill;
::GetClipRgn(pDC->GetSafeHdc(), rgOld);
rgNoFill.CreateRectRgnIndirect(&rcNoFill);
pDC->SelectClipRgn(&rgNoFill);
CBrush* pOld = pDC->SelectObject(&brWhite);
pDC->Polygon(m_ptsOuter, m_nPoints * 2);
rgFill.CreateRectRgnIndirect(&rcFill);
rgNoFill.DeleteObject();
pDC->SelectClipRgn(&rgFill);
pDC->SelectObject(&brYellow);
pDC->Polygon(m_ptsOuter, m_nPoints*2);
pDC->SelectClipRgn(&rgOld);
pDC->SelectObject(pOld);
rgFill.DeleteObject();
}
If you don't do that, you'll have GDI resource leaks, and eventually other GDI objects cannot be created, so drawing on ANY window will be affected.
Glad I could help.