Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [VB .NET] Ошибка с GDI+ 
V
    Опции темы
SFY
Дата 30.3.2007, 02:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 5.1.2007

Репутация: нет
Всего: нет



То ли лыжи... ну вы поняли )

Такая проблема. Есть 2 шестерни, расположенные рядом, так, что зубцы входят в пазы друг друга (как и нужно шестерням). Вращаются в противоположные стороны. Все вроде нормально, но...! 
1) Для клонирования шестерни использовал метод GraphicsPath.Widen(pen, matrix), и при этом перестал работать метод e.Graphics.FillPath(). Не заливает, а просто делает обрамление контура, и все.
2) Вторую шестерню заметно "ведет", т.е. ее немного шатает из стороны в сторону. Из-за этого шестерни переодически пересекаются друг с другом.

Кто знает, как побороть эти проблемы?

код form1.vb
Код

'Option Strict On
Imports System.Drawing.Drawing2D
Public Class Form1
    Dim i As Integer
    Dim j As Integer = 90
    Dim k As Integer = 4
    Dim m As Integer = 184

    Private Sub Forml_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        Dim t As New triangle
        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias
        'e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed

        t.build(e)
        i += 1.6
        If i >= 360 Or j >= 360 Then
            i = 0
            j = 90
        End If
        t.Triangle(e, i, j)

        k -= Math.Abs(i) * 3

        t.Scale(e, k, m)
        k = 4

    End Sub

    Private Sub Timerl_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
        Invalidate()
    End Sub

    Private Sub Axis()
        Dim g As Graphics
        Dim i As Integer
        Dim nX As Integer
        Dim nY As Integer
        Dim ArialFont As Font
        ArialFont = New System.Drawing.Font("Arial", 5, FontStyle.Bold)

        g = Me.CreateGraphics
        nX = Me.Width   'длина
        nY = Me.Height  'ширина

        For i = 0 To Me.Height Step 10
            g.DrawLine(Pens.Black, 0, i, Me.Width, i)
            g.DrawString(i / 10, ArialFont, Brushes.Black, 0, i)
        Next

        For i = 0 To Me.Width Step 10
            g.DrawLine(Pens.Black, i, 0, i, Me.Height)
            g.DrawString(Integer.Parse(CStr(i)) / 10, ArialFont, Brushes.Black, i, 0)
        Next

    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        MyClass.SetStyle(ControlStyles.UserPaint, True)
        MyClass.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        MyClass.SetStyle(ControlStyles.DoubleBuffer, True)
    End Sub

    Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        Timer1.Enabled = False
        Axis()
    End Sub

End Class



код модуля triangle.vb
Код

Imports System.Drawing.Drawing2D
Public Class triangle
    Dim ps1() As PointF = {New PointF(0, 110), New PointF(110, 60), New PointF(220, 110), New PointF(110, 160)}
    Dim ps2() As PointF = {New PointF(4.748158, 82.52991), New PointF(123.9409, 62.70371), New PointF(217.2518, 139.4701), New PointF(98.5904, 159.2963)} '15
    Dim ps3() As PointF = {New PointF(15.7372, 56), New PointF(136, 67.69872), New PointF(206.2628, 166), New PointF(86, 154.3013)} '30
    Dim ps4() As PointF = {New PointF(33.21825, 33.21825), New PointF(146.3553, 75.64465), New PointF(188.7817, 188.7817), New PointF(75.64465, 146.3553)} '30
    Dim ps5() As PointF = {New PointF(55.99998, 15.73721), New PointF(154.3013, 85.99999), New PointF(166, 206.2628), New PointF(67.69872, 136)} '60
    Dim ps6() As PointF = {New PointF(82.52989, 4.748159), New PointF(159.2963, 98.05904), New PointF(139.4701, 217.2518), New PointF(62.7037, 123.9409)} '75
    Dim rotationPoint As New PointF(110.0F, 110.0F)
    Dim rotationTransform As New Matrix(1, 0, 0, 1, 1, 1)
    Dim pm As New Matrix(1, 0, 0, 1, 200, 1)
    Dim gp As New GraphicsPath
    Dim gp1 As New GraphicsPath
    Dim gp2 As New GraphicsPath
    Dim gp3 As New GraphicsPath

    Public Sub New()
    End Sub

    Public Sub build(ByVal e)
        gp.AddPolygon(ps1)
        gp.AddPolygon(ps2)
        gp.AddPolygon(ps3)
        gp.AddPolygon(ps4)
        gp.AddPolygon(ps5)
        gp.AddPolygon(ps6)
        'gp.AddEllipse(80, 80, 60, 60)                      'мелкий эллипс в центре
        'gp.AddRectangle(New Rectangle(95, 95, 3, 3))       'индикатор движения для мелкого
        gp1 = CType(gp.Clone(), GraphicsPath)               'клон полигонов (что бы немного сократить объем работ)
        gp2.AddEllipse(23, 23, 175, 175)                    'большой эллипс
        gp2.AddEllipse(80, 80, 60, 60)                      'мелкий эллипс (для границ заливки)
        gp3.AddRectangle(New Rectangle(55, 55, 3, 3))       'индикатор движения для большого
        gp3.AddEllipse(80, 80, 60, 60)

    End Sub

    Public Sub Triangle(ByVal e As PaintEventArgs, ByVal i As Integer, ByVal j As Integer)

        rotationTransform.RotateAt(i, CType(rotationPoint, PointF))  'первая партия полигонов
        gp.Transform(rotationTransform)                              'трансформация
        e.Graphics.DrawPath(New Pen(Color.Black, 4), gp)             'рисование
        e.Graphics.FillPath(Brushes.AliceBlue, gp)                       'закрашивание

        rotationTransform.RotateAt(j, CType(rotationPoint, PointF))  'вторая партия (с 90)
        gp1.Transform(rotationTransform)
        e.Graphics.DrawPath(New Pen(Color.Black, 4), gp1)
        e.Graphics.FillPath(Brushes.AliceBlue, gp1)

        gp2.Transform(rotationTransform)                             'партия эллипсов
        'e.Graphics.DrawPath(New Pen(Color.Black, 0), gp2)
        e.Graphics.FillPath(Brushes.AliceBlue, gp2)

        gp3.Transform(rotationTransform)                             'партия эллипсов
        e.Graphics.DrawPath(New Pen(Color.Black, 2), gp3)
        'e.Graphics.FillPath(Brushes.Khaki, gp2)

        'e.Graphics.ScaleTransform()                                  '?

    End Sub

    Public Sub Scale(ByVal e As PaintEventArgs, ByVal k As Integer, ByVal m As Integer)
        rotationTransform.RotateAt(k, CType(rotationPoint, PointF))  'первая партия полигонов
        gp.Transform(rotationTransform)                              'трансформация
        gp.Widen(Pens.Black, pm)
        e.Graphics.DrawPath(New Pen(Color.Black, 4), gp)             'рисование
        e.Graphics.FillPath(Brushes.AliceBlue, gp)                       'закрашивание

        rotationTransform.RotateAt(m, CType(rotationPoint, PointF))  'первая партия полигонов
        gp1.Transform(rotationTransform)                              'трансформация
        gp1.Widen(Pens.Black, pm)
        e.Graphics.DrawPath(New Pen(Color.Black, 4), gp1)
        e.Graphics.FillPath(Brushes.AliceBlue, gp1)

        gp2.Transform(rotationTransform)                             'партия эллипсов
        gp2.Widen(Pens.Black, pm)
        e.Graphics.DrawPath(New Pen(Color.Black, 0), gp2)
        e.Graphics.FillPath(Brushes.DarkKhaki, gp2)

        gp3.Transform(rotationTransform)                             'партия эллипсов
        gp3.Widen(Pens.Black, pm)
        e.Graphics.DrawPath(New Pen(Color.Black, 2), gp3)
    End Sub
End Class



Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  scr.JPG 50,50 Kb
PM MAIL   Вверх
ivashkanet
Дата 30.3.2007, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 9
Всего: 149



SFY, ты бы хоть пояснил как это все работает smile
Я, например, пасанул перед таким количеством непонятных преобразований.
Этот проект, для меня, проще переписать заново, чем разобраться

P.S. ИМХО, этой теме не место в центре помощи, ее нужно сразу в VB .Net 
PM MAIL WWW ICQ   Вверх
SFY
Дата 30.3.2007, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 5.1.2007

Репутация: нет
Всего: нет



Я уже сам запутался так, что дальше просто нельзя smile
Начал переписывать заново. Теперь создается одна шестеренка, прорисовывается в памяти и затем выводится на форму. Рисуется хорошо, но как теперь вращать растровое изображение вокруг определенной точки? Делаю, как делал с GraphicsPath - матрица преобразований, точка, вокруг которой надо вращать и метод Transform... Однако, с растровым изображением это не проходит. 

P.S. Казалось бы, нарисовать 2 шестерни и заставить их вращаться, что может быть проще. Думал, сделаю, как 2 пальца об асфальт. Ан фиг там  =)

Код

    Dim rotationPoint As New PointF(110.0F, 110.0F)
    Dim rotationTransform As New Matrix(1, 0, 0, 1, 1, 1)

    Dim bmp = New Bitmap(230, 230)
    Dim g As Graphics = Graphics.FromImage(bmp)


'////////////////
'Постороение шестерни
'////////////////

     rotationTransform.RotateAt(90, CType(rotationPoint, PointF))  ' разворот на 90
     g.Transform(rotationTransform)  ' - не пашет. Ругается.

PM MAIL   Вверх
SFY
Дата 30.3.2007, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 5.1.2007

Репутация: нет
Всего: нет



Оперирование с растровой графикой пока оказалось тупиковой ветвью. Продолжил без них и... сделал таки )
Надо было не GraphicsPath.Widen(pen, matrix) пользоваться, а методами матриц, такими как Translate и д.р.

Это сообщение отредактировал(а) SFY - 30.3.2007, 18:36
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.1473 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.